Cognito App Client Module
This module creates and configures an AWS Cognito User Pool App Client with OAuth 2.0/OIDC support, automatic credential storage in SSM Parameter Store, and optional UI customization.
Client Types
This module supports two types of Cognito app clients:
- Confidential clients (default): Used for server-side applications that can securely store client secrets. These clients have
generate_secret = true. - Public clients: Used for Single Page Applications (SPAs), mobile apps, and other public clients that cannot securely store secrets. These clients have
generate_secret = false.
Public clients should use the Authorization Code flow with PKCE (Proof Key for Code Exchange) for secure authentication without a client secret.
Features
- OAuth 2.0/OIDC app client with configurable flows and scopes
- Automatic storage of client credentials in AWS SSM Parameter Store
- Token validity configuration (access, ID, and refresh tokens)
- Support for multiple identity providers (Cognito, Entra, Google)
- UI customization with custom logo support (legacy hosted UI)
- Managed Login branding for modern login pages (requires ESSENTIALS or PLUS tier)
Usage
Basic Example
module "cognito_app" {
source = "./modules/cognito_app"
create = true
client_app_name = "my-web-app"
cognito_user_pool_id = module.cognito_pool.aws_cognito_pool_id
client_id_ssm_parameter = "/myapp/cognito/client_id"
client_secret_ssm_parameter = "/myapp/cognito/client_secret"
callback_urls = ["https://app.example.com/oauth/openid/callback"]
explicit_auth_flows = ["ALLOW_REFRESH_TOKEN_AUTH"]
allowed_oauth_flows = ["code"]
allowed_oauth_scopes = ["openid", "email", "profile"]
supported_identity_providers = ["COGNITO"]
}
SPA/Public Client Example
Use this configuration for Single Page Applications that cannot securely store client secrets:
module "cognito_spa" {
source = "./modules/cognito_app"
create = true
client_app_name = "my-spa-app"
cognito_user_pool_id = module.cognito_pool.aws_cognito_pool_id
generate_secret = false # No secret for SPA clients
client_id_ssm_parameter = "/myspa/cognito/client_id"
# Note: client_secret_ssm_parameter is not needed for public clients
callback_urls = [
"https://app.example.com/callback",
"http://localhost:3000/callback" # For local development
]
# SPA-appropriate auth flows
explicit_auth_flows = ["ALLOW_USER_SRP_AUTH", "ALLOW_REFRESH_TOKEN_AUTH"]
allowed_oauth_flows = ["code"] # Authorization code with PKCE
allowed_oauth_scopes = ["openid", "email", "profile"]
supported_identity_providers = ["COGNITO"]
}
Recommended SPA Configuration:
| Setting | Recommendation | Reason |
|---|---|---|
generate_secret |
false |
SPAs cannot securely store secrets |
allowed_oauth_flows |
["code"] |
Authorization code flow with PKCE is the most secure option for SPAs |
explicit_auth_flows |
["ALLOW_USER_SRP_AUTH", "ALLOW_REFRESH_TOKEN_AUTH"] |
SRP for sign-in, refresh tokens for session management |
callback_urls |
Include HTTPS production URLs and localhost for development | SPAs often run locally during development |
With Multiple Identity Providers
module "cognito_app" {
source = "./modules/cognito_app"
create = true
client_app_name = "enterprise-app"
cognito_user_pool_id = module.cognito_pool.aws_cognito_pool_id
client_id_ssm_parameter = "/myapp/cognito/client_id"
client_secret_ssm_parameter = "/myapp/cognito/client_secret"
callback_urls = [
"https://app.example.com/oauth/openid/callback",
"http://localhost:8000/callback" # For local development
]
explicit_auth_flows = ["ALLOW_REFRESH_TOKEN_AUTH"]
allowed_oauth_flows = ["code"]
allowed_oauth_scopes = ["openid", "email", "profile"]
supported_identity_providers = ["COGNITO", "Google", "Entra"]
}
With Managed Login Branding (Default Theme)
module "cognito_app" {
source = "./modules/cognito_app"
create = true
client_app_name = "branded-app"
cognito_user_pool_id = module.cognito_pool.aws_cognito_pool_id
client_id_ssm_parameter = "/myapp/cognito/client_id"
client_secret_ssm_parameter = "/myapp/cognito/client_secret"
callback_urls = ["https://app.example.com/oauth/openid/callback"]
explicit_auth_flows = ["ALLOW_REFRESH_TOKEN_AUTH"]
allowed_oauth_flows = ["code"]
allowed_oauth_scopes = ["openid", "email", "profile"]
supported_identity_providers = ["COGNITO"]
# Use Cognito's default branding
managed_login_branding = {
use_defaults = true
}
}
With Custom Branding (Colors and Logo)
locals {
branding_settings = {
categories = {
global = {
colorSchemeMode = "DYNAMIC" # Supports light/dark mode
}
}
components = {
form = {
logo = {
enabled = true
formInclusion = "IN"
location = "CENTER"
position = "TOP"
}
}
primaryButton = {
lightMode = {
defaults = {
backgroundColor = "4f069aff" # Purple
textColor = "ffffffff" # White
}
hover = {
backgroundColor = "3d0578ff"
textColor = "ffffffff"
}
}
darkMode = {
defaults = {
backgroundColor = "7b2fc9ff"
textColor = "ffffffff"
}
hover = {
backgroundColor = "9b4fe9ff"
textColor = "ffffffff"
}
}
}
}
}
}
module "cognito_app" {
source = "./modules/cognito_app"
create = true
client_app_name = "custom-branded-app"
cognito_user_pool_id = module.cognito_pool.aws_cognito_pool_id
client_id_ssm_parameter = "/myapp/cognito/client_id"
client_secret_ssm_parameter = "/myapp/cognito/client_secret"
callback_urls = ["https://app.example.com/oauth/openid/callback"]
explicit_auth_flows = ["ALLOW_REFRESH_TOKEN_AUTH"]
allowed_oauth_flows = ["code"]
allowed_oauth_scopes = ["openid", "email", "profile"]
supported_identity_providers = ["COGNITO", "Google", "Entra"]
managed_login_branding = {
use_defaults = false
settings = jsonencode(local.branding_settings)
assets = [
{
bytes = filebase64("${path.module}/assets/logo_for_white.png")
category = "FORM_LOGO"
color_mode = "LIGHT"
extension = "PNG"
},
{
bytes = filebase64("${path.module}/assets/logo_for_dark.png")
category = "FORM_LOGO"
color_mode = "DARK"
extension = "PNG"
},
{
bytes = filebase64("${path.module}/assets/background_for_light.png")
category = "PAGE_BACKGROUND"
color_mode = "LIGHT"
extension = "PNG"
}
]
}
}
Token Validity
The module configures the following default token validity periods:
| Token Type | Validity | Unit |
|---|---|---|
| Access Token | 2 | hours |
| ID Token | 2 | hours |
| Refresh Token | 30 | days |
SSM Parameters
Client credentials are automatically stored in SSM Parameter Store:
| Parameter Path | Description |
|---|---|
var.client_id_ssm_parameter |
App client ID |
var.client_secret_ssm_parameter |
App client secret (only created when generate_secret = true) |
UI Customization with Managed Login Branding
For the modern managed login experience (requires ESSENTIALS or PLUS user pool tier):
use_defaults: Use Cognito's default branding (mutually exclusive withsettings)settings: Custom JSON settings for branding configurationassets: List of custom assets (logos, backgrounds) with base64-encoded content
Asset Categories
| Category | Description |
|---|---|
FORM_LOGO |
Logo displayed on the login form |
PAGE_BACKGROUND |
Background image for the login page |
Color Modes
| Mode | Description |
|---|---|
LIGHT |
Asset used when light mode is active |
DARK |
Asset used when dark mode is active |
Supported Extensions
| Extension | Format |
|---|---|
PNG |
PNG |
JPEG |
JPEG |
SVG |
SVG |
Inputs
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| allowed_oauth_flows | allowed oauth scopes: code, implicit, and client_credentials | list(string) |
n/a | yes |
| allowed_oauth_scopes | allowed oauth scopes: code, implicit, and client_credentials | list(string) |
n/a | yes |
| callback_urls | List of callback URLs for the Cognito App Client | list(string) |
n/a | yes |
| client_app_name | Name of the Cognito App Client | string |
n/a | yes |
| client_id_ssm_parameter | SSM parameter path to store the Cognito App Client ID | string |
n/a | yes |
| client_secret_ssm_parameter | SSM parameter path to store the Cognito App Client secret. Only used when generate_secret is true. | string |
null |
no |
| cognito_user_pool_id | ID of the Cognito User Pool to which this App Client belongs | string |
n/a | yes |
| create | Whether to create the Cognito App Client | bool |
n/a | yes |
| explicit_auth_flows | List of explicit authentication flows for the Cognito App Client | list(string) |
n/a | yes |
| generate_secret | Whether to generate a client secret. Set to false for SPA/public clients that cannot securely store secrets. | bool |
true |
no |
| managed_login_branding | Managed login page branding configuration. Requires ESSENTIALS or PLUS user pool tier. | object({ |
null |
no |
| supported_identity_providers | List of supported identity providers for the Cognito App Client | list(string) |
n/a | yes |
Outputs
| Name | Description |
|---|---|
| client_id | OPENID client |
| client_secret | OPENID secret (empty string if generate_secret is false) |