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

Error "No Credentials" when using auth mode: "iam" #12985

Closed
3 tasks done
asp3 opened this issue Feb 8, 2024 · 6 comments
Closed
3 tasks done

Error "No Credentials" when using auth mode: "iam" #12985

asp3 opened this issue Feb 8, 2024 · 6 comments
Assignees
Labels
GraphQL Related to GraphQL API issues question General question

Comments

@asp3
Copy link

asp3 commented Feb 8, 2024

Before opening, please confirm:

JavaScript Framework

React Native, Next.js

Amplify APIs

Authentication, GraphQL API

Amplify Version

v6

Amplify Categories

auth, api

Backend

Amplify CLI

Environment information

  System:
    OS: macOS 14.0
    CPU: (12) arm64 Apple M2 Max
    Memory: 5.76 GB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.6.1 - ~/.nvm/versions/node/v20.6.1/bin/node
    Yarn: 1.22.5 - ~/.yarn/bin/yarn
    npm: 9.8.1 - ~/.nvm/versions/node/v20.6.1/bin/npm
    Watchman: 2023.10.23.00 - /usr/local/bin/watchman
  Browsers:
    Brave Browser: 114.1.52.130
    Chrome: 121.0.6167.139
    Safari: 17.0
  npmPackages:
    @knowt/eslint-config: * => 0.0.0 
    dotenv-cli: latest => 7.3.0 
    husky: ^8.0.0 => 8.0.3 
    lint-staged: ^12.4.0 => 12.5.0 
    prettier: ^2.7.1 => 2.8.8 
    turbo: ^1.10.12 => 1.10.16 
  npmGlobalPackages:
    @aws-amplify/cli: 12.10.1
    amplify: 0.0.11
    appcenter-cli: 2.14.0
    corepack: 0.19.0
    eas-cli: 5.4.0
    eslint: 8.56.0
    expo-cli: 6.3.10
    npm-check: 6.0.1
    npm: 9.8.1

Describe the bug

All authenticated calls work perfectly with the new v6 library, as the Authorization header is set. However, when trying to make unauthorized calls with authMode = "iam", we run into the error as described.

image

Expected behavior

I would expect IAM calls work as they did with the previous library, and are able to be made.

Reproduction steps

  1. Set up appsync API with User pool access (default) and IAM as a secondary provider
  2. make API call with auth, see that it works fine
  3. see that any unauthorized call when authMode = "iam" does not work and throws an error.

Verified from my end that the issue is that the call is never even made, not that the connected resolver is rejecting this request.

Code Snippet

try {
    return await client.graphql({
        query,
        variables,

       // removing this line will make the call return successfully. 
        authMode: GRAPHQL_AUTH_MODE.AWS_IAM,
    });
} catch (e) {
    report(e, queryName, variables);
    throw e;
}

Log output

// Put your logs below this line


aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

@asp3 asp3 added the pending-triage Issue is pending triage label Feb 8, 2024
@asp3 asp3 changed the title Error "No Credentials" when using auth_mode: "iam" Error "No Credentials" when using auth mode: "iam" Feb 8, 2024
@asp3
Copy link
Author

asp3 commented Feb 8, 2024

after enabling allowGuestAccess: true in the aws_v6, it no longer fails at the _headerBasedAuth function, but the error now is:

{
  data: {},
  errors: [
    UnauthorizedException: Unknown error
        at buildRestApiError (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/serviceError.mjs:87:26)
        at parseRestApiServiceError (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/serviceError.mjs:30:16)
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async job (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-rest/dist/esm/utils/createCancellableOperation.mjs:31:23)
        at async GraphQLAPIClass._graphql (webpack-internal:///(rsc)/../../node_modules/@aws-amplify/api-graphql/dist/esm/internals/InternalGraphQLAPI.mjs:239:44)
        at async runWithAmplifyServerContext (webpack-internal:///(rsc)/../../node_modules/aws-amplify/dist/esm/adapterCore/runWithAmplifyServerContext.mjs:23:24)
        at async Object.query (webpack-internal:///(rsc)/../../packages/syncing/utils/SyncUtils.ts:51:24)
        at async runESQueryFull (webpack-internal:///(rsc)/../../packages/syncing/fetchFunctions/elasticsearch.ts:491:12)
        at async fetchFlashcardSetsResult (webpack-internal:///(rsc)/./features/WithPreviewerPages/utils.ts:133:33)
        at async getTopFlashcardSets (webpack-internal:///(rsc)/./features/WithPreviewerPages/utils.ts:232:12)
        at async ExplorePage (webpack-internal:///(rsc)/./features/LandingPages/ExplorePage/ExplorePage.tsx:55:41) {
      recoverySuggestion: `If you're calling an Amplify-generated API, make sure to set the "authMode" in generateClient({ authMode: '...' }) to the backend authorization rule's auth provider ('apiKey', 'userPool', 'iam', 'oidc', 'lambda')`
    }
  ]
}

same error as in #12931

@asp3
Copy link
Author

asp3 commented Feb 8, 2024

In case anyone else runs into this, not sending an Authorization when making an IAM call fixed it for me. Found that deep in the amplify code somewhere, iam calls MUST NOT pass the authorization header.

This conflicted with some other code that I saw in another issue. Hopefully this helps someone else who came across this!

Amplify.configure(awsConfig, {
    ssr: true,
    API: {
        GraphQL: {
            headers: async () => {
                const idToken = (await fetchAuthSession()).tokens?.idToken?.toString();

                if (!idToken) return {};
                return {
                    Authorization: idToken,
                };
            },
        },
    },
});

instead of

Amplify.configure(awsConfig, {
    ssr: true,
    API: {
        GraphQL: {
            headers: async () => ({
                    Authorization: (await fetchAuthSession()).tokens?.idToken?.toString(),
                }),
            },
        },
    },
});

@cwomack cwomack self-assigned this Feb 9, 2024
@cwomack cwomack added the GraphQL Related to GraphQL API issues label Feb 9, 2024
@HuiSF
Copy link
Member

HuiSF commented Feb 9, 2024

Hi @asp3 while you are enabling allowGuestAccess: true have you enabled "unauthenticated access" in your Cognito User Pool?

Looking the code path that throws "No Credentials", it's typically due to the fetchAuthSession cannot retrieve credentials from user pool while there is no user signed in and the user pool has not enabled unauthenticated access.

@asp3
Copy link
Author

asp3 commented Feb 9, 2024

@HuiSF Yep, our cognito has had it enabled since we began (we have been using amplify for a few years now), its all working for me now again with v6. From what I can see, it seems the issue was 2 fold.

The initial "No Credentials" error was solved by adding allowGuestAccess: true.
However, that led to the error above, UnauthorizedException: Unknown error.

This was due to the fact that I needed idToken instead of the default accessToken, so I had configured an override in the Amplify.configure call (like so)

Amplify.configure(awsConfig, {
    ssr: true,
    API: {
        GraphQL: {
            headers: async () => ({
                    Authorization: (await fetchAuthSession()).tokens?.idToken?.toString(),
                }),
            },
        },
    },
});

However, in this scenario, for unauth users, it would pass headers as:

{
    Authorization: undefined
}

but since the key was present, I assume it thought it was still in the userPools mode instead of iam. After fixing it to pass blank headers if the idToken is undefined, everything now works as expected.

Amplify.configure(awsConfig, {
    ssr: true,
    API: {
        GraphQL: {
            headers: async () => {
                const idToken = (await fetchAuthSession()).tokens?.idToken?.toString();

                if (!idToken) return {};
                return {
                    Authorization: idToken,
                };
            },
        },
    },
});

@chrisbonifacio chrisbonifacio added question General question and removed pending-triage Issue is pending triage labels Feb 9, 2024
@cwomack
Copy link
Member

cwomack commented Feb 9, 2024

@asp3, quick follow up question for you on this. Is there a section of the docs that you feel could have expanded on this since you've just gone through it seeking the answer? Want to see if we can ensure this confusion can be prevented for future readers if possible. Thanks!

@hanna-becker
Copy link

To answer the question, since I also ran into this and wasted almost an entire day troubleshooting. Not sending the Auth header to make public guest access with iam work should be mentioned somewhere around here in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GraphQL Related to GraphQL API issues question General question
Projects
None yet
Development

No branches or pull requests

5 participants