Skip to main content

Auth

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 { Auth } from "@serverless-stack/resources";

new Auth(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 Auth(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 Auth(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 Auth(stack, "Auth", {
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
});

Specifying function props for all the triggers

new Auth(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 Auth(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 Auth(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 Auth(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 Auth(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 Auth(stack, "Auth", {
identityPoolFederation: {
auth0: {
domain: "https://myorg.us.auth0.com",
clientId: "UsGRQJJz5sDfPQDs6bhQ9Oc3hNISuVif",
},
},
});

Enabling federation with Twitter

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

Enabling federation with multiple social logins

new Auth(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 Auth(stack, "Auth");

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

Attaching permissions for unauthenticated federation identity

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

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

Advanced examples

Configuring attributes

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

new Auth(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 Auth(stack, "Auth", {
cdk: {
userPool: UserPool.fromUserPoolId(stack, "IUserPool", "pool-id"),
userPoolClient: UserPoolClient.fromUserPoolClientId(stack, "IUserPoolClient", "pool-client-id"),
},
});

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 { Auth, StackContext } from "@serverless-stack/resources";

export function AuthStack({ stack }: StackContext) {
const auth = new Auth(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 Auth(scope, id, props)

Parameters

AuthProps

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 Auth(stack, "Auth", {
defaults: {
function: {
timeout: 20,
environment: { topicName: topic.topicName },
permissions: [topic],
}
},
});

identityPoolFederation?

Type : boolean | AuthCognitoIdentityPoolFederationProps

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 : AuthUserPoolTriggers

Default : No triggers

Configure triggers for this User Pool

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

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 Auth has the following properties.

cognitoIdentityPoolId

Type : undefined | string

The id of the internally created IdentityPool instance.

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 Auth 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"]);

getFunction

getFunction(triggerKey)

Parameters

  • triggerKey

AuthAppleProps

servicesId

Type : string

AuthAuth0Props

clientId

Type : string

domain

Type : string

AuthAmazonProps

appId

Type : string

AuthGoogleProps

clientId

Type : string

AuthTwitterProps

consumerKey

Type : string

consumerSecret

Type : string

AuthFacebookProps

appId

Type : string

AuthUserPoolTriggers

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

AuthCdkCfnIdentityPoolProps

allowUnauthenticatedIdentities?

Type : boolean

AuthCognitoIdentityPoolFederationProps

amazon?

Type : AuthAmazonProps

apple?

Type : AuthAppleProps

auth0?

Type : AuthAuth0Props

facebook?

Type : AuthFacebookProps

google?

Type : AuthGoogleProps

twitter?

Type : AuthTwitterProps

cdk.cfnIdentityPool?

Type : AuthCdkCfnIdentityPoolProps