Skip to content

Commit d538ecc

Browse files
authored
add storage access rules to outputs (#1927)
* add storage access rules to outputs * fix tests * remove read action from storage access rule outputs in favor of get and list * update api.md * update permissions for non entity roles for entity_id paths * add entity id substitution constant * add comments for new behavior with owner paths * add back read * pr feedback * update api.md
1 parent 190239a commit d538ecc

37 files changed

+1470
-142
lines changed

.changeset/two-sloths-clap.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@aws-amplify/client-config': minor
3+
'@aws-amplify/backend-output-schemas': patch
4+
'@aws-amplify/integration-tests': patch
5+
'@aws-amplify/backend-storage': patch
6+
'@aws-amplify/backend': patch
7+
'@aws-amplify/backend-cli': patch
8+
---
9+
10+
add storage access rules to outputs

packages/backend-output-schemas/src/storage/v1.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
import { z } from 'zod';
22

3+
const storageAccessActionEnum = z.enum([
4+
'read',
5+
'get',
6+
'list',
7+
'write',
8+
'delete',
9+
]);
10+
11+
const pathSchema = z.record(
12+
z.string(),
13+
z.object({
14+
guest: z.array(storageAccessActionEnum).optional(),
15+
authenticated: z.array(storageAccessActionEnum).optional(),
16+
groups: z.array(storageAccessActionEnum).optional(),
17+
entity: z.array(storageAccessActionEnum).optional(),
18+
resource: z.array(storageAccessActionEnum).optional(),
19+
})
20+
);
21+
322
const bucketSchema = z.object({
423
name: z.string(),
524
bucketName: z.string(),
625
storageRegion: z.string(),
26+
paths: pathSchema.optional(),
727
});
828

929
export const storageOutputSchema = z.object({

packages/backend-storage/src/access_builder.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
ResourceProvider,
66
} from '@aws-amplify/plugin-types';
77
import { StorageAccessBuilder } from './types.js';
8+
import { entityIdSubstitution } from './constants.js';
89

910
export const roleAccessBuilder: StorageAccessBuilder = {
1011
authenticated: {
@@ -69,7 +70,7 @@ export const roleAccessBuilder: StorageAccessBuilder = {
6970
},
7071
],
7172
actions,
72-
idSubstitution: '${cognito-identity.amazonaws.com:sub}',
73+
idSubstitution: entityIdSubstitution,
7374
}),
7475
}),
7576
resource: (other) => ({
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const entityIdPathToken = '{entity_id}';
2+
export const entityIdSubstitution = '${cognito-identity.amazonaws.com:sub}';

packages/backend-storage/src/construct.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { AttributionMetadataStorage } from '@aws-amplify/backend-output-storage'
2020
import { fileURLToPath } from 'node:url';
2121
import { IFunction } from 'aws-cdk-lib/aws-lambda';
2222
import { S3EventSourceV2 } from 'aws-cdk-lib/aws-lambda-event-sources';
23+
import { StorageAccessDefinitionOutput } from './private_types.js';
2324

2425
// Be very careful editing this value. It is the string that is used to attribute stacks to Amplify Storage in BI metrics
2526
const storageStackType = 'storage-S3';
@@ -84,6 +85,7 @@ export class AmplifyStorage
8485
readonly resources: StorageResources;
8586
readonly isDefault: boolean;
8687
readonly name: string;
88+
accessDefinition: StorageAccessDefinitionOutput;
8789
/**
8890
* Create a new AmplifyStorage instance
8991
*/
@@ -146,4 +148,11 @@ export class AmplifyStorage
146148
new S3EventSourceV2(this.resources.bucket, { events })
147149
);
148150
};
151+
152+
/**
153+
* Add access definitions to storage
154+
*/
155+
addAccessDefinition = (accessOutput: StorageAccessDefinitionOutput) => {
156+
this.accessDefinition = accessOutput;
157+
};
149158
}

packages/backend-storage/src/private_types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ export type StorageError =
1515
* StorageAction type intended to be used after mapping "read" to "get" and "list"
1616
*/
1717
export type InternalStorageAction = Exclude<StorageAction, 'read'>;
18+
19+
/**
20+
* Storage access types intended to be used to map storage access to storage outputs
21+
*/
22+
export type StorageAccessConfig = Record<string, InternalStorageAction[]>;
23+
export type StorageAccessDefinitionOutput = Record<string, StorageAccessConfig>;

0 commit comments

Comments
 (0)