Skip to main content

Best practices

Age gate best practices

Always check age gate requirements

Before collecting age information, always call /age-gate/get-requirements with the player's jurisdiction. This ensures you:

  • Display the age gate only when required (shouldDisplay = true)
  • Use only approved age collection methods for the jurisdiction
  • Understand the age thresholds (digital consent age, civil age, minimum age)
  • Know if age assurance is required

Handle all age gate check responses

When calling /age-gate/check, handle all three possible statuses:

  • PROHIBITED: Player is below the minimum age - block access completely
  • CHALLENGE: Player requires parental consent - create and display a challenge
  • PASS: Player can continue - retrieve or create a session

Never assume a player can proceed without checking the response status.

VPC and challenge best practices

Store challenge IDs persistently

When a CHALLENGE status is returned from /age-gate/check, store the challenge ID in local storage or your server. This allows you to:

  • Resume the consent flow if the player returns before consent is granted
  • Display the same challenge information (QR code, OTP) on subsequent visits
  • Retrieve challenge details using /challenge/get

Configure webhooks to receive Challenge.StateChange events instead of polling. Webhooks provide:

  • Real-time updates when consent is granted or denied
  • Reduced API calls and better performance
  • More reliable status tracking

If you must use polling, implement proper rate limiting:

  • Minimum 5 seconds between calls to /challenge/get-status
  • Always check for HTTP 429 responses and implement appropriate retry logic
  • Set appropriate timeout limits

Notify trusted adults effectively

When a challenge is created, provide multiple ways for trusted adults to complete consent:

  • Email notification: Call /challenge/send-email if an email address is available
  • QR code display: Show the QR code URL returned in the challenge response
  • OTP entry: Display the one-time password for manual entry

Store the approverEmail from challenge status responses for customer service purposes.

Session management best practices

Cache sessions appropriately

Sessions should be cached in local or cloud storage and associated with a player's account. Sessions only change when:

  • A parent updates permissions
  • A player "ages up" to the next age category
  • The session is deleted by the parent or player

Use ETags for efficient session retrieval

The /session/get API supports conditional requests by using the etag parameter. Include the ETag from your cached session:

  • If the session hasn't changed, the API returns HTTP 304 (Not Modified)
  • This reduces unnecessary data transfer and improves performance
  • Always refresh sessions when the game restarts

Implement session webhooks

Configure webhooks to receive session-related events:

This provides real-time updates without polling and ensures your game reflects permission changes immediately.

Handle session upgrades properly

When players request additional permissions that require parental consent:

  • Use /session/upgrade to create a challenge for new permissions
  • Use the permissions upgrade widget to handle the consent workflow
  • Monitor session changes via webhooks or polling to detect when upgrades are approved

Permissions best practices

Respect permission states

Always check both the enabled and managedBy fields for each permission:

  • enabled: true: Feature can be enabled for the player
  • enabled: false: Feature must be turned off
  • managedBy: PLAYER: Player can enable/disable themselves
  • managedBy: GUARDIAN: Only a trusted adult can enable/disable
  • managedBy: PROHIBITED: Feature is never allowed - remove it from the UI entirely

Map permissions to game features correctly

Ensure each k-ID permission is properly mapped to the corresponding feature in your game. Permissions should control access to:

  • Age-restricted content
  • Features requiring parental consent
  • Data collection capabilities
  • Communication features

Configure permissions in the Compliance Studio to match your game's feature set.

Security recommendations

Server-only API calls

Important

All widget URL generation endpoints should only be called from your server, never directly from client-side code.

Your k-ID 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

CDK offers the ability to configure target origins in the Compliance Studio to control which domains can embed your widgets. 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://yourgame.com)
  • Wildcard subdomains: Use wildcard patterns for subdomains (for example, https://*.yourgame.com)
  • Unrestricted: Leave empty or set to * for unrestricted embedding (not recommended for production)

Security Benefits: Target origins prevent attackers from embedding your compliance flows in transparent iframes on malicious sites, where they could overlay other content and trick users into inadvertently clicking on verification elements.

Important

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
info

Only certain k-ID pages can be embedded in iframes regardless of target origin settings (verification pages, widgets, and VPC flows). All other k-ID pages (family management, account settings) are always blocked from iframe embedding.

iframe permissions

Always include the necessary permissions in your iframe allow attribute:

<iframe 
src="WIDGET_URL"
allow="camera;payment;publickey-credentials-get;publickey-credentials-create"
width="100%"
height="600"
></iframe>

Permission Breakdown:

  • camera - Required for facial age estimation (if used)
  • payment - Required for credit card verification (if used)
  • publickey-credentials-create - Required for Age Key creation (if used)
  • publickey-credentials-get - Required for Age Key verification (if used)

Origin validation

Always validate the origin of incoming messages:

window.addEventListener('message', (event) => {
// Validate origin based on environment
const validOrigins = [
'https://family.k-id.com', // Live environment
'https://family.test.k-id.com' // Test environment
];

if (!validOrigins.includes(event.origin)) {
return; // Ignore messages from unauthorized origins
}

// Process the event
handleWidgetEvent(event.data);
});

Account system integration

Product context mapping

When integrating CDK with an account system that spans multiple games:

  • Map each game to its own k-ID Product in the Compliance Studio
  • Create a separate k-ID Product for the Account System itself for global permissions
  • Ensure the correct API key is used for each Product context
  • Store the kuid from sessions in your account system for cross-product session retrieval

Session caching for multiple products

Cache sessions by Product ID in your account system:

  • Use k-ID Product ID as the cache key
  • Check for existing sessions before triggering new VPC flows
  • Allow players to continue without additional consent if a session already exists for a Product

Jurisdiction handling

Always pass the correct jurisdiction when making API calls:

  • Determine jurisdiction from player's location or IP address
  • Use jurisdiction-specific age thresholds and requirements
  • Handle jurisdiction changes during gameplay by calling /session/update-jurisdiction