Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot setup Storage access permission for Owner if user is in a Group #1771

Open
mausic opened this issue Jul 22, 2024 · 2 comments
Open

Cannot setup Storage access permission for Owner if user is in a Group #1771

mausic opened this issue Jul 22, 2024 · 2 comments
Labels
bug Something isn't working storage Related to the storage experience

Comments

@mausic
Copy link

mausic commented Jul 22, 2024

Environment information

System:
  OS: macOS 14.5
  CPU: (10) arm64 Apple M1 Pro
  Memory: 153.94 MB / 16.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.11.1 - ~/.nvm/versions/node/v20.11.1/bin/node
  Yarn: 1.22.19 - ~/.nvm/versions/node/v20.11.1/bin/yarn
  npm: 10.8.1 - ~/.nvm/versions/node/v20.11.1/bin/npm
  pnpm: 9.5.0 - ~/Library/pnpm/pnpm
NPM Packages:
  @aws-amplify/backend: Not Found
  @aws-amplify/backend-cli: 1.1.0
  aws-amplify: Not Found
  aws-cdk: Not Found
  aws-cdk-lib: Not Found
  typescript: Not Found
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Description

In AWS Amplify Gen 2.0 there is an issue or a bug related to Owner-based storage permissions and auth groups.

If authenticated user is within a Group, for example, Users, it is impossible to set up Owner-based access rules for Storage without specifying the same-level group permission.
For example.

  1. We have the following auth setup at amplify/auth/resource.ts file
export const auth = defineAuth({
  loginWith: {
    email: {
      verificationEmailStyle: "CODE",
      verificationEmailSubject: "Welcome to the App",
      verificationEmailBody: (createCode) =>
        `Use this code to verify your account: ${createCode()}`,
    },
    callbackUrls: [
        "http://localhost:3000/auth/google/callback",
        "app://",
      ],
      logoutUrls: ["http://localhost:3000/", "app://"],
    },
  },
  groups: ["Admins", "Managers", "Users"],
});
  1. We have the following storage setup at amplify/storage/resource.ts
export const storage = defineStorage({
  name: "storage",
  access: (allow) => ({
    "profiles/{entity_id}/*": [
      allow.entity("identity").to(["write", "delete", "read"]),
      allow.authenticated.to(["read"]),
      allow.groups(["Admins", "Managers", ]).to(["write", "delete", "read"]),
    ],
  }),
});
  1. We have an authenticated user in the Users group.

Now, if we try to upload a file such as

const result = await uploadData({
  path: ({ identityId }) => {
    return `profiles/${identityId}/image.jpg`;
  },
  data: imageBlob,
  options: {
    contentType: mimeType,
    contentDisposition: "inline",
   },
}).result;

we will get AccessDenied error.

The only way to fix this is to either remove the user from the group (which is breaking business logic relying on user groups) or to change amplify/storage/resource.ts file by adding a Users group permission to it, such as:

export const storage = defineStorage({
  name: "storage",
  access: (allow) => ({
    "profiles/{entity_id}/*": [
      allow.entity("identity").to(["write", "delete", "read"]),
      allow.authenticated.to(["read"]),
      allow.groups(["Admins", "Managers","Users" ]).to(["write", "delete", "read"]),
    ],
  }),
});

which breaks Owner-based storage permissions and allows anyone in the Users group to modify other users' files.

@mausic mausic added the pending-triage Incoming issues that need categorization label Jul 22, 2024
@ykethan ykethan added the storage Related to the storage experience label Jul 22, 2024
@ykethan
Copy link
Member

ykethan commented Jul 24, 2024

Hey @mausic, thank you for reaching out. I was able to reproduce the issue, marking this as bug for further improvements.

@brandonwatson
Copy link

I too hit this problem today. Spoke with Harshita Daddala about it.

My use case is similar. I have "ADMINS" and "USERS" - USERS is meant to be a benign holding group. I auto assign the users on signup to USERS and have ADMINS who can access everything.

I was surprised to see that the group membership would completely supersede the individual entity level rights.

As a developer, I would expect a UNION of role based security of groups and individual user auth rules set in AUTH.

I was trying to use FileUploader and StorageImage in a client component (nextjs and mostly server-side rendering in my application). The URL was being correctly created in the FileUploader component, with the correct identityId, which is what caused me so much trouble in tracking down what was happening. I eventually inspected the error in the console and saw:

Error uploading file protected/images/{identityId}/{correct rest of path}: User: <snip>assumed-role/amplify-reintern-watso-sa-amplifyAuthUSERSGroupRole-BMAf5LXBRxas/CognitoIdentityCredentials is not authorized to perform: s3:PutObject on resource: "<snip>/protected/images/{identityId}/{rest of path}" because no identity-based policy allows the s3:PutObject action
It wasn't until I noticed "USERSGroupRole" that I zeroed in on the problem. The solve was non-intuitive as I would have thought that setting up my auth as follows would allow for an individual level scoping of auth rights:

export const auth = defineAuth({
	loginWith: {
		email: {
			verificationEmailStyle: 'CODE',
			verificationEmailSubject:
				'Verification Email for AllTheInterns.com',
			verificationEmailBody: (createCode) =>
				`Thank you for creating a new user account with AllTheInterns. Please use this code to confirm your account: ${createCode()}`,
		},
	},
	groups: ['ADMINS', 'USERS'],
	// triggers: {
	// 	postConfirmation,
	// },
	// access: (allow) => [
	// 	allow.resource(postConfirmation).to(['addUserToGroup']),
	// ],
});

As you can see, I have commented out the triggered lambda which auto-assigns to USERS group. Also removed the impacted user (I'm still in dev mode, so it's a single account) from the USERS group. Permission errors went away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working storage Related to the storage experience
Projects
None yet
Development

No branches or pull requests

3 participants