Security Overview
Security best practices for ChainIT authentication integrations.
A single compromised credential can lead to data breaches. Follow these best practices to protect your application and users.
Security by App Type
| App Type | Key Security Features | Threat Model |
|---|---|---|
| M2M | Client secret protection, scope validation, token expiration | Server-to-server |
| IDP | PKCE required, callback URL validation, allowed origins, state parameter | Browser/mobile app |
| Hosted UI | Server-to-server secrets, session security, token handling | Managed UI |
Key Security Principles
| Principle | Description | Enforcement |
|---|---|---|
| Least Privilege | Only request scopes you need | Server validates scopes |
| Secure Storage | Store secrets in env vars, not code | Client-side responsibility |
| HTTPS Only | Always use HTTPS for API calls | TLS 1.2+ required |
| Token Hygiene | Refresh before expiration, revoke when done | Client responsibility |
| Validate Tokens | Verify signature, expiration, issuer, audience | Server-side validation |
Token Security
clientSecret is for server-side only. Browser bundles, mobile apps, and
frontend code should never contain secrets.
| Practice | Description | Impact |
|---|---|---|
| Never expose secrets in client code | clientSecret is for server-side only | Prevents token theft |
| Use HttpOnly cookies when possible | Prevents XSS access to tokens | Mitigates XSS attacks |
| Don't put tokens in URLs | Tokens in URLs leak via logs/referer | Prevents token leakage |
| Validate on every request | Check signature, expiration, scopes | Ensures token validity |
PKCE (IDP Apps)
PKCE (RFC 7636) is required for all IDP flows:
// Always use S256 method
const codeChallenge = base64url(sha256(codeVerifier));
PKCE prevents authorization code interception attacks. Even if the
authorization code is stolen, the attacker cannot exchange it without the
code_verifier.
Callback URL Validation
The server validates that the redirect_uri matches configured URLs exactly.
| Validation | Description |
|---|---|
| Exact Match | Redirect URL must match configured URL exactly |
| Protocol | HTTPS required for production |
| Port | Non-standard ports must be specified |
Server-to-Server Security (M2M & Hosted UI)
- Client secrets are encrypted at rest (AES-256)
- Rotate secrets periodically from the Developer Portal — open the application's Credentials section and use the Rotate secret action
- Use environment variables, never hardcode secrets
Regularly rotate client secrets from the portal. Update your applications with the new secret immediately after rotation, and revoke any leaked credentials.
Origin Whitelisting
ChainIT enforces origin whitelisting (CORS) for all browser-based integrations. Only origins you explicitly register in URL White Listing (CORS) can make API calls or host your OAuth flow.
| App Type | Enforcement | Reference |
|---|---|---|
| IDP | Browser CORS on token/userinfo endpoints | Origin whitelisting guide |
| Hosted UI | Server-side X-Origin header validation on SDK calls | Origin whitelisting guide |
Always register every environment (production, staging, local) and never use a bare * wildcard.
Configure at least one allowed origin when creating an IDP or Hosted UI application. See the full origin whitelisting guide for configuration rules and troubleshooting.
Mobile QR Face Handoff
When the desktop has no camera, Hosted UI can hand the face scan to a phone via a QR code. The QR returns to the same application page with a single-use code in the URL (?h=<code> by default, or your configured handoffParam), which the SDK detects automatically.
| Control | Description |
|---|---|
| Single-use code | The handoff code is burned server-side on completion; a reused or stale code is rejected. |
| Origin-validated resolve | Resolving the code (/users/v1/hosted-auth/liveness/qr-session/resolve) validates X-Origin against your URL whitelist, so the handoff only works on allowlisted pages. |
| Ephemeral credentials | The resolved request token stays in iframe memory only and is cleared on completion; the SDK strips the handoff param from the URL afterward. |
On pages wrapped by HostedAuthProvider, the handoff query
parameter (h by default, or your configured
handoffParam) is reserved for the mobile face handoff. Do
not reuse it for your own routing, analytics, or feature
flags — any value present on load makes the SDK render the handoff surface
instead of your app. See the
mobile QR face handoff
section.