Developer Documentation

Integrate in minutes

Drop AuthFrame into any web app with an iframe and a few lines of JavaScript. Verify tokens on your server using industry-standard RS256 JWTs.

Quick Start

Get AuthFrame running in under 5 minutes.

  1. Create a new app in the dashboard
  2. Add your domain to the allowed origins
  3. Copy the embed snippet into your HTML
  4. Listen for auth events via postMessage
  5. Verify JWT tokens on your server using the JWKS endpoint
<!-- Step 1: Add the iframe -->
<iframe
  id="authframe"
  src="https://cdn.embedauth.com/embed/YOUR_CLIENT_ID.html?mode=signin"
  width="420"
  height="600"
  frameborder="0"
  style="border: none;"
></iframe>

<!-- Step 2: Listen for auth events -->
<script>
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://cdn.embedauth.com') return;
  if (event.data.type === 'authframe:auth-success') {
    const { token, user } = event.data.data;
    // Store the JWT and redirect the user
    sessionStorage.setItem('authframe_token', token);
    window.location.href = '/dashboard';
  }
});
</script>

JWT Verification

Verify tokens on your backend server.

AuthFrame issues RS256-signed JWT tokens. Verify them on your server using the public JWKS endpoint: https://embedauth.com/.well-known/jwks.json?clientId=YOUR_CLIENT_ID The JWT payload contains: sub — end user ID email — user's email address name — user's display name clientId — your app's client ID iat & exp — issued at and expiry timestamps

// Node.js verification using the "jose" package
import { createRemoteJWKSet, jwtVerify } from 'jose';

const JWKS = createRemoteJWKSet(
  new URL('https://embedauth.com/.well-known/jwks.json?clientId=YOUR_CLIENT_ID')
);

async function verifyToken(token) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: 'https://embedauth.com',
    audience: 'YOUR_CLIENT_ID',
  });
  return payload;
}

// Express middleware example
app.use(async (req, res, next) => {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (!token) return res.status(401).json({ error: 'Unauthorized' });
  try {
    req.user = await verifyToken(token);
    next();
  } catch {
    res.status(401).json({ error: 'Invalid token' });
  }
});

Embed Configuration

Customize the embed behavior with URL parameters.

ParameterValuesDescription
modesignin · signup · forgot-passwordInitial form to display
theme(theme ID)Apply a custom theme from your dashboard
redirect(URL)Redirect after auth (must be in allowed redirects)
compacttrue · falseCompact mode for smaller embeds
<!-- Sign in -->
<iframe src="https://cdn.embedauth.com/embed/CLIENT_ID.html?mode=signin"></iframe>

<!-- Sign up -->
<iframe src="https://cdn.embedauth.com/embed/CLIENT_ID.html?mode=signup"></iframe>

<!-- With a post-auth redirect -->
<iframe src="https://cdn.embedauth.com/embed/CLIENT_ID.html?mode=signin&redirect=https://yoursite.com/app"></iframe>

Content Security Policy

Allow the AuthFrame origin in your CSP frame-src directive.

If your site sends a Content-Security-Policy header you must whitelist the AuthFrame origin in the frame-src (or default-src) directive — otherwise browsers will refuse to load the iframe. The embed is served from: https://embedauth.com https://cdn.embedauth.com Note: password-reset and magic-link emails open at the app host (https://embedauth.com) and redirect to the CDN (https://cdn.embedauth.com), so both origins must be present.

<!-- HTTP response header (recommended) -->
Content-Security-Policy: frame-src https://embedauth.com https://cdn.embedauth.com;

<!-- <meta> tag alternative -->
<meta http-equiv="Content-Security-Policy"
      content="frame-src https://embedauth.com https://cdn.embedauth.com;">

# Nginx
add_header Content-Security-Policy "frame-src https://embedauth.com https://cdn.embedauth.com;" always;

# Node.js / Express
res.setHeader('Content-Security-Policy', 'frame-src https://embedauth.com https://cdn.embedauth.com;');

PostMessage Events

All events emitted by the embedded auth forms.

The iframe communicates with your page via window.postMessage. Always verify event.origin before processing any message.

window.addEventListener('message', (event) => {
  // Always verify the origin
  if (event.origin !== 'https://cdn.embedauth.com') return;

  switch (event.data.type) {
    case 'authframe:auth-success':
      // User signed in or signed up
      // data: { token: string, user: { id, email, name } }
      break;

    case 'authframe:auth-error':
      // Authentication failed
      // data: { error: string, code: string }
      break;

    case 'authframe:mode-change':
      // User switched between signin/signup/forgot-password
      // data: { mode: string }
      break;

    case 'authframe:resize':
      // Content height changed — useful for dynamic iframe sizing
      // data: { height: number }
      break;

    case 'authframe:loaded':
      // Iframe finished loading
      // data: { clientId: string, mode: string }
      break;

    case 'authframe:signout':
      // User signed out
      // data: {}
      break;
  }
});

Server-Side API

Manage users and sessions programmatically via API keys.

Create API keys in the dashboard under API Keys. Use them to access AuthFrame's REST API for listing users, revoking sessions, and managing app configuration.

// List end users
const response = await fetch('https://embedauth.com/api/v1/users', {
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
});
const { users } = await response.json();

// Revoke all sessions for a user
await fetch(`https://embedauth.com/api/v1/users/${userId}/sessions`, {
  method: 'DELETE',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
});

Ready to integrate?

Create a free account and have your first embed running in minutes.