<div class="wp-block-smartcloud-ai-kit-feature"></div>

Architecture · Deep dive · Identity

Cognito Day‑2 Identity Architecture for WordPress

A deep dive into the CloudFormation-backed identity backbone behind Gatey: Cognito triggers, IAM roles, branded email, reCAPTCHA, token scopes and API authorization.

Architecture thesis: The useful architecture is not “add Cognito login to WordPress.” It is a repeatable Cognito subsystem that turns sign-up, SSO, token design, group assignment, email delivery and API authorization into deployable infrastructure.

The real Cognito problem is day‑2 architecture

Creating a Cognito User Pool is easy. Running it as the identity backbone of a WordPress-based platform is where the real work starts.

You need branded email delivery, bot-resistant sign-up, social and enterprise IdP linking, group-to-scope mapping, post-confirmation group assignment, optional IAM credentials, API Gateway authorization and a predictable way to repeat all of it across sites and environments.

That is the purpose of the Cognito day‑2 template: it packages the parts that usually become console checklists, Lambda snippets and tribal knowledge into a repeatable identity subsystem.

System boundary

 WordPress / Gutenberg page
        │
        ▼
 Gatey Authenticator block / shortcode / widget
        │ browser-side auth flow, no WordPress client secret
        ▼
 Amazon Cognito User Pool + App Client
        │
        ├── Pre Sign-Up Lambda
        │      reCAPTCHA validation, trusted domains, IdP linking
        │
        ├── Custom Email Sender Lambda
        │      S3 HTML templates, SES when configured, Cognito fallback
        │
        ├── Pre Token Generation Lambda
        │      Cognito groups → sc.group.<group> access-token scopes
        │
        └── Post Confirmation Lambda
               confirmed users → Registered group

 Optional Cognito Identity Pool
        │
        ├── AuthenticatedRole: minimal identity exchange
        └── RegisteredRole: execute-api permissions for confirmed users

WordPress is not the identity provider in this pattern. It renders the UI and stores non-sensitive configuration such as region, User Pool ID and App Client ID. Cognito owns authentication. Lambda triggers implement the day‑2 behavior. API Gateway and IAM consume the resulting tokens or credentials.

What the template provisions

Building blockWhy it existsKey design choiceOperational note
User Pool + App ClientPrimary user directory and OAuth client for browser-based WordPress loginNo client secret; code/SRP-friendly public-client setupCan be created by the stack or attached to an existing pool depending on template mode.
Optional custom domainBranded sign-in and OAuth callback flowsACM certificate and optional Route53 alias when the hosted zone is availableDNS and certificate ownership must be explicit before production rollout.
Identity PoolExchange authenticated Cognito users for AWS credentials when IAM-signed APIs are neededSeparate AuthenticatedRole from RegisteredRoleUseful for IAM-protected API Gateway calls from static frontends.
Custom Email SenderReplace plain Cognito emails with HTML templates and branded flowsTemplates live in S3; SES is used when configured, otherwise Cognito delivery can remain the fallbackTreat templates as versioned product assets, not inline console text.
Pre Sign-Up triggerValidate sign-up quality before users enter the poolOptional reCAPTCHA, trusted-domain behavior and external IdP linking by emailFailures should be clear enough for frontend UX and logged enough for debugging.
Pre Token Generation triggerProject group membership into access-token scopesAdd scopes such as sc.group.registered or sc.group.adminMakes API Gateway scope checks more declarative.
Post Confirmation triggerMove confirmed users into the Registered groupOnly handles real sign-up confirmations, not every confirmation eventDecouples “authenticated” from “registered enough to call APIs”.
OutputsLet other stacks and plugins consume identity artifactsExpose pool IDs, client IDs, domain, roles, groups and function ARNsOutputs are the contract between this stack and the rest of the platform.

The sign-up flow

Visitor opens a WordPress page
        │
        ▼
Gatey renders the Cognito sign-up UI
        │
        ├─ browser obtains reCAPTCHA token when enabled
        │
        ▼
Cognito SignUp request
        │
        ▼
Pre Sign-Up Lambda
        ├─ validate reCAPTCHA action and score
        ├─ evaluate trusted domains if configured
        └─ link external IdP identities by email when possible
        │
        ▼
Cognito creates the user and sends confirmation
        │
        ▼
Custom Email Sender Lambda
        ├─ load matching HTML template from S3
        ├─ interpolate attributes and confirmation code/link
        └─ send with SES or allow Cognito fallback
        │
        ▼
User confirms account
        │
        ▼
Post Confirmation Lambda adds user to Registered group

The important design detail is that bot filtering, email branding, account linking and group assignment are not WordPress plugin hooks. They happen inside Cognito and Lambda, where they remain valid whether the WordPress frontend is dynamic, statically exported or served behind CloudFront.

Token and authorization model

A common mistake is to treat login as the end of the identity story. For application features, the important question is what the authenticated user can call after login.

The day‑2 template supports a clean split: a user can be authenticated without automatically receiving every runtime permission. After confirmation, the Post Confirmation trigger places the user into the Registered group. The Pre Token Generation trigger can then add scopes based on group membership, such as sc.group.registered and sc.group.admin.

API Gateway methods can be protected with Cognito authorizers and scopes, while IAM-based patterns can use the Identity Pool role mapping. This keeps authorization at the API edge instead of burying it in WordPress templates or frontend visibility logic.

LayerArtifactWhat it provesWhat it should not do
Gatey/browserCognito tokens and local auth stateThe user completed the configured Cognito flowStore secrets on the WordPress server or proxy passwords through PHP.
User Pool groupsregistered, admin or project-specific groupsThe user belongs to a business roleBecome the only runtime enforcement point.
Access-token scopessc.group.The token carries API-readable role contextReplace backend authorization where resource ownership matters.
Identity Pool roleAuthenticatedRole or RegisteredRoleThe browser can obtain temporary AWS credentials for allowed actionsGrant broad account-level permissions.
API Gateway methodCognito scope or IAM authorizationThe route enforces identity at the service boundaryRely on hidden buttons or CSS-only restrictions.

Why the two-role IAM model matters

The Identity Pool part of the architecture is especially interesting because it separates two ideas that are often collapsed into one: “the user is signed in” and “the user may call protected AWS APIs.”

Step 1

AuthenticatedRole

This role represents the minimal state of being authenticated through the Identity Pool. It should be conservative and only support the credential exchange path needed by the application.

Step 2

RegisteredRole

This role is attached to confirmed users through the Registered group and can receive execute-api permissions for the current account’s API Gateway resources.

Result

Permission becomes intentional

The architecture avoids treating every signed-in user as an application user with full runtime access. That matters for portals, member areas and client-facing tools.

This split also gives future templates a clean contract: a backend stack can trust that “registered” users are not merely visitors with a token, but users who passed the confirmation and group-assignment path.

Custom email is infrastructure, not cosmetics

Cognito’s built-in email experience is acceptable for prototypes, but production portals usually need branded HTML emails, localized copy, custom callback links and a clear sender identity.

The template treats email as deployable infrastructure. Starter templates live in S3, the Lambda interpolates known attributes and verification codes, and SES can be used when the sender identity is verified. When SES is not configured, the design can fall back to Cognito’s built-in transport rather than blocking the whole identity rollout.

S3 templates

Versioned HTML assets

Sign-up, resend-code, forgot-password, admin-create, attribute verification, authentication and account-takeover templates can be managed as files.

SES sender

Production sender identity

The stack can use a verified email or domain identity for branded delivery when the customer owns SES setup.

Runtime fallback

Safer adoption path

When full SES delivery is not ready, Cognito delivery can keep the user journey moving while the stack remains deployable.

Security model

No password proxy

Browser talks to Cognito

The WordPress server does not need to receive passwords or become an authentication broker.

No client secret in WP

Public-client setup

The app client is designed for browser flows and avoids secrets that cannot be protected in static or frontend environments.

Trigger-scoped IAM

Least privilege Lambdas

Each trigger needs only the actions it performs: template reads, SES send, user linking or group assignment.

reCAPTCHA server validation

Bot checks outside WordPress

The token is collected in the browser but validated by the Pre Sign-Up Lambda before Cognito accepts the sign-up path.

Groups to scopes

Authorization-ready tokens

Group context becomes machine-readable for API Gateway without forcing every backend to call Cognito again.

Outputs as contract

Composable stacks

Other templates should consume stack outputs rather than duplicating identity resources manually.

Operational failure modes

Failure modeUser-visible symptomLikely causeRunbook direction
reCAPTCHA rejects sign-upUser cannot create an accountWrong site key/secret, stale token, low score or action mismatchCheck clientMetadata token path, SSM secret, score threshold and Lambda logs.
Custom email not deliveredNo confirmation/password email arrivesSES identity not verified, sandbox restriction, template read failure or FROM mismatchCheck SES identity, CloudWatch logs, S3 template key and fallback behavior.
Social login creates duplicate usersSame email appears under separate provider identitiesExternal IdP linking disabled or failedReview Pre Sign-Up logs and AdminLinkProviderForUser permissions.
API call denied after loginFrontend authenticates but protected API returns 401/403User not in Registered group, scopes missing, Identity Pool role not mapped or API authorizer misconfiguredInspect token scopes, group membership, Post Confirmation logs and API Gateway authorizer settings.
Custom domain failsHosted UI or callback domain does not resolveCertificate region/validation, Route53 zone mismatch or alias target issueValidate ACM cert, DNS zone ownership and Cognito domain status.

When this is a good fit

  • You want Cognito login in WordPress without turning WordPress into the authentication backend.
  • You need social or enterprise SSO, MFA, role-aware APIs or static-export-compatible login.
  • You want sign-up hardening with reCAPTCHA and consistent user linking across external identity providers.
  • You need branded, template-based Cognito emails that can be managed as deployment assets.
  • You plan to compose protected APIs, AI backend or workflow stacks around the same identity backbone.

When not to use this

  • The site only needs a simple WordPress login for wp-admin users and no frontend identity layer.
  • The team does not want Cognito, AWS IAM, DNS/certificate ownership or CloudFormation-managed identity resources.
  • All user management must remain in the WordPress users table because of existing plugin dependencies.
  • The project is a short-lived prototype where console-created Cognito resources are acceptable and no repeatability is needed.

Deep dive

WordPress on AWS Reference Architecture

pillar article that positions identity inside the wider WP Suite runtime split

Deep dive

Secure Static WordPress with Signed Cookies

how Cognito login can unlock protected static paths at CloudFront

Product

Gatey

Cognito login, registration, MFA, SSO and account blocks for WordPress

Guide

WordPress SSO with Amazon Cognito

social and enterprise SSO guide for Gatey and Cognito

Guide

Complete Guide to Amazon Cognito for WordPress

User Pool, App Client and Gatey setup basics

Implementation guide

Gatey Docs

configuration, blocks, APIs and static-export guidance

FAQ

Why call this “day‑2” Cognito?

Because the hard parts appear after the first User Pool exists: email templates, IdP linking, sign-up protection, group assignment, API authorization, IAM credentials, DNS, certificates and repeatable deployment.

Does Gatey store Cognito secrets in WordPress?

No. The architecture is built around browser-side Cognito flows and public-client configuration, so WordPress does not need to store a Cognito client secret or user tokens.

Why add group names as token scopes?

Scopes make group context directly usable by API Gateway authorizers. Instead of every API reloading Cognito group membership, the access token can carry scoped authorization hints.

Why separate AuthenticatedRole and RegisteredRole?

A signed-in visitor and a confirmed application user are not always the same thing. The split lets the architecture grant API permissions only after the post-confirmation group path has completed.

Can this attach to an existing User Pool?

The architecture is designed to support both newly created and existing Cognito resources, with optional triggers and outputs depending on the deployment parameters.

Is this only useful for static WordPress?

No. Dynamic WordPress sites benefit too. Static export simply makes the browser-side and AWS-native boundary more visible.

Turn Cognito login into an identity backbone

Use this architecture when WordPress needs real identity primitives: SSO, MFA, groups, API authorization, protected static paths and repeatable customer-owned AWS deployment.