Best practices
Age verification best practices
Handling verification failures
When implementing age verification, developers should check the failureReason field in verification results to properly handle failures:
- Fraudulent Activity Detection: If a verification fails and the
failureReasonisfraudulent-activity-detected, don't allow additional verification attempts for that user. - Other Failure Reasons: For all other failure reasons (such as
age-criteria-not-metormax-attempts-exceeded), implement rate limiting to prevent abuse while allowing legitimate retry attempts. Allow a maximum of 3 verification attempts per 24-hour period. This prevents users from repeatedly attempting to bypass the verification system while providing reasonable retry opportunities for legitimate users
Security recommendations
Server-only API calls
All age verification API endpoints should only be called from your server, never directly from client-side code.
Your OpenAge API key is a secret credential that must be protected:
- Store API keys securely using a secrets manager
- Never expose API keys in front end JavaScript, mobile app code, or any client-facing code
- Never store API keys on client devices or in client-side storage
Target origins configuration
You can configure target origins in the Compliance Studio to control which domains can embed your verification flows. This setting controls the frame-ancestors directive of the Content Security Policy. As an optional security measure, it's recommended to evaluate your risk tolerance and decide whether to implement target origin restrictions based on your security requirements.
Configuration Options:
- Specific domains: Set exact domains for production use (for example,
https://yourapp.com) - Wildcard subdomains: Use wildcard patterns for subdomains (for example,
https://*.yourapp.com) - Unrestricted: Leave empty or set to
*for unrestricted embedding (not recommended for production)
Security Benefits: Target origins prevent attackers from embedding your verification flows in transparent iFrames on malicious sites, where they could overlay other content and trick users into inadvertently clicking on verification elements.
Implementation Notes:
- Configure separate target origins for each environment (test/live)
- Ensure target origins are properly configured for all production endpoints before going live.
- Each subdomain requires its own entry unless using wildcards
- Only certain OpenAge pages can be embedded in iFrames regardless of target origin settings (verification pages and widgets)
- All other OpenAge pages (account settings) are always blocked from iFrame embedding
iFrame permissions
Always include the necessary permissions in your iFrame allow attribute:
<iframe
src="VERIFICATION_URL"
allow="camera;payment;publickey-credentials-get;publickey-credentials-create"
width="100%"
height="600"
></iframe>
Permission Breakdown:
camera- Required for facial age estimationpayment- Required for credit card verificationpublickey-credentials-create- Required for AgeKey creationpublickey-credentials-get- Required for AgeKey verification
Origin validation
Always validate the origin of incoming messages:
window.addEventListener('message', (event) => {
// Validate origin based on environment
const validOrigins = [
'https://ui.ageapi.org', // Live environment
'https://test.ui.ageapi.org' // Test environment
];
if (!validOrigins.includes(event.origin)) {
return; // Ignore messages from unauthorized origins
}
// Process the event
handleVerificationEvent(event.data);
});
Privacy and data handling
AgeKey best practices
- Reusable Credentials: AgeKeys are designed to be reusable across different services. Store them securely and use them for subsequent verifications.
- Privacy Preservation: AgeKeys only reveal age categories, not exact ages, maintaining user privacy.
- Secure Storage: Store AgeKeys using secure, encrypted storage mechanisms.
Data minimization
- Only request the minimum age verification data necessary for your use case
- Implement proper data retention policies
- Ensure compliance with local privacy regulations
Performance optimization
Caching strategies
- Cache verification results appropriately to reduce API calls
- Implement proper cache invalidation for security-sensitive data
- Use AgeKeys to minimize repeated verification requests
Error handling
- Implement comprehensive error handling for all verification scenarios
- Provide clear user feedback for different failure modes
- Log errors appropriately for debugging while maintaining privacy
Integration patterns
Progressive enhancement
- Design your app to work without age verification as a fallback
- Implement graceful degradation for users who can't complete verification
- Provide alternative access methods where legally permissible
User experience
- Make the verification process as smooth as possible
- Provide clear instructions and feedback throughout the process
- Minimize the number of steps required for verification