From 8617c5c5e782a75e329d508ececff74c1fd662ce Mon Sep 17 00:00:00 2001 From: Tamar Kalir Date: Tue, 11 Nov 2025 22:25:16 +0200 Subject: [PATCH 1/7] migrate garbage collection endpoints to use authorizeReq --- pkg/api/controller.go | 42 ++++------------------- pkg/permissions/permission.go | 63 ++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 4e69d6603b0..f790fc67b21 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -614,12 +614,7 @@ func (c *Controller) CompletePresignMultipartUpload(w http.ResponseWriter, r *ht } func (c *Controller) PrepareGarbageCollectionUncommitted(w http.ResponseWriter, r *http.Request, body apigen.PrepareGarbageCollectionUncommittedJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.PrepareGarbageCollectionUncommittedAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "PrepareGarbageCollectionUncommitted", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2545,12 +2540,7 @@ func (c *Controller) SetBranchProtectionRules(w http.ResponseWriter, r *http.Req } func (c *Controller) DeleteGCRules(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DeleteGCRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2562,12 +2552,7 @@ func (c *Controller) DeleteGCRules(w http.ResponseWriter, r *http.Request, repos } func (c *Controller) GetGCRules(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.GetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetGCRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2584,12 +2569,7 @@ func (c *Controller) GetGCRules(w http.ResponseWriter, r *http.Request, reposito } func (c *Controller) SetGCRules(w http.ResponseWriter, r *http.Request, body apigen.SetGCRulesJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetGCRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3793,12 +3773,7 @@ func (c *Controller) InternalGetGarbageCollectionRules(w http.ResponseWriter, r } func (c *Controller) SetGarbageCollectionRulesPreflight(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetGarbageCollectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetGarbageCollectionRulesPreflight", permissions.PermissionParams{Repository: &repository}, nil) { return } @@ -3817,12 +3792,7 @@ func (c *Controller) InternalDeleteGarbageCollectionRules(w http.ResponseWriter, } func (c *Controller) PrepareGarbageCollectionCommits(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.PrepareGarbageCollectionCommitsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "PrepareGarbageCollectionCommits", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index 14e9217cab8..bf0ce2284d9 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -98,6 +98,19 @@ func (o *BranchPermission) Permission(params PermissionParams) Node { } } +type RepoPermission struct { + Action string +} + +func (r *RepoPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: r.Action, + Resource: RepoArn(*params.Repository), + }, + } +} + var readObjectPermission = ObjectPermission{Action: ReadObjectAction} var writeObjectPermission = ObjectPermission{Action: WriteObjectAction} var createBranchPermission = BranchPermission{Action: CreateBranchAction} @@ -106,28 +119,38 @@ var readBranchPermission = BranchPermission{Action: ReadBranchAction} var revertBranchPermission = BranchPermission{Action: RevertBranchAction} var createCommitPermission = BranchPermission{Action: CreateCommitAction} var importCancelPermission = BranchPermission{Action: ImportCancelAction} +var prepareGCUncommittedPermission = RepoPermission{Action: PrepareGarbageCollectionUncommittedAction} +var getGCRulesPermission = RepoPermission{Action: GetGarbageCollectionRulesAction} +var setGCRulesPermission = RepoPermission{Action: SetGarbageCollectionRulesAction} +var prepareGCCommitsPermission = RepoPermission{Action: PrepareGarbageCollectionCommitsAction} var permissionByOp = map[string]PermissionDescriptor{ - "HeadObject": &readObjectPermission, - "GetObject": &readObjectPermission, - "StatObject": &readObjectPermission, - "GetUnderlyingProperties": &readObjectPermission, - "StageObject": &writeObjectPermission, - "CreateSymlinkFile": &writeObjectPermission, - "UpdateObjectUserMetadata": &writeObjectPermission, - "UploadObject": &writeObjectPermission, - "UploadObjectPreflight": &writeObjectPermission, - "CreateBranch": &createBranchPermission, - "DeleteBranch": &deleteBranchPermission, - "GetBranch": &readBranchPermission, - "RevertBranch": &revertBranchPermission, - "LogCommits": &readBranchPermission, - "ResetBranch": &revertBranchPermission, - "MergeIntoBranch": &createCommitPermission, - "HardResetBranch": &revertBranchPermission, - "ImportStatus": &readBranchPermission, - "Commit": &createCommitPermission, - "ImportCancel": &importCancelPermission, + "HeadObject": &readObjectPermission, + "GetObject": &readObjectPermission, + "StatObject": &readObjectPermission, + "GetUnderlyingProperties": &readObjectPermission, + "StageObject": &writeObjectPermission, + "CreateSymlinkFile": &writeObjectPermission, + "UpdateObjectUserMetadata": &writeObjectPermission, + "UploadObject": &writeObjectPermission, + "UploadObjectPreflight": &writeObjectPermission, + "CreateBranch": &createBranchPermission, + "DeleteBranch": &deleteBranchPermission, + "GetBranch": &readBranchPermission, + "RevertBranch": &revertBranchPermission, + "LogCommits": &readBranchPermission, + "ResetBranch": &revertBranchPermission, + "MergeIntoBranch": &createCommitPermission, + "HardResetBranch": &revertBranchPermission, + "ImportStatus": &readBranchPermission, + "Commit": &createCommitPermission, + "ImportCancel": &importCancelPermission, + "PrepareGarbageCollectionUncommitted": &prepareGCUncommittedPermission, + "GetGCRules": &getGCRulesPermission, + "SetGCRules": &setGCRulesPermission, + "DeleteGCRules": &setGCRulesPermission, + "SetGarbageCollectionRulesPreflight": &setGCRulesPermission, + "PrepareGarbageCollectionCommits": &prepareGCCommitsPermission, } func GetPermissionDescriptor(operationId string) PermissionDescriptor { From 11ea37f48377ec8941236855cebd02e756413e63 Mon Sep 17 00:00:00 2001 From: Tamar Kalir Date: Wed, 12 Nov 2025 12:39:21 +0200 Subject: [PATCH 2/7] migrate repo management endpoints to use authorizeReq --- pkg/api/controller.go | 35 +++++------------------------------ pkg/permissions/permission.go | 8 ++++++++ 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index f790fc67b21..75d0984d1ac 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -2379,12 +2379,7 @@ func (c *Controller) ensureStorageNamespace(ctx context.Context, storageID, stor } func (c *Controller) DeleteRepository(w http.ResponseWriter, r *http.Request, repository string, params apigen.DeleteRepositoryParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.DeleteRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DeleteRepository", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2397,12 +2392,7 @@ func (c *Controller) DeleteRepository(w http.ResponseWriter, r *http.Request, re } func (c *Controller) GetRepository(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRepository", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2432,12 +2422,7 @@ func (c *Controller) GetRepository(w http.ResponseWriter, r *http.Request, repos } func (c *Controller) GetRepositoryMetadata(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRepositoryMetadata", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2450,12 +2435,7 @@ func (c *Controller) GetRepositoryMetadata(w http.ResponseWriter, r *http.Reques } func (c *Controller) SetRepositoryMetadata(w http.ResponseWriter, r *http.Request, body apigen.SetRepositoryMetadataJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.UpdateRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetRepositoryMetadata", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2468,12 +2448,7 @@ func (c *Controller) SetRepositoryMetadata(w http.ResponseWriter, r *http.Reques } func (c *Controller) DeleteRepositoryMetadata(w http.ResponseWriter, r *http.Request, body apigen.DeleteRepositoryMetadataJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.UpdateRepositoryAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DeleteRepositoryMetadata", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index bf0ce2284d9..02a00c5711a 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -123,6 +123,9 @@ var prepareGCUncommittedPermission = RepoPermission{Action: PrepareGarbageCollec var getGCRulesPermission = RepoPermission{Action: GetGarbageCollectionRulesAction} var setGCRulesPermission = RepoPermission{Action: SetGarbageCollectionRulesAction} var prepareGCCommitsPermission = RepoPermission{Action: PrepareGarbageCollectionCommitsAction} +var readRepositoryPermission = RepoPermission{Action: ReadRepositoryAction} +var updateRepositoryPermission = RepoPermission{Action: UpdateRepositoryAction} +var deleteRepositoryPermission = RepoPermission{Action: DeleteRepositoryAction} var permissionByOp = map[string]PermissionDescriptor{ "HeadObject": &readObjectPermission, @@ -151,6 +154,11 @@ var permissionByOp = map[string]PermissionDescriptor{ "DeleteGCRules": &setGCRulesPermission, "SetGarbageCollectionRulesPreflight": &setGCRulesPermission, "PrepareGarbageCollectionCommits": &prepareGCCommitsPermission, + "GetRepository": &readRepositoryPermission, + "GetRepositoryMetadata": &readRepositoryPermission, + "SetRepositoryMetadata": &updateRepositoryPermission, + "DeleteRepositoryMetadata": &updateRepositoryPermission, + "DeleteRepository": &deleteRepositoryPermission, } func GetPermissionDescriptor(operationId string) PermissionDescriptor { From fdca1fe6959f83e6dd90d4340e8ba66a050e5d3f Mon Sep 17 00:00:00 2001 From: Tamar Kalir Date: Wed, 12 Nov 2025 13:04:00 +0200 Subject: [PATCH 3/7] migrate pull request endpoints to use authorizeReq --- pkg/api/controller.go | 28 ++++------------------------ pkg/permissions/permission.go | 7 +++++++ 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 75d0984d1ac..05d550566ff 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -5406,12 +5406,7 @@ func (c *Controller) PostStatsEvents(w http.ResponseWriter, r *http.Request, bod } func (c *Controller) ListPullRequests(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListPullRequestsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListPullRequestsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListPullRequests", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5448,12 +5443,7 @@ func (c *Controller) ListPullRequests(w http.ResponseWriter, r *http.Request, re } func (c *Controller) CreatePullRequest(w http.ResponseWriter, r *http.Request, body apigen.CreatePullRequestJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.WritePullRequestAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "CreatePullRequest", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5484,12 +5474,7 @@ func (c *Controller) CreatePullRequest(w http.ResponseWriter, r *http.Request, b } func (c *Controller) GetPullRequest(w http.ResponseWriter, r *http.Request, repository string, pullRequestID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadPullRequestAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetPullRequest", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -5516,12 +5501,7 @@ func (c *Controller) GetPullRequest(w http.ResponseWriter, r *http.Request, repo } func (c *Controller) UpdatePullRequest(w http.ResponseWriter, r *http.Request, body apigen.UpdatePullRequestJSONRequestBody, repository string, pullRequestID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.WritePullRequestAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "UpdatePullRequest", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index 02a00c5711a..4d721351323 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -126,6 +126,9 @@ var prepareGCCommitsPermission = RepoPermission{Action: PrepareGarbageCollection var readRepositoryPermission = RepoPermission{Action: ReadRepositoryAction} var updateRepositoryPermission = RepoPermission{Action: UpdateRepositoryAction} var deleteRepositoryPermission = RepoPermission{Action: DeleteRepositoryAction} +var writePullRequestPermission = RepoPermission{Action: WritePullRequestAction} +var listPullRequestsPermission = RepoPermission{Action: ListPullRequestsAction} +var readPullRequestPermission = RepoPermission{Action: ReadPullRequestAction} var permissionByOp = map[string]PermissionDescriptor{ "HeadObject": &readObjectPermission, @@ -159,6 +162,10 @@ var permissionByOp = map[string]PermissionDescriptor{ "SetRepositoryMetadata": &updateRepositoryPermission, "DeleteRepositoryMetadata": &updateRepositoryPermission, "DeleteRepository": &deleteRepositoryPermission, + "UpdatePullRequest": &writePullRequestPermission, + "CreatePullRequest": &writePullRequestPermission, + "ListPullRequests": &listPullRequestsPermission, + "GetPullRequest": &readPullRequestPermission, } func GetPermissionDescriptor(operationId string) PermissionDescriptor { From a75a7b9afbe1444f87eb94367f36eb0d5cc7b095 Mon Sep 17 00:00:00 2001 From: tkalir Date: Tue, 18 Nov 2025 00:51:06 +0200 Subject: [PATCH 4/7] migrate list-branches\tags\objects endpoints to use authorizeReq --- pkg/api/controller.go | 21 +++------------------ pkg/permissions/permission.go | 6 ++++++ 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 05d550566ff..87e0310e423 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -2785,12 +2785,7 @@ func (c *Controller) GetRunHookOutput(w http.ResponseWriter, r *http.Request, re } func (c *Controller) ListBranches(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListBranchesParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListBranchesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListBranches", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -4709,12 +4704,7 @@ func (c *Controller) GetObject(w http.ResponseWriter, r *http.Request, repositor } func (c *Controller) ListObjects(w http.ResponseWriter, r *http.Request, repository, ref string, params apigen.ListObjectsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListObjectsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListObjects", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -4997,12 +4987,7 @@ func (c *Controller) FindMergeBase(w http.ResponseWriter, r *http.Request, repos } func (c *Controller) ListTags(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListTagsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListTagsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListTags", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index 4d721351323..695181a481c 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -129,6 +129,9 @@ var deleteRepositoryPermission = RepoPermission{Action: DeleteRepositoryAction} var writePullRequestPermission = RepoPermission{Action: WritePullRequestAction} var listPullRequestsPermission = RepoPermission{Action: ListPullRequestsAction} var readPullRequestPermission = RepoPermission{Action: ReadPullRequestAction} +var listBranchesPermission = RepoPermission{Action: ListBranchesAction} +var listTagsPermission = RepoPermission{Action: ListTagsAction} +var listObjectsPermission = RepoPermission{Action: ListObjectsAction} var permissionByOp = map[string]PermissionDescriptor{ "HeadObject": &readObjectPermission, @@ -166,6 +169,9 @@ var permissionByOp = map[string]PermissionDescriptor{ "CreatePullRequest": &writePullRequestPermission, "ListPullRequests": &listPullRequestsPermission, "GetPullRequest": &readPullRequestPermission, + "ListBranches": &listBranchesPermission, + "ListTags": &listTagsPermission, + "ListObjects": &listObjectsPermission, } func GetPermissionDescriptor(operationId string) PermissionDescriptor { From 3de04878a0ea16fbf3202f124dcf15efb9cd0db1 Mon Sep 17 00:00:00 2001 From: tkalir Date: Tue, 18 Nov 2025 15:35:34 +0200 Subject: [PATCH 5/7] migrate commit-related and diff endpoints to use authorizeReq --- pkg/api/controller.go | 35 +++++------------------------------ pkg/permissions/permission.go | 8 ++++++++ 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 87e0310e423..143e5cad09d 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -3187,12 +3187,7 @@ func (c *Controller) Commit(w http.ResponseWriter, r *http.Request, body apigen. } func (c *Controller) CreateCommitRecord(w http.ResponseWriter, r *http.Request, body apigen.CreateCommitRecordJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.CreateCommitAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "CreateCommitRecord", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3226,12 +3221,7 @@ func commitResponse(w http.ResponseWriter, r *http.Request, newCommit *catalog.C } func (c *Controller) DiffBranch(w http.ResponseWriter, r *http.Request, repository, branch string, params apigen.DiffBranchParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListObjectsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DiffBranch", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3701,12 +3691,7 @@ func getCommitOverrides(commitOverrides *apigen.CommitOverrides) *graveler.Commi } func (c *Controller) GetCommit(w http.ResponseWriter, r *http.Request, repository, commitID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadCommitAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetCommit", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -4352,12 +4337,7 @@ func writeSymlink(ctx context.Context, repo *catalog.Repository, branch, path st } func (c *Controller) DiffRefs(w http.ResponseWriter, r *http.Request, repository, leftRef, rightRef string, params apigen.DiffRefsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListObjectsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "DiffRefs", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -4964,12 +4944,7 @@ func (c *Controller) MergeIntoBranch(w http.ResponseWriter, r *http.Request, bod } func (c *Controller) FindMergeBase(w http.ResponseWriter, r *http.Request, repository string, sourceRef string, destinationRef string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ListCommitsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "FindMergeBase", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index 695181a481c..a91b8ef5ab1 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -132,6 +132,9 @@ var readPullRequestPermission = RepoPermission{Action: ReadPullRequestAction} var listBranchesPermission = RepoPermission{Action: ListBranchesAction} var listTagsPermission = RepoPermission{Action: ListTagsAction} var listObjectsPermission = RepoPermission{Action: ListObjectsAction} +var readCommitPermission = RepoPermission{Action: ReadCommitAction} +var listCommitsPermission = RepoPermission{Action: ListCommitsAction} +var createCommitRepoPermission = RepoPermission{Action: CreateCommitAction} var permissionByOp = map[string]PermissionDescriptor{ "HeadObject": &readObjectPermission, @@ -172,6 +175,11 @@ var permissionByOp = map[string]PermissionDescriptor{ "ListBranches": &listBranchesPermission, "ListTags": &listTagsPermission, "ListObjects": &listObjectsPermission, + "GetCommit": &readCommitPermission, + "FindMergeBase": &listCommitsPermission, + "CreateCommitRecord": &createCommitRepoPermission, + "DiffBranch": &listObjectsPermission, + "DiffRefs": &listObjectsPermission, } func GetPermissionDescriptor(operationId string) PermissionDescriptor { From 382228c763d88d72ee41a2caf121ed9e101c5028 Mon Sep 17 00:00:00 2001 From: Tamar Kalir Date: Tue, 18 Nov 2025 20:51:07 +0200 Subject: [PATCH 6/7] migrate branch protection endpoints to use authorizeReq --- pkg/api/controller.go | 35 +--- pkg/permissions/permission.go | 379 +++++++++++++++++----------------- 2 files changed, 198 insertions(+), 216 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 143e5cad09d..2237982fcb4 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -2461,12 +2461,7 @@ func (c *Controller) DeleteRepositoryMetadata(w http.ResponseWriter, r *http.Req } func (c *Controller) GetBranchProtectionRules(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.GetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetBranchProtectionRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2485,12 +2480,7 @@ func (c *Controller) GetBranchProtectionRules(w http.ResponseWriter, r *http.Req } func (c *Controller) SetBranchProtectionRules(w http.ResponseWriter, r *http.Request, body apigen.SetBranchProtectionRulesJSONRequestBody, repository string, params apigen.SetBranchProtectionRulesParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "SetBranchProtectionRules", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3782,12 +3772,7 @@ func (c *Controller) InternalGetBranchProtectionRules(w http.ResponseWriter, r * } func (c *Controller) InternalDeleteBranchProtectionRule(w http.ResponseWriter, r *http.Request, body apigen.InternalDeleteBranchProtectionRuleJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "InternalDeleteBranchProtectionRule", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -3812,12 +3797,7 @@ func (c *Controller) InternalDeleteBranchProtectionRule(w http.ResponseWriter, r } func (c *Controller) CreateBranchProtectionRulePreflight(w http.ResponseWriter, r *http.Request, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "CreateBranchProtectionRulePreflight", permissions.PermissionParams{Repository: &repository}, nil) { return } @@ -3828,12 +3808,7 @@ func (c *Controller) CreateBranchProtectionRulePreflight(w http.ResponseWriter, } func (c *Controller) InternalCreateBranchProtectionRule(w http.ResponseWriter, r *http.Request, body apigen.InternalCreateBranchProtectionRuleJSONRequestBody, repository string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.SetBranchProtectionRulesAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "InternalCreateBranchProtectionRule", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index a91b8ef5ab1..45a743c2a69 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -1,187 +1,194 @@ -package permissions - -const ( - fsArnPrefix = "arn:lakefs:fs:::" - authArnPrefix = "arn:lakefs:auth:::" - - All = "*" -) - -type Permission struct { - Action string - Resource string -} - -type NodeType int - -const ( - NodeTypeNode NodeType = iota - NodeTypeOr - NodeTypeAnd -) - -type Node struct { - Type NodeType - Permission Permission - Nodes []Node -} - -func RepoArn(repoID string) string { - return fsArnPrefix + "repository/" + repoID -} - -func StorageNamespace(namespace string) string { - return fsArnPrefix + "namespace/" + namespace -} - -func ObjectArn(repoID, key string) string { - return fsArnPrefix + "repository/" + repoID + "/object/" + key -} - -func BranchArn(repoID, branchID string) string { - return fsArnPrefix + "repository/" + repoID + "/branch/" + branchID -} - -func TagArn(repoID, tagID string) string { - return fsArnPrefix + "repository/" + repoID + "/tag/" + tagID -} - -func UserArn(userID string) string { - return authArnPrefix + "user/" + userID -} - -func GroupArn(groupID string) string { - return authArnPrefix + "group/" + groupID -} - -func PolicyArn(policyID string) string { - return authArnPrefix + "policy/" + policyID -} - -func ExternalPrincipalArn(principalID string) string { - return authArnPrefix + "externalPrincipal/" + principalID -} - -type PermissionParams struct { - Repository *string - Path *string - Branch *string -} - -type PermissionDescriptor interface { - Permission(PermissionParams) Node -} - -type ObjectPermission struct { - Action string -} - -func (o *ObjectPermission) Permission(params PermissionParams) Node { - return Node{ - Permission: Permission{ - Action: o.Action, - Resource: ObjectArn(*params.Repository, *params.Path), - }, - } -} - -type BranchPermission struct { - Action string -} - -func (o *BranchPermission) Permission(params PermissionParams) Node { - return Node{ - Permission: Permission{ - Action: o.Action, - Resource: ObjectArn(*params.Repository, *params.Branch), - }, - } -} - -type RepoPermission struct { - Action string -} - -func (r *RepoPermission) Permission(params PermissionParams) Node { - return Node{ - Permission: Permission{ - Action: r.Action, - Resource: RepoArn(*params.Repository), - }, - } -} - -var readObjectPermission = ObjectPermission{Action: ReadObjectAction} -var writeObjectPermission = ObjectPermission{Action: WriteObjectAction} -var createBranchPermission = BranchPermission{Action: CreateBranchAction} -var deleteBranchPermission = BranchPermission{Action: DeleteBranchAction} -var readBranchPermission = BranchPermission{Action: ReadBranchAction} -var revertBranchPermission = BranchPermission{Action: RevertBranchAction} -var createCommitPermission = BranchPermission{Action: CreateCommitAction} -var importCancelPermission = BranchPermission{Action: ImportCancelAction} -var prepareGCUncommittedPermission = RepoPermission{Action: PrepareGarbageCollectionUncommittedAction} -var getGCRulesPermission = RepoPermission{Action: GetGarbageCollectionRulesAction} -var setGCRulesPermission = RepoPermission{Action: SetGarbageCollectionRulesAction} -var prepareGCCommitsPermission = RepoPermission{Action: PrepareGarbageCollectionCommitsAction} -var readRepositoryPermission = RepoPermission{Action: ReadRepositoryAction} -var updateRepositoryPermission = RepoPermission{Action: UpdateRepositoryAction} -var deleteRepositoryPermission = RepoPermission{Action: DeleteRepositoryAction} -var writePullRequestPermission = RepoPermission{Action: WritePullRequestAction} -var listPullRequestsPermission = RepoPermission{Action: ListPullRequestsAction} -var readPullRequestPermission = RepoPermission{Action: ReadPullRequestAction} -var listBranchesPermission = RepoPermission{Action: ListBranchesAction} -var listTagsPermission = RepoPermission{Action: ListTagsAction} -var listObjectsPermission = RepoPermission{Action: ListObjectsAction} -var readCommitPermission = RepoPermission{Action: ReadCommitAction} -var listCommitsPermission = RepoPermission{Action: ListCommitsAction} +package permissions + +const ( + fsArnPrefix = "arn:lakefs:fs:::" + authArnPrefix = "arn:lakefs:auth:::" + + All = "*" +) + +type Permission struct { + Action string + Resource string +} + +type NodeType int + +const ( + NodeTypeNode NodeType = iota + NodeTypeOr + NodeTypeAnd +) + +type Node struct { + Type NodeType + Permission Permission + Nodes []Node +} + +func RepoArn(repoID string) string { + return fsArnPrefix + "repository/" + repoID +} + +func StorageNamespace(namespace string) string { + return fsArnPrefix + "namespace/" + namespace +} + +func ObjectArn(repoID, key string) string { + return fsArnPrefix + "repository/" + repoID + "/object/" + key +} + +func BranchArn(repoID, branchID string) string { + return fsArnPrefix + "repository/" + repoID + "/branch/" + branchID +} + +func TagArn(repoID, tagID string) string { + return fsArnPrefix + "repository/" + repoID + "/tag/" + tagID +} + +func UserArn(userID string) string { + return authArnPrefix + "user/" + userID +} + +func GroupArn(groupID string) string { + return authArnPrefix + "group/" + groupID +} + +func PolicyArn(policyID string) string { + return authArnPrefix + "policy/" + policyID +} + +func ExternalPrincipalArn(principalID string) string { + return authArnPrefix + "externalPrincipal/" + principalID +} + +type PermissionParams struct { + Repository *string + Path *string + Branch *string +} + +type PermissionDescriptor interface { + Permission(PermissionParams) Node +} + +type ObjectPermission struct { + Action string +} + +func (o *ObjectPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: o.Action, + Resource: ObjectArn(*params.Repository, *params.Path), + }, + } +} + +type BranchPermission struct { + Action string +} + +func (o *BranchPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: o.Action, + Resource: ObjectArn(*params.Repository, *params.Branch), + }, + } +} + +type RepoPermission struct { + Action string +} + +func (r *RepoPermission) Permission(params PermissionParams) Node { + return Node{ + Permission: Permission{ + Action: r.Action, + Resource: RepoArn(*params.Repository), + }, + } +} + +var readObjectPermission = ObjectPermission{Action: ReadObjectAction} +var writeObjectPermission = ObjectPermission{Action: WriteObjectAction} +var createBranchPermission = BranchPermission{Action: CreateBranchAction} +var deleteBranchPermission = BranchPermission{Action: DeleteBranchAction} +var readBranchPermission = BranchPermission{Action: ReadBranchAction} +var revertBranchPermission = BranchPermission{Action: RevertBranchAction} +var createCommitPermission = BranchPermission{Action: CreateCommitAction} +var importCancelPermission = BranchPermission{Action: ImportCancelAction} +var prepareGCUncommittedPermission = RepoPermission{Action: PrepareGarbageCollectionUncommittedAction} +var getGCRulesPermission = RepoPermission{Action: GetGarbageCollectionRulesAction} +var setGCRulesPermission = RepoPermission{Action: SetGarbageCollectionRulesAction} +var prepareGCCommitsPermission = RepoPermission{Action: PrepareGarbageCollectionCommitsAction} +var readRepositoryPermission = RepoPermission{Action: ReadRepositoryAction} +var updateRepositoryPermission = RepoPermission{Action: UpdateRepositoryAction} +var deleteRepositoryPermission = RepoPermission{Action: DeleteRepositoryAction} +var writePullRequestPermission = RepoPermission{Action: WritePullRequestAction} +var listPullRequestsPermission = RepoPermission{Action: ListPullRequestsAction} +var readPullRequestPermission = RepoPermission{Action: ReadPullRequestAction} +var listBranchesPermission = RepoPermission{Action: ListBranchesAction} +var listTagsPermission = RepoPermission{Action: ListTagsAction} +var listObjectsPermission = RepoPermission{Action: ListObjectsAction} +var readCommitPermission = RepoPermission{Action: ReadCommitAction} +var listCommitsPermission = RepoPermission{Action: ListCommitsAction} var createCommitRepoPermission = RepoPermission{Action: CreateCommitAction} - -var permissionByOp = map[string]PermissionDescriptor{ - "HeadObject": &readObjectPermission, - "GetObject": &readObjectPermission, - "StatObject": &readObjectPermission, - "GetUnderlyingProperties": &readObjectPermission, - "StageObject": &writeObjectPermission, - "CreateSymlinkFile": &writeObjectPermission, - "UpdateObjectUserMetadata": &writeObjectPermission, - "UploadObject": &writeObjectPermission, - "UploadObjectPreflight": &writeObjectPermission, - "CreateBranch": &createBranchPermission, - "DeleteBranch": &deleteBranchPermission, - "GetBranch": &readBranchPermission, - "RevertBranch": &revertBranchPermission, - "LogCommits": &readBranchPermission, - "ResetBranch": &revertBranchPermission, - "MergeIntoBranch": &createCommitPermission, - "HardResetBranch": &revertBranchPermission, - "ImportStatus": &readBranchPermission, - "Commit": &createCommitPermission, - "ImportCancel": &importCancelPermission, - "PrepareGarbageCollectionUncommitted": &prepareGCUncommittedPermission, - "GetGCRules": &getGCRulesPermission, - "SetGCRules": &setGCRulesPermission, - "DeleteGCRules": &setGCRulesPermission, - "SetGarbageCollectionRulesPreflight": &setGCRulesPermission, - "PrepareGarbageCollectionCommits": &prepareGCCommitsPermission, - "GetRepository": &readRepositoryPermission, - "GetRepositoryMetadata": &readRepositoryPermission, - "SetRepositoryMetadata": &updateRepositoryPermission, - "DeleteRepositoryMetadata": &updateRepositoryPermission, - "DeleteRepository": &deleteRepositoryPermission, - "UpdatePullRequest": &writePullRequestPermission, - "CreatePullRequest": &writePullRequestPermission, - "ListPullRequests": &listPullRequestsPermission, - "GetPullRequest": &readPullRequestPermission, - "ListBranches": &listBranchesPermission, - "ListTags": &listTagsPermission, - "ListObjects": &listObjectsPermission, - "GetCommit": &readCommitPermission, - "FindMergeBase": &listCommitsPermission, - "CreateCommitRecord": &createCommitRepoPermission, - "DiffBranch": &listObjectsPermission, - "DiffRefs": &listObjectsPermission, -} - -func GetPermissionDescriptor(operationId string) PermissionDescriptor { - return permissionByOp[operationId] -} +var getBranchProtectionRulesPermission = RepoPermission{Action: GetBranchProtectionRulesAction} +var setBranchProtectionRulesPermission = RepoPermission{Action: SetBranchProtectionRulesAction} + +var permissionByOp = map[string]PermissionDescriptor{ + "HeadObject": &readObjectPermission, + "GetObject": &readObjectPermission, + "StatObject": &readObjectPermission, + "GetUnderlyingProperties": &readObjectPermission, + "StageObject": &writeObjectPermission, + "CreateSymlinkFile": &writeObjectPermission, + "UpdateObjectUserMetadata": &writeObjectPermission, + "UploadObject": &writeObjectPermission, + "UploadObjectPreflight": &writeObjectPermission, + "CreateBranch": &createBranchPermission, + "DeleteBranch": &deleteBranchPermission, + "GetBranch": &readBranchPermission, + "RevertBranch": &revertBranchPermission, + "LogCommits": &readBranchPermission, + "ResetBranch": &revertBranchPermission, + "MergeIntoBranch": &createCommitPermission, + "HardResetBranch": &revertBranchPermission, + "ImportStatus": &readBranchPermission, + "Commit": &createCommitPermission, + "ImportCancel": &importCancelPermission, + "PrepareGarbageCollectionUncommitted": &prepareGCUncommittedPermission, + "GetGCRules": &getGCRulesPermission, + "SetGCRules": &setGCRulesPermission, + "DeleteGCRules": &setGCRulesPermission, + "SetGarbageCollectionRulesPreflight": &setGCRulesPermission, + "PrepareGarbageCollectionCommits": &prepareGCCommitsPermission, + "GetRepository": &readRepositoryPermission, + "GetRepositoryMetadata": &readRepositoryPermission, + "SetRepositoryMetadata": &updateRepositoryPermission, + "DeleteRepositoryMetadata": &updateRepositoryPermission, + "DeleteRepository": &deleteRepositoryPermission, + "UpdatePullRequest": &writePullRequestPermission, + "CreatePullRequest": &writePullRequestPermission, + "ListPullRequests": &listPullRequestsPermission, + "GetPullRequest": &readPullRequestPermission, + "ListBranches": &listBranchesPermission, + "ListTags": &listTagsPermission, + "ListObjects": &listObjectsPermission, + "GetCommit": &readCommitPermission, + "FindMergeBase": &listCommitsPermission, + "CreateCommitRecord": &createCommitRepoPermission, + "DiffBranch": &listObjectsPermission, + "DiffRefs": &listObjectsPermission, + "GetBranchProtectionRules": &getBranchProtectionRulesPermission, + "SetBranchProtectionRules": &setBranchProtectionRulesPermission, + "InternalCreateBranchProtectionRule": &setBranchProtectionRulesPermission, + "CreateBranchProtectionRulePreflight": &setBranchProtectionRulesPermission, + "InternalDeleteBranchProtectionRule": &setBranchProtectionRulesPermission, +} + +func GetPermissionDescriptor(operationId string) PermissionDescriptor { + return permissionByOp[operationId] +} From 3dc82f54947026ae597c5e8767513d6c222f97a4 Mon Sep 17 00:00:00 2001 From: Tamar Kalir Date: Tue, 18 Nov 2025 21:22:28 +0200 Subject: [PATCH 7/7] migrate action endpoints to use authorizeReq --- pkg/api/controller.go | 28 ++++------------------------ pkg/permissions/permission.go | 5 +++++ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/pkg/api/controller.go b/pkg/api/controller.go index 2237982fcb4..839b2735972 100644 --- a/pkg/api/controller.go +++ b/pkg/api/controller.go @@ -2553,12 +2553,7 @@ func (c *Controller) SetGCRules(w http.ResponseWriter, r *http.Request, body api } func (c *Controller) ListRepositoryRuns(w http.ResponseWriter, r *http.Request, repository string, params apigen.ListRepositoryRunsParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListRepositoryRuns", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2621,12 +2616,7 @@ func runResultToActionRun(val *actions.RunResult) apigen.ActionRun { } func (c *Controller) GetRun(w http.ResponseWriter, r *http.Request, repository, runID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRun", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2660,12 +2650,7 @@ func (c *Controller) GetRun(w http.ResponseWriter, r *http.Request, repository, } func (c *Controller) ListRunHooks(w http.ResponseWriter, r *http.Request, repository, runID string, params apigen.ListRunHooksParams) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "ListRunHooks", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() @@ -2725,12 +2710,7 @@ func (c *Controller) ListRunHooks(w http.ResponseWriter, r *http.Request, reposi } func (c *Controller) GetRunHookOutput(w http.ResponseWriter, r *http.Request, repository, runID, hookRunID string) { - if !c.authorize(w, r, permissions.Node{ - Permission: permissions.Permission{ - Action: permissions.ReadActionsAction, - Resource: permissions.RepoArn(repository), - }, - }) { + if !c.authorizeReq(w, r, "GetRunHookOutput", permissions.PermissionParams{Repository: &repository}, nil) { return } ctx := r.Context() diff --git a/pkg/permissions/permission.go b/pkg/permissions/permission.go index 45a743c2a69..44409e4941f 100644 --- a/pkg/permissions/permission.go +++ b/pkg/permissions/permission.go @@ -137,6 +137,7 @@ var listCommitsPermission = RepoPermission{Action: ListCommitsAction} var createCommitRepoPermission = RepoPermission{Action: CreateCommitAction} var getBranchProtectionRulesPermission = RepoPermission{Action: GetBranchProtectionRulesAction} var setBranchProtectionRulesPermission = RepoPermission{Action: SetBranchProtectionRulesAction} +var readActionsPermission = RepoPermission{Action: ReadActionsAction} var permissionByOp = map[string]PermissionDescriptor{ "HeadObject": &readObjectPermission, @@ -187,6 +188,10 @@ var permissionByOp = map[string]PermissionDescriptor{ "InternalCreateBranchProtectionRule": &setBranchProtectionRulesPermission, "CreateBranchProtectionRulePreflight": &setBranchProtectionRulesPermission, "InternalDeleteBranchProtectionRule": &setBranchProtectionRulesPermission, + "ListRepositoryRuns": &readActionsPermission, + "GetRun": &readActionsPermission, + "ListRunHooks": &readActionsPermission, + "GetRunHookOutput": &readActionsPermission, } func GetPermissionDescriptor(operationId string) PermissionDescriptor {