Skip to main content

Auth

caution

This is the SST v0.x Constructs doc. SST v1 is now released. If you are using v1, see the v1 Constructs doc. If you are looking to upgrade to v1, check out the migration 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.

Initializer

new Auth(scope: Construct, id: string, props: AuthProps)

Parameters

Examples

Allowing users to sign in using User Pool

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

new Auth(this, "Auth", {
cognito: true,
});

Allowing users to sign in with their email or phone number

new Auth(this, "Auth", {
cognito: {
userPool: {
signInAliases: { email: true, phone: true },
},
},
});

Configuring User Pool triggers

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

Adding triggers

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

Specifying function props for all the triggers

new Auth(this, "Auth", {
cognito: {
defaultFunctionProps: {
timeout: 20,
environment: { tableName: table.tableName },
permissions: [table],
},
triggers: {
preAuthentication: "src/preAuthentication.main",
postAuthentication: "src/postAuthentication.main",
},
},
});

Using the full config for a trigger

If you wanted to configure each Lambda function separately, you can pass in the FunctionProps.

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

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

new Auth(this, "Auth", {
cognito: {
defaultFunctionProps: {
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 defaultFunctionProps. 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(this, "Auth", {
cognito: {
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(this, "Auth", {
cognito: {
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.

Allowing Twitter auth and a User Pool

new Auth(this, "Auth", {
cognito: true,
twitter: {
consumerKey: "gyMbPOiwefr6x63SjIW8NN2d9",
consumerSecret: "qxld1zic5c2eyahqK3gjGLGQaOTogGfAgGh17MYOIcOUR9l2Nz",
},
});

Adding all the supported social logins

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

Allowing users to login using Auth0

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

Attaching permissions for authenticated users

import * as iam from "aws-cdk-lib/aws-iam";

const auth = new Auth(this, "Auth", {
cognito: {
userPool: { signInAliases: { email: true } },
},
});

auth.attachPermissionsForAuthUsers([
api,
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["s3:*"],
resources: ["*"],
}),
]);

Aside from IAM policy statements, you can pass in certain other SST constructs.

Attaching permissions for unauthenticated users

import * as iam from "aws-cdk-lib/aws-iam";

const auth = new Auth(this, "Auth", {
cognito: {
userPool: { signInAliases: { email: true } },
},
});

auth.attachPermissionsForUnauthUsers([
api,
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ["s3:*"],
resources: ["*"],
}),
]);

Similar to the example above. Aside from IAM policy statements, you can pass in certain other SST constructs.

Sharing Auth across stacks

You can create the Auth construct in one stack, and attach permissions in other stacks. To do this, expose the Auth as a class property.

stacks/AuthStack.js
import { Auth, Stack } from "@serverless-stack/resources";

export class AuthStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);

this.auth = new Auth(this, "Auth", {
cognito: true,
});
}
}

Then pass the Auth to a different stack.

stacks/index.js
const authStack = new AuthStack(app, "auth");

new ApiStack(app, "api", { auth: authStack.auth });

Finally, attach the permissions.

stacks/ApiStack.js
import { Api, Stack } from "@serverless-stack/resources";

export class ApiStack extends Stack {
constructor(scope, id, props) {
super(scope, id, props);

const api = new Api(this, "Api", {
routes: {
"GET /notes": "src/list.main",
"POST /notes": "src/create.main",
},
});
props.auth.attachPermissionsForAuthUsers([api]);
}
}

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

Upgrading to v0.12.0

The v0.12.0 release of the Auth construct includes a small breaking change. You might be impacted by this change if:

  • You are currently using any version < v0.12.0
  • And using Cognito as the authentication provider

Using signInAliases

If you are configuring the signInAliases like so:

new Auth(this, "Auth", {
cognito: {
signInAliases: { email: true, phone: true },
},
});

Change it to:

new Auth(this, "Auth", {
cognito: {
userPool: {
signInAliases: { email: true, phone: true },
},
},
});

Note the userPool prop is expected as a part of the cognito prop.

Using cognitoUserPool and cognitoUserPoolClient

If you are creating the UserPool and the UserPoolClient manually like this:

import * as cognito from "aws-cdk-lib/aws-cognito";

const userPool = new cognito.UserPool(this, "UserPool", {
userPoolName: "my-user-pool",
signInAliases: { email: true, phone: true },
});
const userPoolClient = new cognito.UserPoolClient(this, "UserPoolClient", {
userPool,
disableOAuth: true,
});

new Auth(this, "Auth", {
cognitoUserPool: userPool,
cognitoUserPoolClient: userPoolClient,
});

Change it to:

import * as cognito from "aws-cdk-lib/aws-cognito";

const userPool = new cognito.UserPool(this, "UserPool", {
userPoolName: "my-user-pool",
signInAliases: { email: true, phone: true },
});
const userPoolClient = new cognito.UserPoolClient(this, "UserPoolClient", {
userPool,
disableOAuth: true,
});

new Auth(this, "Auth", {
cognito: {
userPool,
userPoolClient,
},
});

Read more about the AuthCognitoProps below.

Properties

An instance of Auth contains the following properties.

cognitoIdentityPoolId

Type : string

The ID of the Cognito Identity Pool.

cognitoCfnIdentityPool

Type : cdk.aws-cognito.CfnIdentityPool

The internally created CDK CfnIdentityPool instance.

cognitoUserPool?

Type : cdk.aws-cognito.IUserPool

The internally created CDK UserPool instance. Not available if only social logins are used.

cognitoUserPoolClient?

Type : cdk.aws-cognito.IUserPoolClient

The internally created CDK UserPoolClient instance. Not available if only social logins are used.

iamAuthRole

Type : cdk.aws-iam.Role

The internally created CDK IAM Role instance for the authenticated users of the Identity Pool.

iamUnauthRole

Type : cdk.aws-iam.Role

The internally created CDK IAM Role instance for the unauthenticated users of the Identity Pool.

Methods

An instance of Auth contains the following methods.

attachPermissionsForAuthUsers

attachPermissionsForAuthUsers(permissions: Permissions)

Parameters

Attaches the given list of permissions to IAM role used for authenticated users. This dictates which resources an authenticated user has access to.

Follows the same format as Function.attachPermissions.

attachPermissionsForUnauthUsers

attachPermissionsForUnauthUsers(permissions: Permissions)

Parameters

Attaches the given list of permissions to IAM role used for unauthenticated users. This dictates which resources an unauthenticated user has access to.

Follows the same format as Function.attachPermissions.

attachPermissionsForTriggers

attachPermissions(permissions: Permissions)

Parameters

Attaches the given list of permissions to all the triggers in the User Pool. This allows the functions to access other AWS resources.

Internally calls Function.attachPermissions.

attachPermissionsForTrigger

attachPermissionsToTarget(triggerKey: keyof AuthUserPoolTriggers, permissions: Permissions)

Parameters

  • triggerKey keyof AuthUserPoolTriggers

  • permissions Permissions

Attaches the given list of permissions to a specific trigger in the User Pool. This allows that function to access other AWS resources.

Internally calls Function.attachPermissions.

AuthProps

cognito?

Type : AuthCognitoProps

The props that'll be used to configure a Cognito User Pool.

apple?

Type : AuthAppleProps

The props necessary to configure Apple as an authentication provider for the Identity Pool.

auth0?

Type : AuthAuth0Props

The props necessary to configure Auth0 as an authentication provider for the Identity Pool.

google?

Type : AuthGoogleProps

The props necessary to configure Google as an authentication provider for the Identity Pool.

facebook?

Type : AuthFacebookProps

The props necessary to configure Facebook as an authentication provider for the Identity Pool.

twitter?

Type : AuthTwitterProps

The props necessary to configure Twitter as an authentication provider for the Identity Pool.

amazon?

Type : AuthAmazonProps

The props necessary to configure Amazon as an authentication provider for the Identity Pool.

identityPool?

Type : AuthCdkCfnIdentityPoolProps

The props that'll be used to configure the Cognito Identity Pool.

AuthCognitoProps

userPool?

Type : cdk.aws-cognito.UserPoolProps | cdk.aws-cognito.IUserPool

Optionally, pass in an instance of the CDK cdk.aws-cognito.UserPoolProps or cdk.aws-cognito.IUserPool. This will override the default settings this construct uses to create the CDK UserPool internally.

caution

You cannot change some of the User Pool properties once the it has been created.

For example, SignInAliases cannot be changed after the User Pool has been created.

The different aliases a user can use to 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 userPool prop to:

    {
    signInAliases: {
    username: true,
    email: true,
    phone: true,
    preferredUsername: true,
    }
    }

    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 userPool prop to:

    {
    signInAliases: {
    email: true,
    phone: true,
    }
    }

    Read more on this over on the AWS docs.

userPoolClient?

Type : cdk.aws-cognito.UserPoolClientOptions | cdk.aws-cognito.IUserPoolClient

Optionally, pass in an instance of the CDK cdk.aws-cognito.UserPoolClientOptions or cdk.aws-cognito.IUserPoolClient. This will override the default settings this construct uses to create the CDK UserPoolClient internally.

triggers?

Type : AuthUserPoolTriggers, defaults to undefined

The triggers for the User Pool. Takes an associative array, where the key is the trigger type and the value is a FunctionDefinition.

defaultFunctionProps?

Type : FunctionProps, defaults to {}

The default function props to be applied to all the Lambda functions for the triggers. These default values are overridden by the function props for each trigger. Except for the environment, the layers, and the permissions properties, it will be merged.

AuthAuth0Props

domain

Type : string

The Domain for your Auth0 app.

clientId

Type : string

The Client ID for your Auth0 app.

AuthAppleProps

servicesId

Type : string

The Services id of your Apple app.

AuthGoogleProps

clientId

Type : string

The client id of your Google app.

AuthFacebookProps

appId

Type : string

The id of your Facebook app.

AuthTwitterProps

consumerKey

Type : string

The Consumer key for your Twitter app.

consumerSecret

Type : string

The Consumer secret key for your Twitter app.

AuthAmazonProps

appId

Type : string

The id of your Amazon app.

AuthUserPoolTriggers

The following User Pool triggers can be connected to Lambda functions in your app. Read more about this over on the AWS docs.

createAuthChallenge?

Type: FunctionDefinition

Creates a challenge in a custom auth flow.

customMessage?

Type: FunctionDefinition

Customize the message that is sent to a user.

defineAuthChallenge?

Type: FunctionDefinition

Determine the next challenge in a custom auth flow.

postAuthentication?

Type: FunctionDefinition

Triggered after a user is authenticated.

postConfirmation?

Type: FunctionDefinition

Triggered after a user has been confirmed.

preAuthentication?

Type: FunctionDefinition

Custom validation to accept or deny the sign-in request.

preSignUp?

Type: FunctionDefinition

Custom validation to accept or deny the sign-up request.

preTokenGeneration?

Type: FunctionDefinition

Add or remove attributes in Id tokens.

userMigration?

Type: FunctionDefinition

Migrate a user from an existing user directory to User Pools.

verifyAuthChallengeResponse?

Type: FunctionDefinition

Determines if a response is correct in a custom auth flow.

AuthCdkCfnIdentityPoolProps

AuthCdkCfnIdentityPoolProps extends cdk.aws-cognito.CfnIdentityPoolProps with the exception that the allowUnauthenticatedIdentities fields is optional, and defaults to true.

You can use AuthCdkCfnIdentityPoolProps to configure the other Identity Pool properties.