Skip to main content
Version: 3.18.0

Set Up SSO with Amazon Cognito

OpenID Connect (OIDC) adds an identity layer to OAuth 2.0, allowing applications to verify an end user's identity and obtain basic profile information from an identity provider (IdP). In a single sign-on (SSO) deployment, users authenticate through the IdP and can access connected applications without signing in separately to each one.

Amazon Cognito is a managed identity service from AWS. A Cognito user pool provides a user directory, an OIDC authorization server, and managed login pages. In this integration, Apache APISIX delegates browser authentication to Cognito before proxying requests to an upstream service.

The guide shows how to create a Cognito user pool and web app client, then configure APISIX for the OIDC Authorization Code flow with Proof Key for Code Exchange (PKCE). When a request does not have a valid APISIX session, APISIX redirects the browser to Cognito. After successful authentication, APISIX exchanges the authorization code for tokens, creates a browser session, and resumes the original request.

Prerequisite(s)

Configure Amazon Cognito

Create a user pool, a web app client, and a test user for the browser authentication flow.

Create a User Pool and Web App Client

Sign in to the AWS Management Console and open Amazon Cognito → User pools. Create the user directory and application:

  1. Select Create user pool.
  2. Select Traditional web application as the application type.
  3. Enter APISIX Authorization Code as the application name.
  4. Under Options for sign-in identifiers, select Email.
  5. Clear Enable self-registration unless users should be able to create their own accounts.
  6. Enter http://localhost:9080/anything/user/callback as the return URL.
  7. Select Create user directory.

Cognito creates the user pool, a confidential app client, a user pool domain, and managed login pages. The return URL identifies the APISIX endpoint where Cognito sends the browser after authentication. In production, use an HTTPS endpoint that users can reach and register that exact URL in Cognito.

On the new app client's Login pages tab, verify that Authorization code grant is the only OAuth grant type and that the allowed callback URL matches the APISIX callback.

Configure the Cognito Authorization Code app client for APISIX

Create a User

Create a user that can sign in through the managed login pages:

  1. In the user pool, select User management → Users → Create user.
  2. Keep Invitation message set to the option that does not send an invitation.
  3. Enter the user's email address and select Mark email address as verified.
  4. Set a temporary password that meets the user pool's password policy.
  5. Select Create user.

The user must replace the temporary password during the first sign-in.

Save the OIDC Configuration

On the user pool Overview page, record the User pool ID. Under Applications → App clients, open APISIX Authorization Code and record its Client ID and Client secret.

Save these values to environment variables, replacing the examples:

export COGNITO_REGION=ap-southeast-2
export COGNITO_USER_POOL_ID=ap-southeast-2_example
export COGNITO_SSO_CLIENT_ID=replace-with-your-client-id
export COGNITO_SSO_CLIENT_SECRET=replace-with-your-client-secret
export COGNITO_ISSUER="https://cognito-idp.${COGNITO_REGION}.amazonaws.com/${COGNITO_USER_POOL_ID}"
export COGNITO_DISCOVERY="${COGNITO_ISSUER}/.well-known/openid-configuration"

Keep the client secret confidential. Store production credentials in a secret manager and rotate them according to the organization's credential-rotation policy.

Configure APISIX

Configure a route that authenticates browser requests before forwarding them to httpbin.org, a public HTTP request and response service. The /anything/user/* endpoint returns request details for verification.

Generate a unique secret that APISIX will use to encrypt and authenticate the browser session cookie:

export APISIX_SESSION_SECRET="$(openssl rand -hex 32)"

Choose either the Admin API or ADC to configure the route.

Create the route through the Admin API:

curl "http://127.0.0.1:9180/apisix/admin/routes/cognito-sso" -X PUT \
--data-binary @- <<EOF
{
"uri": "/anything/user/*",
"plugins": {
"openid-connect": {
"client_id": "$COGNITO_SSO_CLIENT_ID",
"client_secret": "$COGNITO_SSO_CLIENT_SECRET",
"discovery": "$COGNITO_DISCOVERY",
"redirect_uri": "http://localhost:9080/anything/user/callback",
"bearer_only": false,
"use_pkce": true,
"scope": "openid email phone",
"session": {
"secret": "$APISIX_SESSION_SECRET"
},
"set_access_token_header": false,
"set_id_token_header": false,
"set_userinfo_header": false
},
"proxy-rewrite": {
"headers": {
"remove": ["Authorization", "Cookie"]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
EOF

discovery: URI of the Cognito user pool's OIDC discovery document.

redirect_uri: URI where Cognito returns the browser after authentication. It must match the callback URL configured for the app client.

bearer_only and use_pkce: Start browser authentication when no valid session exists and send an S256 PKCE challenge during authorization.

set_access_token_header, set_id_token_header, and set_userinfo_header: Set to false to prevent APISIX from adding tokens and user information to upstream request headers.

proxy-rewrite.headers.remove: Removes the original authorization header and the entire cookie header, including the APISIX session cookie, before proxying the request. Review this setting if the upstream application requires cookies.

Verify Authentication

Navigate to http://localhost:9080/anything/user/get in a browser. APISIX redirects you to the Cognito managed login pages.

Sign in with the Cognito user. If this is the user's first sign-in, replace the temporary password when prompted. If the APISIX authorization session expires before sign-in is complete, navigate to the protected URL again to start a new authentication flow. For more information, see No Session State Found.

Cognito then returns the browser to APISIX, and APISIX forwards the request to httpbin.org. The response should contain fields similar to these:

{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-CA,en-US;q=0.9,en;q=0.8",
"Host": "localhost",
"Priority": "u=0, i",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15",
"X-Amzn-Trace-Id": "Root=1-...",
"X-Forwarded-Host": "localhost:9080"
},
"json": null,
"method": "GET",
"origin": "192.168.155.1, xxx.xxx.xxx.xxx",
"url": "http://localhost:9080/anything/user/get"
}

Header values and the reported origin address vary by browser and network environment.

The upstream request headers should not include the APISIX session cookie, access token, ID token, or user-information header. Reload the page to verify that APISIX reuses the browser session without redirecting you to Cognito.

Next Steps

You have now configured APISIX to authenticate browser requests with Amazon Cognito. To authorize requests from services without an end-user session, see Authorize M2M Requests with Amazon Cognito. See the openid-connect plugin reference for more configuration options.