You're on the right path by setting up an AWS Cognito User Pool and a Snowflake external OAuth security integration, but a key detail in how AWS Cognito issues access tokens for machine-to-machine app clients is causing this issue.
issue: Missing aud (audience) claim
AWS Cognito, when used for machine-to-machine (client credentials flow), issues access tokens that do not contain an aud claim by default — only an access_token is returned and it’s formatted for use with AWS APIs (not generic OAuth 2.0 providers like Snowflake).
Snowflake, however, requires the aud claim (audience) in the JWT and validates it against the external_oauth_audience_list in your security integration.
AWS Cognito doesn't allow you to customize the aud claim in the access token for machine-to-machine apps.
You cannot add a custom audience (like your Snowflake URL) to the JWT access token issued by Cognito for this flow.
Option 1: Use a custom authorizer (e.g., AWS API Gateway + Lambda)
This is a middleware pattern:
Call a Lambda that:
Validates the Cognito token.
Issues a custom JWT token (signed with your own private key / JWKS endpoint).
Includes the correct aud claim for Snowflake (e.g., your Snowflake URL).
Configure Snowflake’s EXTERNAL_OAUTH_JWS_KEYS_URL to point to the JWKS endpoint for your custom tokens.
Steps in the documents as pointed above by Srinath Menon
Option 2: Use a proper OAuth 2.0 Provider that supports client_credentials flow with configurable audience
Providers like Auth0, Okta, Azure AD, or Keycloak let you define custom aud claims in the issued token — better suited for Snowflake M2M auth.