aws-amplify / amplify-backend

Home to all tools related to Amplify's code-first DX (Gen 2) for building fullstack apps on AWS
Apache License 2.0
140 stars 46 forks source link

Insufficient permissions to execute the `AdminLinkProviderForUser` command #1382

Open eechih opened 2 months ago

eechih commented 2 months ago

Environment information

System:
  OS: Linux 6.5 Ubuntu 22.04.4 LTS 22.04.4 LTS (Jammy Jellyfish)
  CPU: (12) x64 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
  Memory: 53.89 GB / 62.64 GB
  Shell: /usr/bin/zsh
Binaries:
  Node: 18.15.0 - ~/.nvm/versions/node/v18.15.0/bin/node
  Yarn: 1.22.19 - ~/.nvm/versions/node/v18.15.0/bin/yarn
  npm: 9.6.2 - ~/.nvm/versions/node/v18.15.0/bin/npm
  pnpm: 8.5.1 - ~/.nvm/versions/node/v18.15.0/bin/pnpm
NPM Packages:
  @aws-amplify/backend: 0.13.2
  @aws-amplify/backend-cli: 0.13.0
  aws-amplify: 6.0.30
  aws-cdk: 2.138.0
  aws-cdk-lib: 2.138.0
  typescript: 5.4.5
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Description

I have a function that needs to use the AdminLinkProviderForUserCommand command, but the "manageUsers" action does not seem to contain the 'cognito-idp:AdminLinkProviderForUser' action.

// amplify/auth/resource.ts

import { linkProviderForUserFunction } from '@/amplify/functions/link-provider-for-user/resource'

export const auth = defineAuth({
  ...
  access: allow => [
    allow.resource(linkProviderForUserFunction).to(['manageUsers']),
  ],
})
// amplify/functions/link-provider-for-user/handler.ts

import { env } from '$amplify/env/link-provider-for-user'
import type { Schema } from '@/amplify/data/resource'
import {
  AdminLinkProviderForUserCommand,
  CognitoIdentityProviderClient,
  InvalidParameterException,
} from '@aws-sdk/client-cognito-identity-provider'
import { AppSyncIdentityCognito } from 'aws-lambda'

const client = new CognitoIdentityProviderClient()

export const handler: Schema['linkProviderForUser']['functionHandler'] =
  async event => {
    const { providerName, providerUserId } = event.arguments
    const identity = event.identity as AppSyncIdentityCognito

    const command = new AdminLinkProviderForUserCommand({
      UserPoolId: env.AMPLIFY_AUTH_USERPOOL_ID,
      DestinationUser: {
        ProviderName: 'Cognito',
        ProviderAttributeValue: identity.username,
      },
      SourceUser: {
        ProviderName: providerName,
        ProviderAttributeName: 'Cognito_Subject',
        ProviderAttributeValue: providerUserId,
      },
    })

    const response = await client.send(command)
    ...
  }

The following error occurs:

2024-04-26T01:10:30.391Z    5eada46c-eea6-4093-8b5e-0f4557193695    ERROR   Invoke Error    {
    "errorType": "AccessDeniedException",
    "errorMessage": "User: arn:aws:sts::089370838833:assumed-role/amplify-drinkshopbackend--linkproviderforuserlambda-Hji1xUz2DDsw/amplify-drinkshopbackend--linkproviderforuserlambd-GNHSJOXwO4To is not authorized to perform: cognito-idp:AdminLinkProviderForUser on resource: arn:aws:cognito-idp:us-east-1:089370838833:userpool/us-east-1_SPrRZH9Kd because no identity-based policy allows the cognito-idp:AdminLinkProviderForUser action",
    ...
}

Is there any solution? Thanks.

ykethan commented 2 months ago

Hey @eechih, thank you for reaching out. The issue appears to be similar to https://github.com/aws-amplify/amplify-backend/issues/1375, refer to the comment https://github.com/aws-amplify/amplify-backend/issues/1375#issuecomment-2079388509 using override to add the permissions Marking this as feature request.

eechih commented 2 months ago

@ykethan Thanks a lot, that worked :)