github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/docs/reference/security/rbac.md (about) 1 --- 2 title: Role-Based Access Control (RBAC) 3 description: This section covers authorization (using RBAC) of your lakeFS server. 4 grand_parent: Reference 5 parent: Security 6 redirect_from: 7 - /reference/authorization.html 8 - /reference/rbac.html 9 --- 10 11 12 # Role-Based Access Control (RBAC) 13 {: .d-inline-block } 14 lakeFS Cloud 15 {: .label .label-green } 16 17 lakeFS Enterprise 18 {: .label .label-purple } 19 20 21 {: .note} 22 > RBAC is available on [lakeFS Cloud]({% link understand/lakefs-cloud.md %}) and [lakeFS Enterprise]({% link understand/enterprise/index.md %}). 23 > 24 > If you're using the open source version of lakeFS then the [ACL-based authorization mechanism](access-control-lists.html) is an alternative to RBAC. 25 26 {% include toc.html %} 27 28 ## RBAC Model 29 30 Access to resources is managed very much like [AWS IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/intro-structure.html){:target="_blank"}. 31 32 There are five basic components to the system: 33 34 1. **Users** - Representing entities that access and use the system. A user is given one or more **Access Credentials** for authentication. 35 36 2. **Actions** - Representing a logical action within the system - reading a file, creating a repository, etc. 37 38 3. **Resources** - A unique identifier representing a specific resource in the system - a repository, an object, a user, etc. 39 40 4. **Policies** - Representing a set of **Actions**, a **Resource** and an effect: whether or not these actions are `allowed` or `denied` for the given resource(s). 41 42 5. **Groups** - A named collection of users. Users can belong to multiple groups. 43 44 45 Controlling access is done by attaching **Policies**, either directly to **Users**, or to **Groups** they belong to. 46 47 ## Authorization process 48 49 Every action in the system - be it an API request, UI interaction, S3 Gateway call, or CLI command - requires a set of actions to be allowed for one or more resources. 50 51 When a user makes a request to perform that action, the following process takes place: 52 53 1. Authentication - the credentials passed in the request are evaluated and the user's identity is extracted. 54 1. Action permission resolution - lakeFS then calculates the set of allowed actions and resources that this request requires. 55 1. Effective policy resolution - the user's policies (either attached directly or through group memberships) are calculated. 56 1. Policy/Permission evaluation - lakeFS will compare the given user policies with the request actions and determine whether or not the request is allowed to continue. 57 58 ## Policy Precedence 59 60 Each policy attached to a user or a group has an `Effect` - either `allow` or `deny`. 61 During evaluation of a request, `deny` would take precedence over any other `allow` policy. 62 63 This helps us compose policies together. For example, we could attach a very permissive policy to a user and use `deny` rules to then selectively restrict what that user can do. 64 65 66 ## Resource naming - ARNs 67 68 lakeFS uses [ARN identifier](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns){:target="_blank"} - very similar in structure to those used by AWS. 69 The resource segment of the ARN supports wildcards: use `*` to match 0 or more characters, or `?` to match exactly one character. 70 71 Here are a some **examples** of valid ARNs within lakeFS and their meaning: 72 73 | ARN | Meaning | 74 |------------------------------------|---------------------------------------------| 75 | `arn:lakefs:auth:::user/jane.doe` | A specific user 76 | `arn:lakefs:auth:::user/*` | All users | 77 | `arn:lakefs:fs:::repository/myrepo/*` | All resources under `myrepo` | 78 | `arn:lakefs:fs:::repository/myrepo/object/foo/bar/baz` | A single object ARN | 79 | `arn:lakefs:fs:::repository/myrepo/object/*` | All objects in `myrepo` | 80 | `arn:lakefs:fs:::repository/*` | All repositories| 81 | `arn:lakefs:fs:::*` | All resources under the fs ARN prefix | 82 83 Additionally, the current user's ID is interpolated in runtime into the ARN using the `${user}` placeholder. 84 85 This allows us to create fine-grained policies affecting only a specific subset of resources. 86 87 See below for a full reference of ARNs and actions. 88 89 90 ## Actions and Permissions 91 92 For the full list of actions and their required permissions see the following table: 93 94 | Action name | required action | Resource | API endpoint | S3 gateway operation | 95 |------------------------------------|---------------------------------------------|--------------------------------------------------------------------------|-------------------------------------------------------------------------------------|-----------------------------------------------------------------------| 96 | List Repositories | `fs:ListRepositories` | `*` | GET /repositories | ListBuckets | 97 | Get Repository | `fs:ReadRepository` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId} | HeadBucket | 98 | Get Commit | `fs:ReadCommit` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId}/commits/{commitId} | - | 99 | Create Commit | `fs:CreateCommit` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | POST /repositories/{repositoryId}/branches/{branchId}/commits | - | 100 | Get Commit log | `fs:ReadBranch` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | GET /repositories/{repositoryId}/branches/{branchId}/commits | - | 101 | Create Repository | `fs:CreateRepository` | `arn:lakefs:fs:::repository/{repositoryId}` | POST /repositories | - | 102 | Namespace Attach to Repository | `fs:AttachStorageNamespace` | `arn:lakefs:fs:::namespace/{storageNamespace}` | POST /repositories | - | 103 | Import From Source | `fs:ImportFromStorage` | `arn:lakefs:fs:::namespace/{storageNamespace}` | POST /repositories/{repositoryId}/branches/{branchId}/import | - | 104 | Cancel Import | `fs:ImportCancel` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | DELETE /repositories/{repositoryId}/branches/{branchId}/import | - | 105 | Delete Repository | `fs:DeleteRepository` | `arn:lakefs:fs:::repository/{repositoryId}` | DELETE /repositories/{repositoryId} | - | 106 | List Branches | `fs:ListBranches` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId}/branches | ListObjects/ListObjectsV2 (with delimiter = `/` and empty prefix) | 107 | Get Branch | `fs:ReadBranch` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | GET /repositories/{repositoryId}/branches/{branchId} | - | 108 | Create Branch | `fs:CreateBranch` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | POST /repositories/{repositoryId}/branches | - | 109 | Delete Branch | `fs:DeleteBranch` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | DELETE /repositories/{repositoryId}/branches/{branchId} | - | 110 | Merge branches | `fs:CreateCommit` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{destinationBranchId}` | POST /repositories/{repositoryId}/refs/{sourceBranchId}/merge/{destinationBranchId} | - | 111 | Diff branch uncommitted changes | `fs:ListObjects` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId}/branches/{branchId}/diff | - | 112 | Diff refs | `fs:ListObjects` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId}/refs/{leftRef}/diff/{rightRef} | - | 113 | Stat object | `fs:ReadObject` | `arn:lakefs:fs:::repository/{repositoryId}/object/{objectKey}` | GET /repositories/{repositoryId}/refs/{ref}/objects/stat | HeadObject | 114 | Get Object | `fs:ReadObject` | `arn:lakefs:fs:::repository/{repositoryId}/object/{objectKey}` | GET /repositories/{repositoryId}/refs/{ref}/objects | GetObject | 115 | List Objects | `fs:ListObjects` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId}/refs/{ref}/objects/ls | ListObjects, ListObjectsV2 (no delimiter, or "/" + non-empty prefix) | 116 | Upload Object | `fs:WriteObject` | `arn:lakefs:fs:::repository/{repositoryId}/object/{objectKey}` | POST /repositories/{repositoryId}/branches/{branchId}/objects | PutObject, CreateMultipartUpload, UploadPart, CompleteMultipartUpload | 117 | Delete Object | `fs:DeleteObject` | `arn:lakefs:fs:::repository/{repositoryId}/object/{objectKey}` | DELETE /repositories/{repositoryId}/branches/{branchId}/objects | DeleteObject, DeleteObjects, AbortMultipartUpload | 118 | Revert Branch | `fs:RevertBranch` | `arn:lakefs:fs:::repository/{repositoryId}/branch/{branchId}` | PUT /repositories/{repositoryId}/branches/{branchId} | - | 119 | Get Branch Protection Rules | `branches:GetBranchProtectionRules` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repository}/branch_protection | - | 120 | Set Branch Protection Rules | `branches:SetBranchProtectionRules` | `arn:lakefs:fs:::repository/{repositoryId}` | POST /repositories/{repository}/branch_protection | - | 121 | Delete Branch Protection Rules | `branches:SetBranchProtectionRules` | `arn:lakefs:fs:::repository/{repositoryId}` | DELETE /repositories/{repository}/branch_protection | - | 122 | Create User | `auth:CreateUser` | `arn:lakefs:auth:::user/{userId}` | POST /auth/users | - | 123 | List Users | `auth:ListUsers` | `*` | GET /auth/users | - | 124 | Get User | `auth:ReadUser` | `arn:lakefs:auth:::user/{userId}` | GET /auth/users/{userId} | - | 125 | Delete User | `auth:DeleteUser` | `arn:lakefs:auth:::user/{userId}` | DELETE /auth/users/{userId} | - | 126 | Get Group | `auth:ReadGroup` | `arn:lakefs:auth:::group/{groupId}` | GET /auth/groups/{groupId} | - | 127 | List Groups | `auth:ListGroups` | `*` | GET /auth/groups | - | 128 | Create Group | `auth:CreateGroup` | `arn:lakefs:auth:::group/{groupId}` | POST /auth/groups | - | 129 | Delete Group | `auth:DeleteGroup` | `arn:lakefs:auth:::group/{groupId}` | DELETE /auth/groups/{groupId} | - | 130 | List Policies | `auth:ListPolicies` | `*` | GET /auth/policies | - | 131 | Create Policy | `auth:CreatePolicy` | `arn:lakefs:auth:::policy/{policyId}` | POST /auth/policies | - | 132 | Update Policy | `auth:UpdatePolicy` | `arn:lakefs:auth:::policy/{policyId}` | POST /auth/policies | - | 133 | Delete Policy | `auth:DeletePolicy` | `arn:lakefs:auth:::policy/{policyId}` | DELETE /auth/policies/{policyId} | - | 134 | Get Policy | `auth:ReadPolicy` | `arn:lakefs:auth:::policy/{policyId}` | GET /auth/policies/{policyId} | - | 135 | List Group Members | `auth:ReadGroup` | `arn:lakefs:auth:::group/{groupId}` | GET /auth/groups/{groupId}/members | - | 136 | Add Group Member | `auth:AddGroupMember` | `arn:lakefs:auth:::group/{groupId}` | PUT /auth/groups/{groupId}/members/{userId} | - | 137 | Remove Group Member | `auth:RemoveGroupMember` | `arn:lakefs:auth:::group/{groupId}` | DELETE /auth/groups/{groupId}/members/{userId} | - | 138 | List User Credentials | `auth:ListCredentials` | `arn:lakefs:auth:::user/{userId}` | GET /auth/users/{userId}/credentials | - | 139 | Create User Credentials | `auth:CreateCredentials` | `arn:lakefs:auth:::user/{userId}` | POST /auth/users/{userId}/credentials | - | 140 | Delete User Credentials | `auth:DeleteCredentials` | `arn:lakefs:auth:::user/{userId}` | DELETE /auth/users/{userId}/credentials/{accessKeyId} | - | 141 | Get User Credentials | `auth:ReadCredentials` | `arn:lakefs:auth:::user/{userId}` | GET /auth/users/{userId}/credentials/{accessKeyId} | - | 142 | List User Groups | `auth:ReadUser` | `arn:lakefs:auth:::user/{userId}` | GET /auth/users/{userId}/groups | - | 143 | List User Policies | `auth:ReadUser` | `arn:lakefs:auth:::user/{userId}` | GET /auth/users/{userId}/policies | - | 144 | Attach Policy To User | `auth:AttachPolicy` | `arn:lakefs:auth:::user/{userId}` | PUT /auth/users/{userId}/policies/{policyId} | - | 145 | Detach Policy From User | `auth:DetachPolicy` | `arn:lakefs:auth:::user/{userId}` | DELETE /auth/users/{userId}/policies/{policyId} | - | 146 | List Group Policies | `auth:ReadGroup` | `arn:lakefs:auth:::group/{groupId}` | GET /auth/groups/{groupId}/policies | - | 147 | Attach Policy To Group | `auth:AttachPolicy` | `arn:lakefs:auth:::group/{groupId}` | PUT /auth/groups/{groupId}/policies/{policyId} | - | 148 | Detach Policy From Group | `auth:DetachPolicy` | `arn:lakefs:auth:::group/{groupId}` | DELETE /auth/groups/{groupId}/policies/{policyId} | - | 149 | Read Storage Config | `fs:ReadConfig` | `*` | GET /config/storage | - | 150 | Get Garbage Collection Rules | `retention:GetGarbageCollectionRules` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repositoryId}/gc/rules | - | 151 | Set Garbage Collection Rules | `retention:SetGarbageCollectionRules` | `arn:lakefs:fs:::repository/{repositoryId}` | POST /repositories/{repositoryId}/gc/rules | - | 152 | Prepare Garbage Collection Commits | `retention:PrepareGarbageCollectionCommits` | `arn:lakefs:fs:::repository/{repositoryId}` | POST /repositories/{repositoryId}/gc/prepare_commits | - | 153 | List Repository Action Runs | `ci:ReadAction` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repository}/actions/runs | - | 154 | Get Action Run | `ci:ReadAction` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repository}/actions/runs/{run_id} | - | 155 | List Action Run Hooks | `ci:ReadAction` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repository}/actions/runs/{run_id}/hooks | - | 156 | Get Action Run Hook Output | `ci:ReadAction` | `arn:lakefs:fs:::repository/{repositoryId}` | GET /repositories/{repository}/actions/runs/{run_id}/hooks/{hook_run_id}/output | - | 157 | Attach External Principal to a User | `auth:CreateUserExternalPrincipal` | `arn:lakefs:auth:::user/{userId}` | POST /auth/users/{userId}/external/principals | - | 158 | Delete External Principal Attachment from a User | `auth:DeleteUserExternalPrincipal` | `arn:lakefs:auth:::user/{userId}` | DELETE /auth/users/{userId}/external/principals | - | 159 | Get the User attached to an External Principal | `auth:ReadExternalPrincipal` | `arn:lakefs:auth:::externalPrincipal/{principalId}` | GET /auth/external/principals | - | 160 161 162 Some APIs may require more than one action.For instance, in order to 163 create a repository (`POST /repositories`), you need permission to 164 `fs:CreateRepository` for the _name_ of the repository and also 165 `fs:AttachStorageNamespace` for the _storage namespace_ used. 166 167 ## Preconfigured Policies 168 169 The following Policies are created during initial setup: 170 171 ### FSFullAccess 172 173 ```json 174 { 175 "statement": [ 176 { 177 "action": [ 178 "fs:*" 179 ], 180 "effect": "allow", 181 "resource": "*" 182 } 183 ] 184 } 185 ``` 186 187 ### FSReadAll 188 189 ```json 190 { 191 "statement": [ 192 { 193 "action": [ 194 "fs:List*", 195 "fs:Read*" 196 ], 197 "effect": "allow", 198 "resource": "*" 199 } 200 ] 201 } 202 ``` 203 204 ### FSReadWriteAll 205 206 ```json 207 { 208 "statement": [ 209 { 210 "action": [ 211 "fs:Read*", 212 "fs:List*", 213 "fs:WriteObject", 214 "fs:DeleteObject", 215 "fs:RevertBranch", 216 "fs:CreateBranch", 217 "fs:CreateTag", 218 "fs:DeleteBranch", 219 "fs:DeleteTag", 220 "fs:CreateCommit", 221 "fs:CreateMetaRange" 222 ], 223 "effect": "allow", 224 "resource": "*" 225 } 226 ] 227 } 228 ``` 229 230 ### AuthFullAccess 231 232 ```json 233 { 234 "statement": [ 235 { 236 "action": [ 237 "auth:*" 238 ], 239 "effect": "allow", 240 "resource": "*" 241 } 242 ] 243 } 244 ``` 245 246 ### AuthManageOwnCredentials 247 248 ```json 249 { 250 "statement": [ 251 { 252 "action": [ 253 "auth:CreateCredentials", 254 "auth:DeleteCredentials", 255 "auth:ListCredentials", 256 "auth:ReadCredentials" 257 ], 258 "effect": "allow", 259 "resource": "arn:lakefs:auth:::user/${user}" 260 } 261 ] 262 } 263 ``` 264 265 ### RepoManagementFullAccess 266 267 ```json 268 { 269 "statement": [ 270 { 271 "action": [ 272 "ci:*" 273 ], 274 "effect": "allow", 275 "resource": "*" 276 }, 277 { 278 "action": [ 279 "retention:*" 280 ], 281 "effect": "allow", 282 "resource": "*" 283 } 284 ] 285 } 286 ``` 287 ### RepoManagementReadAll 288 289 ```json 290 { 291 "statement": [ 292 { 293 "action": [ 294 "ci:Read*" 295 ], 296 "effect": "allow", 297 "resource": "*" 298 }, 299 { 300 "action": [ 301 "retention:Get*" 302 ], 303 "effect": "allow", 304 "resource": "*" 305 } 306 ] 307 } 308 ``` 309 310 ## Additional Policies 311 312 You can create additional policies to further limit user access. Use the web UI or the [lakectl auth]({% link reference/cli.md%}#lakectl-auth-policies-create) command to create policies. Here is an example to define read/write access for a specific repository: 313 314 ```json 315 { 316 "statement": [ 317 { 318 "action": [ 319 "fs:ReadRepository", 320 "fs:ReadCommit", 321 "fs:ListBranches", 322 "fs:ListTags", 323 "fs:ListObjects" 324 ], 325 "effect": "allow", 326 "resource": "arn:lakefs:fs:::repository/<repository-name>" 327 }, 328 { 329 "action": [ 330 "fs:RevertBranch", 331 "fs:ReadBranch", 332 "fs:CreateBranch", 333 "fs:DeleteBranch", 334 "fs:CreateCommit" 335 ], 336 "effect": "allow", 337 "resource": "arn:lakefs:fs:::repository/<repository-name>/branch/*" 338 }, 339 { 340 "action": [ 341 "fs:ListObjects", 342 "fs:ReadObject", 343 "fs:WriteObject", 344 "fs:DeleteObject" 345 ], 346 "effect": "allow", 347 "resource": "arn:lakefs:fs:::repository/<repository-name>/object/*" 348 }, 349 { 350 "action": [ 351 "fs:ReadTag", 352 "fs:CreateTag", 353 "fs:DeleteTag" 354 ], 355 "effect": "allow", 356 "resource": "arn:lakefs:fs:::repository/<repository-name>/tag/*" 357 }, 358 { 359 "action": ["fs:ReadConfig"], 360 "effect": "allow", 361 "resource": "*" 362 } 363 ] 364 } 365 ``` 366 367 ## Preconfigured Groups 368 369 lakeFS has four preconfigured groups: 370 371 * Admins 372 * SuperUsers 373 * Developers 374 * Viewers 375 376 They have the following policies granted to them: 377 378 | Policy | Admins | SuperUsers | Developers | Viewers | 379 |---------------------------------------------------------|--------|------------|------------|---------| 380 | [`FSFullAccess`](#fsfullaccess) | ✅ | ✅ | | | 381 | [`AuthFullAccess`](#authfullaccess) | ✅ | | | | 382 | [`RepoManagementFullAccess`](#repomanagementfullaccess) | ✅ | | | | 383 | [`AuthManageOwnCredentials`](#authmanageowncredentials) | | ✅ | ✅ | ✅ | 384 | [`RepoManagementReadAll`](#repomanagementreadall) | | ✅ | ✅ | | 385 | [`FSReadWriteAll`](#fsreadwriteall) | | | ✅ | | 386 | [`FSReadAll`](#fsreadall) | | | | ✅ | 387 388 ## Pluggable Authentication and Authorization 389 390 Authorization and authentication is pluggable in lakeFS. If lakeFS is attached to a [remote authentication server](remote-authenticator.html) (or you are using lakeFS Cloud) then the [role-based access control](rbac.html) user interface can be used. If you are using RBAC with your self-managed lakeFS then the lakeFS configuration element `auth.ui_config.rbac` should be set to `external`. An enterprise (paid) solution of lakeFS should set `auth.ui_config.rbac` as `internal`. 391 392 If you are using self-managed lakeFS and do not have a [remote authentication server](remote-authenticator.html) then you should set `auth.ui_config.rbac` to `simplified` and refer to the [access control list](access-control-lists.html) documentation instead.