Authentication & Security
All requests to the Aptia One Public Partner API must be authenticated via OAuth 2.0 Client Credentials Grant using tokens issued by AWS Cognito User Pools.
1. Token Exchange Architecture
Partners do not share database credentials or session cookies. Instead, machine clients exchange their client_id and client_secret for signed JSON Web Tokens (JWTs) via the AWS Cognito OAuth token endpoint:
[Partner Client]
│
│ 1. POST /oauth2/token (client_credentials)
▼
[AWS Cognito Auth]
│
│ 2. Signed JWT (expires in 3600s)
▼
[Partner Client]
│
│ 3. API Request with Authorization: Bearer <JWT>
▼
[API Gateway & Facade] ──► Validates JWT & Enforces Tenant Isolation
2. Acquiring an Access Token
Token Endpoint URLs
- Production:
https://auth-api-development-us-east-1.auth.us-east-1.amazoncognito.com/oauth2/token - Sandbox:
https://auth-api-development-us-east-1.auth.us-east-1.amazoncognito.com/oauth2/token
(Cognito domain format: https://<cognito-domain-prefix>.auth.<region>.amazoncognito.com/oauth2/token derived from aws_cognito_user_pool_domain)
Request Example
curl -X POST https://auth-api-development-us-east-1.auth.us-east-1.amazoncognito.com/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=aptia/participants.read aptia/enrollments.read aptia/payroll.read"
3. Scopes & Permissions Matrix
Aptia One enforces role-based access control (RBAC) via OAuth scopes provisioned in AWS Cognito. Your client credentials must be granted the appropriate scopes for the resources you access:
| Endpoint | Verb | Required Scope | Description |
|---|---|---|---|
/v1/participants | GET | aptia/participants.read | Query census participants |
/v1/participants | POST | aptia/participants.write | Ingest new participant |
/v1/participants/{id} | GET | aptia/participants.read | Retrieve participant details |
/v1/participants/{id} | PATCH | aptia/participants.write | Update demographic fields |
/v1/participants/{id}/dependents | GET | aptia/participants.read | List participant dependents |
/v1/participants/{id}/dependents | POST | aptia/participants.write | Add dependent association |
/v1/participants/{id}/enrollments | GET | aptia/enrollments.read | View active plan elections |
/v1/participants/{id}/enrollment-events | POST | aptia/enrollments.write | Initiate qualified event |
/v1/participants/{id}/enrollment-events/{eventId}/elections | POST | aptia/enrollments.write | Elect benefit choices |
/v1/participants/{id}/payroll-deductions | GET | aptia/payroll.read | Extract calculated deductions |
/v1/tenants/{tenantId}/payroll-schedules | GET | aptia/payroll.read | Retrieve deduction calendar |
4. Tenant Isolation & Security Boundaries
To safeguard sensitive census and benefits data across plan sponsors, Aptia One enforces strict zero-trust tenant isolation. Tenancy is governed entirely by server-side partner configuration registered in the platform (stored in AWS Secrets Manager and resolved by the edge facade), rather than custom claims inside the client JWT:
Single-Tenant Plan Sponsors
Single-tenant employer partners are bound directly to their designated plan sponsor tenant via server-side partner configuration:
- Standard Cognito client credentials tokens contain standard claims (
sub,client_id,token_use,scope). - Upon authenticating the JWT, the API facade matches the
client_idagainst platform partner configuration to determine the bound tenant UUID. - The API facade automatically scopes all queries and commands to this bound tenant.
- Attempting to access resources belonging to a different tenant produces an immediate
403 Forbidden.
Multi-Tenant Carrier Partners
Carriers managing multiple employer plans are configured server-side with an authorized tenant whitelist:
- The partner passes the target tenant in the request header:
X-Aptia-Tenant-Id: <tenantId-or-clientOnecode> - The API facade verifies that the requested tenant exists in the carrier's server-side authorized whitelist (
authorizedTenants). - If the carrier attempts to query a tenant outside their authorized scope, the request is rejected immediately with
403 Forbidden.
Friendly Tenant Codes
Both UUIDs (11111111-1111-1111-1111-111111111111) and human-readable plan sponsor codes (clientOnecode, e.g. LINDT_US or ACME_CORP) are supported in the X-Aptia-Tenant-Id header. The API facade transparently resolves friendly codes to tenant UUIDs in real time.
5. Authentication Errors (RFC 7807)
Missing or Expired Token (401 Unauthorized)
{
"type": "https://developer.aptiaone.com/errors/unauthorized",
"title": "Unauthorized",
"status": 401,
"detail": "OAuth 2.0 access token has expired or is invalid.",
"instance": "/v1/participants"
}
Insufficient Scope or Cross-Tenant Access (403 Forbidden)
{
"type": "https://developer.aptiaone.com/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Client credentials do not possess the required scope 'aptia/participants.write' or requested tenant is outside authorized scope.",
"instance": "/v1/participants/11111111-1111-1111-1111-111111111111"
}