User authentication
Human users authenticate with stateless JWTs issued by Amazon Cognito. After sign-in or registration, clients store tokens locally and send them on each API request. There is no server-side session store — any service instance can validate tokens independently, which supports horizontal scaling behind CloudFront and load balancers.
This guide is for architecture review, procurement, and security diligence. Technical decisions are recorded in ADR-0011 and ADR-0004.
What problem this solves
Session-based authentication ties users to specific server instances or shared session clusters. That complicates ECS scaling, increases operational overhead, and creates affinity assumptions at the load balancer.
Backbone’s model:
- Cognito is the identity provider (user pools, password policies, token issuance).
- Clients hold tokens — browsers use local storage; mobile clients use platform secure storage.
- Services validate on every request — no sticky sessions required.
What's in place
| Capability | Description |
|---|---|
| Email/password login | First-party UI; server-side authentication against Cognito (no redirect to Cognito hosted pages) |
| Self-service registration | Creates Cognito user and actor profile in one flow |
| LinkedIn sign-in | OAuth2 with short-lived temporary token handoff to the browser |
| Token refresh | Long-lived sessions without re-entering credentials on every visit |
| Browser entry point | CloudFront → backend-for-frontend (BFF) → domain services |
Request path (deployed environments)
Browser → CloudFront (apex hostname)
→ Internet-facing ALB (API paths only)
→ actor-bff
→ auth-service / actor-service / document-service
Static UI assets are served from S3 via CloudFront. API paths (/auth/*, /actors/*, /documents/*, etc.) forward to the application load balancer with origin verification. See Platform security posture and Infrastructure.
Typical user-facing operations:
| User action | Entry path |
|---|---|
| Sign in | POST /auth/login |
| Register | POST /auth/register |
| Refresh session | POST /auth/refresh-user-token |
| LinkedIn sign-in | Redirect flow via /auth/linkedin/login, then token exchange |
| Profile / documents | Authenticated calls through the BFF |
Authentication flows
Email and password (primary)
Browser → BFF → auth-service → Cognito
← JWTs (access, id, refresh) ←
Client stores tokens; subsequent calls use Authorization: Bearer
This keeps branding and UX in your product while Cognito still issues standard OIDC-shaped JWTs.
LinkedIn OAuth2
- User starts LinkedIn sign-in from the product UI.
- After LinkedIn callback, auth-service issues a temporary, single-use token to the browser (not a long-lived JWT in the URL).
- Browser exchanges the temporary token for Cognito JWTs via a dedicated endpoint.
Temporary tokens expire quickly and are invalidated on first use — reducing exposure in redirect URLs.
Registration
Browser → BFF → auth-service → Cognito (create user)
→ actor-service (create profile)
→ notification-service (welcome email, queued)
← JWTs ←
Registration is a multi-step backend orchestration.
Security principles
These apply to human identity specifically. Platform-wide edge and network assumptions are in Platform security posture.
- Verify explicitly — Protected APIs require a valid user JWT; anonymous access is denied by default on secured routes.
- Least privilege — Authentication proves identity; authorization rules apply at the resource layer.
- Assume breach — Tokens are short-lived and refreshable; a compromised user token does not grant service-to-service identity (see Service authentication).
- No network trust — Source IP and VPC location are not treated as proof of user identity.
User JWT validation results are cached in Redis across ECS tasks for performance; see Application caching and distributed scale.
Operator expectations
| Topic | Expectation |
|---|---|
| Identity provider | Cognito user pool per environment; password policy configured in CDK |
| Social login | LinkedIn developer app credentials supplied as deployment secrets |
| Token storage | Browser clients responsible for secure storage; XSS remains an application concern |
| Future enhancements | MFA, passkeys, and centralized revocation are roadmap items, not baseline |
Further reading
- Service authentication — workload identity (separate trust domain)
- ADR-0011: Stateless JWT authentication
- Amazon Cognito user pool security best practices — AWS Documentation
Updated 2 days ago
