Authentication — AWS Cognito OIDC Provider
Authentication — AWS Cognito OIDC Provider
As of v0.1.7, myProp supports AWS Cognito as its primary OIDC identity provider alongside the existing SaaS Factory provider. The Cognito integration is opt-in — deployments that do not supply Cognito environment variables continue to work unchanged.
How It Works
myProp uses NextAuth.js for authentication. The src/lib/auth.ts module now owns the full NextAuth configuration and registers providers in priority order:
- AWS Cognito (primary) — active when
COGNITO_USER_POOL_ID,COGNITO_CLIENT_ID, andCOGNITO_CLIENT_SECRETare all set. - SaaS Factory OIDC (fallback) — active when its own env vars are set.
If neither provider is configured, NextAuth logs a warning at startup and no sign-in routes will succeed.
Environment Variables
Add the following variables to your deployment environment to enable Cognito:
| Variable | Required | Default | Description |
|---|---|---|---|
COGNITO_USER_POOL_ID | Yes | — | Your Cognito User Pool ID (e.g. eu-west-2_AbCdEfGhI) |
COGNITO_CLIENT_ID | Yes | — | The App Client ID associated with the portal |
COGNITO_CLIENT_SECRET | Yes | — | The App Client Secret for the App Client |
COGNITO_REGION | No | eu-west-2 | AWS region where the User Pool resides |
NEXT_PUBLIC_AUTH_COGNITO_ENABLED | No | — | Set to "true" to display the Cognito button on the sign-in page |
Note:
NEXT_PUBLIC_AUTH_COGNITO_ENABLEDis a build-time variable. If you change it, you must rebuild the application for the sign-in page to reflect the update.
Sign-In Page Behaviour
The sign-in page at /sign-in renders a single sign-in button whose appearance depends on NEXT_PUBLIC_AUTH_COGNITO_ENABLED:
- Cognito enabled (
NEXT_PUBLIC_AUTH_COGNITO_ENABLED=true): an orange "Sign in with Cognito" button is shown. Submitting the form POSTs to/api/auth/signin/cognito. - Cognito not enabled: a standard blue "Sign in" button is shown, which POSTs to
/api/auth/signin/saasfactory.
OIDC Discovery
The Cognito provider uses automatic OIDC discovery. The issuer URL is constructed from your region and User Pool ID:
https://cognito-idp.{COGNITO_REGION}.amazonaws.com/{COGNITO_USER_POOL_ID}
NextAuth fetches the .well-known/openid-configuration document from this URL at startup. No manual endpoint configuration is required.
The authorization request uses the openid profile email scope and the code response type (authorization code flow).
Claim Mapping
The following Cognito ID token claims are mapped to the NextAuth user profile:
| Cognito Claim | NextAuth Field | Notes |
|---|---|---|
sub | user.id | Stable unique identifier within the pool |
email | user.email | Required — sign-in is rejected if absent |
name | user.name | Falls back to cognito:username if not set |
picture | user.image | Optional profile picture URL |
sub | session.user.cognitoSub | Also persisted directly on the session |
email_verified | JWT token emailVerified | Accepts true (boolean), "true", or "True" |
Session Shape
When a user authenticates via Cognito, the NextAuth session includes an additional cognitoSub field:
const session = await getServerSession();
console.log(session.user.id); // NextAuth user ID (database row)
console.log(session.user.cognitoSub); // Cognito sub — stable pool identifier
console.log(session.user.email); // Verified email address
Use cognitoSub when making lookups against AWS services or external systems that reference the Cognito identity.
Account Linking
The Cognito provider has allowDangerousEmailAccountLinking enabled. If a user already has a portal account (created via the SaaS Factory provider or another mechanism) and their Cognito-verified email matches, the accounts are automatically linked on first Cognito sign-in. No duplicate accounts are created.
This is safe because Cognito enforces email verification within the User Pool before issuing tokens.
Email Validation
The signIn callback rejects any Cognito authentication where the user's profile does not contain an email address. This prevents account creation for Cognito users with phone-number-only identities. The rejection is logged via captureError for audit purposes.
Graceful Degradation
If any of the three required Cognito environment variables (COGNITO_USER_POOL_ID, COGNITO_CLIENT_ID, COGNITO_CLIENT_SECRET) is missing, the Cognito provider is silently skipped. The SaaS Factory provider remains active as the fallback. This means:
- Existing deployments without Cognito variables are not broken by upgrading to v0.1.7.
- You can enable Cognito incrementally by adding the environment variables to your deployment without a code change.
Architecture Notes
- The NextAuth API route handler (
src/app/api/auth/[...nextauth]/route.ts) and the middleware (src/middleware.ts) both import from@/lib/auth— no changes to those files are required. src/platform/auth/files are not modified. The product-levelsrc/lib/auth.tsnow owns the complete NextAuth config and delegates tosrc/platform/auth/providersfor the SaaS Factory provider list.- Sessions use the JWT strategy with a default maximum age of 30 days (configurable via
SESSION_MAX_AGE).