Skip to main content

Cognito

caution

This is the SST v1.x Constructs doc. SST v2 is now released. If you are using v2, see the v2 Constructs doc. If you are looking to upgrade to v2, check out the upgrade steps.

The Auth construct is a higher level CDK construct that makes it easy to configure a Cognito User Pool and Cognito Identity Pool. Also, allows setting up Auth0, Facebook, Google, Twitter, Apple, and Amazon as authentication providers.

Examples

Using the minimal config

import { Cognito } from "@serverless-stack/resources";

new Cognito(stack, "Auth");

Configuring login

You can configure how a user can sign in to our application for our User Pool. For example, you might want a user to be able to sign in with their email or username. Or with their phone number.

There are two ways of setting this up.

  1. User signs up with username and signs in with username or alias

    A user signs up with a username. In addition to the username, you can optionally allow users to sign in with one or more of the following aliases:

    Note that, the username that Cognito refers to, is an internally used user id. So in practice, you'll ask a user to create a new username, this is called the preferred username by Cognito.

    • A verified email address
    • A verified phone number
    • A preferred username

    These aliases can be changed after the user signs up.

    To use this option, set the login prop to:

    new Cognito(stack, "Auth", {
    login: ["email", "phone", "username", "preferredUsername"]
    });

    Read more on this over on the AWS docs.

  2. User signs up and signs in with email or phone number instead of username

    A user signs up with an email address or phone number as their username. You can choose whether to allow sign-up with only email addresses, only phone numbers, or either one.

    Note that, the email or phone number that gets set as a username needs to be unique. This is because when Cognito refers to the username, it really refers to an internally used user id.

    In addition, if a user signs up with an email address, they can only change it to another email address and not a phone number. The same applies if they sign up with a phone number. It cannot be changed to an email.

    To use this option, set the login prop to:

    new Cognito(stack, "Auth", {
    login: ["email", "phone"]
    });

    Read more on this over on the AWS docs.

Configuring triggers

The Cognito User Pool can invoke a Lambda function for specific triggers.

Adding triggers

new Cognito(stack, "Auth", {
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
});

Specifying function props for all the triggers

new Cognito(stack, "Auth", {
defaults: {
function: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
},
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
});

Configuring an individual trigger

Configure each Lambda function separately.

new Cognito(stack, "Auth", {
triggers: {
preAuthentication: {
handler: "src/preAuthentication.main",
timeout: 10,
environment: { bucketName: bucket.bucketName },
permissions: [bucket],
},
postAuthentication: "src/postAuthentication.main",
},
});

Note that, you can set the defaults.function while using the FunctionProps per trigger. The function will just override the defaults.function. Except for the environment, the layers, and the permissions properties, it will be merged.

new Cognito(stack, "Auth", {
defaults: {
function: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
},
triggers: {
preAuthentication: {
handler: "src/preAuthentication.main",
timeout: 10,
environment: { bucketName: bucket.bucketName },
permissions: [bucket],
},
postAuthentication: "src/postAuthentication.main",
},
});

So in the above example, the preAuthentication function doesn't use the timeout that is set in the defaults.function. It'll instead use the one that is defined in the function definition (10 seconds). And the function will have both the tableName and the bucketName environment variables set; as well as permissions to both the table and the bucket.

Attaching permissions for all triggers

Allow all the triggers to access S3.

const auth = new Cognito(stack, "Auth", {
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
});

auth.attachPermissionsForTriggers(["s3"]);

Attaching permissions for a specific trigger

Allow one of the triggers to access S3.

const auth = new Cognito(stack, "Auth", {
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
});

auth.attachPermissionsForTriggers("preAuthentication", ["s3"]);

Here we are referring to the trigger using the trigger key, preAuthentication.

Identity Pool federation

Enabling federation with Auth0

new Cognito(stack, "Auth", {
identityPoolFederation: {
auth0: {
domain: "https://myorg.us.auth0.com",
clientId: "UsGRQJJz5sDfPQDs6bhQ9Oc3hNISuVif",
},
},
});

Enabling federation with Twitter

new Cognito(stack, "Auth", {
identityPoolFederation: {
twitter: {
consumerKey: "gyMbPOiwefr6x63SjIW8NN2d9",
consumerSecret: "qxld1zic5c2eyahqK3gjGLGQaOTogGfAgGh17MYOIcOUR9l2Nz",
},
},
});

Enabling federation with multiple social logins

new Cognito(stack, "Auth", {
identityPoolFederation: {
facebook: { appId: "419718329085014" },
apple: { servicesId: "com.myapp.client" },
amazon: { appId: "amzn1.application.24ebe4ee4aef41e5acff038aee2ee65f" },
google: {
clientId:
"38017095028-abcdjaaaidbgt3kfhuoh3n5ts08vodt3.apps.googleusercontent.com",
},
},
});

Attaching permissions for authenticated federation identity

const auth = new Cognito(stack, "Auth");

auth.attachPermissionsForAuthUsers(stack, [api, "s3"]);

Attaching permissions for unauthenticated federation identity

const auth = new Cognito(stack, "Auth");

auth.attachPermissionsForUnauthUsers(stack, [api, "s3"]);

Advanced examples

Configuring attributes

import {
StringAttribute,
NumberAttribute,
BooleanAttribute,
DateTimeAttribute,
} from "aws-cdk-lib/aws-cognito";

new Cognito(stack, "Auth", {
cdk: {
userPool: {
standardAttributes: {
fullname: { required: true, mutable: false },
address: { required: false, mutable: true },
},
customAttributes: {
'gameId': new StringAttribute({ minLen: 5, maxLen: 15, mutable: false }),
'participants': new NumberAttribute({ min: 1, max: 3, mutable: true }),
'isCompleted': new BooleanAttribute({ mutable: true }),
'startedAt': new DateTimeAttribute(),
},
}
},
});

Importing an existing User Pool

Override the internally created CDK UserPool and UserPoolClient instance.

import { UserPool, UserPoolClient } from "aws-cdk-lib/aws-cognito";

new Cognito(stack, "Auth", {
cdk: {
userPool: UserPool.fromUserPoolId(stack, "IUserPool", "pool-id"),
userPoolClient: UserPoolClient.fromUserPoolClientId(stack, "IUserPoolClient", "pool-client-id"),
},
});

Adding additional clients

You can create additional clients for the Cognito user pool.

const cognito = new Cognito(stack, "Auth");

cognito.cdk.userPool.addClient("anotherClient", {
authFlows: {
userPassword: true,
userSrp: true,
},
});

Sharing Auth across stacks

You can create the Auth construct in one stack, and attach permissions in other stacks. To do this, return the Auth construct from your stack function.

stacks/AuthStack.ts
import { Cognito, StackContext } from "@serverless-stack/resources";

export function AuthStack({ stack }: StackContext) {
const auth = new Cognito(stack, "Auth");
return {
auth
}
}

Then import the auth construct into another stack with use and attach the permissions.

stacks/ApiStack.ts
import { Api, StackContext } from "@serverless-stack/resources";
import { AuthStack } from "./AuthStack"

export function ApiStack({ stack }: StackContext) {
const { auth } = use(AuthStack)
const api = new Api(stack, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
},
});
auth.attachPermissionsForAuthUsers(stack, [api]);
}

Constructor

new Cognito(scope, id, props)

Parameters

CognitoProps

defaults.function?

Type : FunctionProps

The default function props to be applied to all the triggers in the UserPool. The environment, permissions and layers properties will be merged with per route definitions if they are defined.

new Cognito(stack, "Auth", {
defaults: {
function: {
timeout: 20,
environment: { topicName: topic.topicName },
permissions: [topic],
}
},
});

identityPoolFederation?

Type : boolean | CognitoIdentityPoolFederationProps

Default : Identity Pool created with the User Pool as the authentication provider

Configure the Cognito Identity Pool and its authentication providers.

login?

Type : Array<"email" | "phone" | "username" | "preferredUsername">

Default : ["username"]

Configure the different ways a user can sign in to our application for our User Pool. For example, you might want a user to be able to sign in with their email or username. Or with their phone number.

caution

You cannot change the login property once the User Pool has been created.

triggers?

Type : CognitoUserPoolTriggers

Default : No triggers

Configure triggers for this User Pool

new Cognito(stack, "Auth", {
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
});

cdk.id?

Type : string

Allows you to override default id for this construct.

cdk.userPool?

Type : UserPoolProps | IUserPool

This allows you to override the default settings this construct uses internally to create the User Pool.

cdk.userPoolClient?

Type : UserPoolClientOptions | IUserPoolClient

This allows you to override the default settings this construct uses internally to create the User Pool client.

Properties

An instance of Cognito has the following properties.

cognitoIdentityPoolId

Type : undefined | string

The id of the internally created IdentityPool instance.

id

Type : string

userPoolArn

Type : string

The ARN of the internally created Cognito User Pool.

userPoolClientId

Type : string

The id of the internally created Cognito User Pool client.

userPoolId

Type : string

The id of the internally created Cognito User Pool.

cdk.authRole

Type : Role

cdk.cfnIdentityPool?

Type : CfnIdentityPool

cdk.unauthRole

Type : Role

cdk.userPool

Type : IUserPool

cdk.userPoolClient

Type : IUserPoolClient

Methods

An instance of Cognito has the following methods.

attachPermissionsForAuthUsers

attachPermissionsForAuthUsers(scope, permissions)

Parameters

Attaches the given list of permissions to the authenticated users. This allows the authenticated users to access other AWS resources.

auth.attachPermissionsForAuthUsers(stack, ["s3"]);
caution

This function signature has been deprecated.

attachPermissionsForAuthUsers(permissions)

You are now required to pass in a scope as the first argument.

// Change
auth.attachPermissionsForAuthUsers(["s3"]);
// to
auth.attachPermissionsForAuthUsers(auth, ["s3"]);

attachPermissionsForTrigger

attachPermissionsForTrigger(triggerKey, permissions)

Parameters

attachPermissionsForTriggers

attachPermissionsForTriggers(permissions)

Parameters

attachPermissionsForUnauthUsers

attachPermissionsForUnauthUsers(scope, permissions)

Parameters

Attaches the given list of permissions to the authenticated users. This allows the authenticated users to access other AWS resources.

auth.attachPermissionsForUnauthUsers(stack, ["s3"]);
caution

This function signature has been deprecated.

attachPermissionsForUnauthUsers(permissions)

You are now required to pass in a scope as the first argument.

// Change
auth.attachPermissionsForUnauthUsers(["s3"]);
// to
auth.attachPermissionsForUnauthUsers(auth, ["s3"]);

bindForTrigger

bindForTrigger(triggerKey, constructs)

Parameters

  • triggerKey
  • constructs Array<SSTConstruct>

bindForTriggers

bindForTriggers(constructs)

Parameters

  • constructs Array<SSTConstruct>

getFunction

getFunction(triggerKey)

Parameters

  • triggerKey

CognitoAppleProps

servicesId

Type : string

CognitoAuth0Props

clientId

Type : string

domain

Type : string

CognitoAmazonProps

appId

Type : string

CognitoGoogleProps

clientId

Type : string

CognitoTwitterProps

consumerKey

Type : string

consumerSecret

Type : string

CognitoFacebookProps

appId

Type : string

CognitoUserPoolTriggers

createAuthChallenge?

Type : string | Function | FunctionProps

customEmailSender?

Type : string | Function | FunctionProps

customMessage?

Type : string | Function | FunctionProps

customSmsSender?

Type : string | Function | FunctionProps

defineAuthChallenge?

Type : string | Function | FunctionProps

postAuthentication?

Type : string | Function | FunctionProps

postConfirmation?

Type : string | Function | FunctionProps

preAuthentication?

Type : string | Function | FunctionProps

preSignUp?

Type : string | Function | FunctionProps

preTokenGeneration?

Type : string | Function | FunctionProps

userMigration?

Type : string | Function | FunctionProps

verifyAuthChallengeResponse?

Type : string | Function | FunctionProps

CognitoCdkCfnIdentityPoolProps

allowUnauthenticatedIdentities?

Type : boolean

CognitoIdentityPoolFederationProps

amazon?

Type : CognitoAmazonProps

apple?

Type : CognitoAppleProps

auth0?

Type : CognitoAuth0Props

facebook?

Type : CognitoFacebookProps

google?

Type : CognitoGoogleProps

twitter?

Type : CognitoTwitterProps

cdk.cfnIdentityPool?

Type : CognitoCdkCfnIdentityPoolProps