Overview
Dynamic provides a range of security tools and configuration options. Not every measure will be necessary for every use case — evaluate what best suits your risk profile, business requirements, and user experience. The recommendations below focus on authentication-specific practices. For broader security guidance (including embedded wallet security, developer credentials, and attack vector mitigations), see the Security overview and Security Best Practices.JWT lifetime and storage
- Keep JWT lifetime short. Configure the JWT expiration to the shortest acceptable duration that balances security and user experience. The maximum is 30 days. Adjust this in your dashboard security settings.
- Never save or log user JWTs. JWTs are session credentials — treat them like passwords. Do not persist them in databases, log files, or analytics.
- Consider cookie-based storage. Cookie storage makes the JWT inaccessible to client-side JavaScript, reducing the risk of XSS-based session theft. Use this when your architecture supports same-origin requests to your backend.
- Use in-app storage only when needed. If you need to pass the JWT to third-party integrations or your backend via explicit headers, in-app storage is appropriate — but be aware of the increased XSS exposure.
When using Dynamic-powered embedded wallets without transactional MFA, limit the JWT lifetime further — since the wallet is primarily gated by the JWT and the method used to log in.
Multi-factor authentication
- Enable MFA for high-value applications. MFA significantly reduces the risk of account takeover. Dynamic supports TOTP and Passkey as second factors.
- Consider action-based MFA for sensitive operations. Rather than requiring MFA at every login, you can require it only for high-value actions (e.g. large transactions, key export). This improves UX while protecting critical operations.
- Do not rely on SMS as a sole factor. If you use SMS for primary authentication, add a second factor (TOTP or Passkey) for stronger security.
Server-side JWT verification
- Always verify JWTs on your backend. Never trust a client-sent JWT without cryptographically verifying the signature and validating claims (
iss,exp,aud). See Tokens. - Cache the JWKS public key. Fetch the public key from the JWKS endpoint and cache it to avoid per-request latency. Refresh the cache when you encounter an unknown
kid. - Check for
requiresAdditionalAuth. If MFA is enabled, reject or limit access for tokens with therequiresAdditionalAuthscope — these tokens have not completed the full authentication flow.
CORS and allowed origins
- Configure specific CORS origins. Add explicit domains in your dashboard settings to prevent unauthorized websites from using your environment ID.
- Avoid wildcards. Use exact domains rather than wildcard patterns, especially in production.
- Keep production strict. Do not include
localhostor development domains in your live environment’s allowed origins.
Session management
- Implement proper logout flows. Ensure your application calls the SDK’s logout method when users sign out, clearing the session and JWT from the client. See Revoking Sessions.
- Use server-side revocation for security incidents. If an account is compromised, revoke all sessions for the user via the API to force re-authentication across all devices.
- Monitor session events. Use webhooks (
user.session.revoked,admin.user.session.revoked) to track session lifecycle and detect anomalies.
Access control
- Use access lists and gates at authentication time. Configure access control rules to block or scope users during authentication rather than only checking permissions on your backend.
- Use Return scopes for fine-grained authorization. Rather than blocking users entirely, add scopes to the JWT that your app and backend can use for feature gating.
API key security
- Store API keys on the backend only. Dynamic API tokens should never be exposed in client-side code, public repositories, or browser-accessible storage.
- Rotate API keys regularly. Institute an internal policy for periodic key rotation.
- Use role-based permissions. Restrict which team members can access API tokens and dashboard features using Dynamic’s role-based permissions.