diff --git a/policy/actionset.go b/policy/actionset.go index 2eb2d0b..ab4c50d 100644 --- a/policy/actionset.go +++ b/policy/actionset.go @@ -53,9 +53,8 @@ var implicitActions = map[Action]ActionSet{ GetObjectVersionAction: NewActionSet(GetObjectAction), // S3Tables actions implicitly allow their data actions - Action(S3TablesGetTableDataAction): NewActionSet(GetObjectAction, ListMultipartUploadPartsAction), - Action(S3TablesPutTableDataAction): NewActionSet(PutObjectAction, AbortMultipartUploadAction, ListBucketAction), - Action(S3TablesDeleteTableDataAction): NewActionSet(DeleteObjectAction), + Action(S3TablesGetTableDataAction): NewActionSet(GetObjectAction, ListMultipartUploadPartsAction), + Action(S3TablesPutTableDataAction): NewActionSet(PutObjectAction, AbortMultipartUploadAction, ListBucketAction), // Action(S3TablesDeleteTableAction) implicitly allows DeleteObjectAction to support table purging. // This is needed because Spark's DROP TABLE ... PURGE performs client-side deletes rather than // using purgeRequested=true to let the catalog handle deletion. This workaround grants the diff --git a/policy/policy_test.go b/policy/policy_test.go index b3f2a4d..266185f 100644 --- a/policy/policy_test.go +++ b/policy/policy_test.go @@ -2257,17 +2257,6 @@ func TestS3TablesActionsWithImplicitMatching(t *testing.T) { ] }` - policy5JSON := `{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": ["s3tables:DeleteTableData"], - "Resource": ["arn:aws:s3tables:::bucket/del-warehouse/table/uuid-789"] - } - ] - }` - testCases := []struct { name string policyJSON string @@ -2394,60 +2383,6 @@ func TestS3TablesActionsWithImplicitMatching(t *testing.T) { expectedResult: true, description: "Should match PutObject when both GetTableData and PutTableData are allowed", }, - { - name: "DeleteTableData direct match", - policyJSON: policy5JSON, - args: Args{ - Action: Action(S3TablesDeleteTableDataAction), - BucketName: "bucket/del-warehouse/table/uuid-789", - }, - expectedResult: true, - description: "DeleteTableData action should match S3 Tables resource directly", - }, - { - name: "DeleteTableData implicit DeleteObject match", - policyJSON: policy5JSON, - args: Args{ - Action: DeleteObjectAction, - BucketName: "bucket", - ObjectName: "del-warehouse/table/uuid-789", - }, - expectedResult: true, - description: "DeleteObject (implicit from DeleteTableData) should match on the table resource", - }, - { - name: "DeleteTableData implicit DeleteObject with extra path", - policyJSON: policy5JSON, - args: Args{ - Action: DeleteObjectAction, - BucketName: "del-warehouse", - ObjectName: "uuid-789/data/file.parquet", - }, - expectedResult: false, - description: "a plain object path is not table data until the server presents it in tables form", - }, - { - name: "DeleteTableData wrong table uuid - should not match", - policyJSON: policy5JSON, - args: Args{ - Action: DeleteObjectAction, - BucketName: "del-warehouse", - ObjectName: "wrong-uuid", - }, - expectedResult: false, - description: "Should not match when table UUID doesn't match", - }, - { - name: "DeleteTableData does not grant PutObject", - policyJSON: policy5JSON, - args: Args{ - Action: PutObjectAction, - BucketName: "del-warehouse", - ObjectName: "uuid-789", - }, - expectedResult: false, - description: "PutObject is not implicit from DeleteTableData, should not match", - }, { name: "Non-implicit action should not match", policyJSON: policy1JSON, diff --git a/policy/table-action.go b/policy/table-action.go index 86422cc..67fa9d7 100644 --- a/policy/table-action.go +++ b/policy/table-action.go @@ -37,10 +37,6 @@ const ( // S3TablesDeleteTableAction maps to the AWS `DeleteTable` S3 Tables action. S3TablesDeleteTableAction TableAction = "s3tables:DeleteTable" - // S3TablesDeleteTableDataAction is an AIStor extension granting deletion of a - // table's underlying data objects. - S3TablesDeleteTableDataAction TableAction = "s3tables:DeleteTableData" - // S3TablesDeleteTableEncryptionAction is an AIStor extension for deleting a // table-level encryption configuration override. S3TablesDeleteTableEncryptionAction TableAction = "s3tables:DeleteTableEncryption" @@ -278,7 +274,6 @@ var SupportedTableActions = map[TableAction]struct{}{ S3TablesDeleteTableBucketAction: {}, S3TablesDeleteTableBucketEncryptionAction: {}, S3TablesDeleteTableBucketPolicyAction: {}, - S3TablesDeleteTableDataAction: {}, S3TablesDeleteTableEncryptionAction: {}, S3TablesDeleteTablePolicyAction: {}, S3TablesGetNamespaceAction: {}, @@ -430,7 +425,6 @@ func createTableActionConditionKeyMap() map[Action]condition.KeySet { tableActionConditionKeyMap[Action(S3TablesDeleteTableBucketAction)] = withWarehouseCommon() tableActionConditionKeyMap[Action(S3TablesDeleteTableBucketEncryptionAction)] = withWarehouseCommon() tableActionConditionKeyMap[Action(S3TablesDeleteTableBucketPolicyAction)] = withWarehouseCommon() - tableActionConditionKeyMap[Action(S3TablesDeleteTableDataAction)] = withTableCommon() tableActionConditionKeyMap[Action(S3TablesDeleteTableEncryptionAction)] = withTableCommon() tableActionConditionKeyMap[Action(S3TablesDeleteTablePolicyAction)] = withTableCommon() tableActionConditionKeyMap[Action(S3TablesGetNamespaceAction)] = withWarehouseCommon(s3TablesNamespaceKey)