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.
- JavaScript
- TypeScript
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,
});
}
}
import { App, Auth, Stack, StackProps } from "@serverless-stack/resources";
export class AuthStack extends Stack {
public readonly auth: Auth;
constructor(scope: App, id: string, props?: StackProps) {
super(scope, id, props);
this.auth = new Auth(this, "Auth", {
cognito: true,
});
}
}
Then pass the Auth to a different stack.
- JavaScript
- TypeScript
const authStack = new AuthStack(app, "auth");
new ApiStack(app, "api", { auth: authStack.auth });
const authStack = new AuthStack(app, "auth");
new ApiStack(app, "api", { auth: authStack.auth });
Finally, attach the permissions.
- JavaScript
- TypeScript
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]);
}
}
import { Api, App, Auth, Stack, StackProps } from "@serverless-stack/resources";
interface ApiStackProps extends StackProps {
readonly auth: Auth;
}
export class ApiStack extends Stack {
constructor(scope: App, id: string, props: ApiStackProps) {
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
- permissions
Permissions
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
- permissions
Permissions
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
- permissions
Permissions
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.
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,
}
}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,
}
}
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.