Integrationssign-in providers
Amazon Cognito tokens
Accept Amazon Cognito user pool access or ID tokens on Mayura's server with @mayurajs/auth-cognito: checks, app clients, machines and errors.
- Package
- @mayurajs/auth-cognito
- Install
- npm install mayura @mayurajs/auth-cognito
- Vendor
- Amazon Cognito ↗
Amazon Cognito
user pools sign users in and issue access and ID tokens to your app clients, and access tokens to machines with client
credentials. @mayurajs/auth-cognito turns those tokens into identities for Mayura's server: it is a
jwtAuthenticator already set up for your pool, and
your identity mapping decides what each holder may do. It verifies tokens with mayura/auth's own JWT verifier
(WebCrypto only): no AWS SDK, no dependency, and it runs on every runtime Mayura runs on.
Install
npm install mayura @mayurajs/auth-cognitoCredentials
Nothing secret is needed: no AWS credentials, only your user pool ID (such as us-east-1_AbCdEf123) and the
client IDs of the app clients whose tokens you accept, both in the
Amazon Cognito console on the user pool's overview and App clients pages.
The package reads nothing from the environment: pass the values in yourself, for example from COGNITO_USER_POOL_ID
and COGNITO_CLIENT_ID.
Use it
import { mapCapabilities, principalId } from 'mayura/auth';
import { cognitoAuthenticator } from '@mayurajs/auth-cognito';
export const authenticate = cognitoAuthenticator({
userPoolId: process.env.COGNITO_USER_POOL_ID ?? '', // us-east-1_AbCdEf123
clientIds: [process.env.COGNITO_CLIENT_ID ?? ''],
identity: session => ({
principalId: principalId('cognito', session.subject),
projectId: 'acme',
agentIds: ['support'],
capabilities: mapCapabilities(session.groups, { agents: ['runs:submit', 'runs:read'] }),
}),
});
// createAgentServer({ ..., authenticate })Clients send the access token as the bearer token, as APIs should receive. Key users on session.subject (sub), the
stable id in the pool.
Options
| Option | Default | Meaning |
|---|---|---|
userPoolId |
required | The user pool's id, <region>_<id>. The region is read from it. |
clientIds |
required | The app client ids whose tokens are accepted (lowercase letters and digits). |
identity |
required | What a token's holder may do, or null to refuse. |
tokenUse |
access |
Which tokens are accepted: access, or id for ID tokens; never both. |
allowMachines |
false |
Accept machine (client credentials) access tokens. |
clockSkewMs |
5 s | Clock difference allowed for exp, nbf and iat. At most 60 s. |
maxIdentityMs |
60 s | The longest an identity lasts before the token is checked again (1 s to 1 hour). |
fetch |
globalThis.fetch |
For tests and proxies: the fetch used for the JWKS. |
What is checked
- Issuer and signature. Issued by the pool,
https://cognito-idp.<region>.amazonaws.com/<userPoolId>, and signed with RS256 by a key from<issuer>/.well-known/jwks.json. - Times. The token must carry
expand be unexpired, withclockSkewMsof leeway. - Token use.
token_usemust be the kind you accept: an access token is never accepted as an ID token, nor the other way round. - App client. Access tokens carry no audience: their
client_idmust be one ofclientIds. An ID token'saudmust be. - Machines. An access token with no user name whose subject is its own client is a machine's, and is refused unless
allowMachines.
Cognito can revoke tokens (on sign-out, or when a refresh token is revoked) that still verify until they expire: keep access tokens short-lived. Fetched keys are kept as described in Tokens from an identity provider.
What identity receives
| Field | From |
|---|---|
tokenUse |
access or id. |
subject |
sub: the user's id in the pool, or a machine's app client id. |
username |
username (access) or cognito:username (ID); null for a machine. |
clientId |
client_id (access) or aud (ID). |
machine |
true for a client credentials token. |
groups |
cognito:groups |
scopes |
scope, split on spaces (access tokens only). |
email, emailVerified |
email and email_verified (ID tokens). |
claims |
The verified claims. |
cognitoSession(claims) is exported for checks of your own.
Errors
| What happens | Result |
|---|---|
A configuration mistake: a malformed userPoolId, empty or malformed clientIds, a tokenUse other than access or id, a non-boolean allowMachines |
cognitoAuthenticator() throws MayuraError INVALID_CONFIG. |
The token fails any check, or identity returns null |
authenticate returns null; the server answers 401 AUTH_INVALID. |
| The JWKS cannot be fetched and no keys are cached (or they are over 10 minutes past their age) | MayuraError TOOL_FAILED; the server answers 503 AUTH_UNAVAILABLE. |
identity returns ids or capabilities the server cannot use |
MayuraError INVALID_CONFIG; the server answers 503 AUTH_UNAVAILABLE, never lets the caller in. |
How it is tested
- Unit tests sign real RS256 tokens and serve the pool's JWKS through a fake
fetch. They check access tokens and, withtokenUse: 'id', ID tokens, that one is never accepted for the other, that other clients, pools and keys are refused, and that machines needallowMachines. - A live script,
scripts/live/auth-cognito.mjs, exists but has not passed against a real user pool yet.
Related
- Authentication and API keys: the verifier, key caching and identity mapping.
- Server and client: capabilities and auth errors.
- Okta access tokens and Microsoft Entra ID access tokens: other enterprise issuers.