Multi-Tenant Auth as a Service

Authentication that
embeds anywhere

Drop-in iframe authentication for your apps. Email/password, magic links, OTP, and OAuth — fully customizable with your branding. Launch in minutes.

yourapp.com/login

Welcome back

Sign in to continue

or
The Basics

What is embedded authentication?

A practical explainer for engineers evaluating identity options for their SaaS, B2B dashboard, or white-label product.

Embedded authentication is a pattern where the login experience lives inside your application — typically rendered through an iframe, a web component, or a UI SDK — rather than redirecting users to a separate identity provider domain. Your user never leaves yourapp.com. They type their email, click the magic link, finish OAuth, and stay on your page the entire time. The auth provider hands a signed token back to your application through a secure cross-origin channel, and your app takes it from there.

The alternative is hosted login — the model popularized by Auth0, Okta, and most enterprise IAM vendors. With hosted login, your application redirects the browser to auth.yourprovider.com, the user authenticates there, and the provider redirects them back with an authorization code. It is the safest pattern for credentials — there is no way for your application code to ever see a password — and it is what every OAuth 2.0 textbook recommends. But it comes with real ergonomic costs.

Hosted login breaks the visual continuity of your product. The login page lives on a different domain, with a different URL bar, a different favicon, and frequently a different look-and-feel no matter how carefully you theme it. Single-page applications that want to keep a user in-place — modals, drawers, embedded widgets, white-label dashboards — cannot use a redirect-based flow without unmounting their entire UI state. And for white-label products specifically, sending an end-user to a third-party domain is a deal-breaker: the customer is paying you to look like a first-party experience.

Embedded auth solves the UX problem. The iframe loads the provider's login page, but the user perceives it as part of your app. The frame is fully themable. Forms post directly to the provider, so credentials still never touch your servers. When authentication succeeds, the iframe sends a postMessage back to the parent page containing a signed JWT, and your front-end uses it to make authenticated API calls.

The trade-off is implementation complexity for the provider. Doing embedded auth correctly means solving the third-party-cookie problem, handling postMessageorigin validation correctly, isolating the auth context inside an iframe so a compromised parent page can't exfiltrate credentials, and managing refresh tokens without exposing them to the embedding application. This is exactly what AuthFrame is built for — the provider absorbs the hard parts, and you get a one-line embed.

Developers reach for embedded auth in three common situations. First, when conversion matters: a redirect costs you a measurable percentage of signups, especially on mobile where the bounce-back loop is jarring. Second, when the product is itself an embed — a widget, a chat box, a checkout extension — and a full-page redirect would break the parent application's state. Third, when the product is white-labeled: a B2B dashboard sold to enterprises that need their end-users to never see a vendor's domain. In all three cases, the redirect-based hosted flow is the wrong tool, and an embeddable authentication surface is the right one.

AuthFrame is opinionated about this. We don't ask you to choose between embedded and hosted — we treat embedded as the primary mode and design every feature around it. The iframe surface, the postMessage protocol, the JWKS endpoint, the theming engine, the multi-tenant isolation model: all of it exists so you can put auth inside your product without writing the cross-origin plumbing yourself.

Under The Hood

Technical architecture

How a request flows from the embedded iframe through token exchange to an authenticated API call — and the isolation guarantees at each hop.

Diagram 1 — End-to-end embed flow
PARENT PAGE
yourapp.com
Your SPA or server-rendered app
<iframe src="...">
onMessage(event)
AUTH IFRAME
embedauth.com
Isolated origin, sandboxed
POST /api/signin
Set-Cookie: refresh
postMessage(jwt)
YOUR API
api.yourapp.com
Verifies JWT via JWKS
Authorization: Bearer
GET /.well-known/jwks.json
1.Parent embeds iframe with origin-scoped client ID.
2.User submits credentials; iframe sets HttpOnly refresh cookie scoped to embedauth.com.
3.Iframe posts a short-lived access JWT to the parent; your API verifies via JWKS.

Iframe isolation

The login surface runs on a separate origin from your application. Browser same-origin policy prevents the parent from reading the iframe's DOM, cookies, or localStorage. A compromised parent page cannot read what the user typed into the login form. The iframe is served with a strict CSP andX-Frame-Optionsis replaced by per-tenantframe-ancestorsrules.

Token handling

Access tokens are RS256-signed JWTs with a 15-minute default lifetime. They includesub,aud,iss, and tenant claims. Verification is stateless: your API fetches the public JWKS once, caches it, and verifies signatures locally. No round trips back to AuthFrame on the hot path.

Cookie strategy

Refresh tokens live in HttpOnly, Secure, SameSite=None cookies scoped to the AuthFrame origin. JavaScript in the parent page cannot read them. To work around third-party cookie restrictions in modern browsers, AuthFrame supports CNAME-based custom domains so the auth iframe loads fromauth.yourapp.com, keeping cookies first-party.

Session management

Sessions follow the rolling-refresh pattern. The iframe silently calls /refreshahead of token expiry, rotates the refresh token (one-time-use), and posts the new access token to the parent. Logout revokes the refresh family server-side, so a stolen refresh token can't outlive an explicit signout across devices.

Cross-domain security

Every postMessage from the iframe is sent with an explicit target origin (never "*") and includes a signed nonce. The parent SDK verifies the message origin matches the configured auth domain and that the nonce matches its outstanding request. Allowed parent origins are configured per-application — a stolen client ID cannot be rendered from an arbitrary domain.

Diagram 2 — Token lifecycle
Sign in
POST /signin
Access JWT
15 min TTL
API call
Bearer header
Silent refresh
iframe → /refresh
Rotate refresh
one-time-use
Logout / revoke
family invalidated
The Hard Parts

Why embedded auth is harder than it looks

The browser is actively hostile to most of what embedded authentication needs to do. Here's the terrain.

Browser restrictions

Same-origin policy is the foundation of web security — and the main obstacle to embedding anything that needs identity. Cross-origin iframes can't read parent state, can't share cookies by default, and modern browsers increasingly enforceSameSite=Laxas the default for cookies, breaking naive cross-site session models. Working with these restrictions (instead of trying to defeat them) is the entire game.

Third-party cookie deprecation

Safari (ITP) and Firefox (ETP) already block third-party cookies by default. Chrome is rolling out the same. Any auth provider relying on a session cookie set on its own domain — read from inside a cross-site iframe — is on borrowed time. The fix is CNAME-based first-party deployment, but doing that securely requires automated TLS provisioning, per-tenant certificate management, and careful origin pinning.

OAuth complexity

OAuth 2.0 has a redirect-based mental model baked in. Doing a Google or GitHub sign-in from inside an iframe means popping a new window (because Google explicitly blocks framing of accounts.google.com), running PKCE, catching the redirect on a callback page, and posting the code back to the original iframe. Each provider has quirks — Apple Sign-In requires form_post response mode, Microsoft requires nonce handling, GitHub doesn't support PKCE confidentially.

Security tradeoffs

Every UX shortcut chips away at the security boundary. Storing access tokens in localStorage makes XSS catastrophic. Exposing refresh tokens to JavaScript makes them stealable. Loosening frame-ancestors to a wildcard opens clickjacking. The right answer is rarely the simple one: HttpOnly cookies for refresh, short-lived access JWTs in memory, strict origin allowlists, and a refusal to ship features that require relaxing any of it.

The honest version:most of the engineering work in an auth provider isn't the login form — it's the cross-origin choreography, the cookie strategy, the OAuth quirks, and the constant browser-vendor moving target. That's the work AuthFrame absorbs so your team doesn't have to.

Who It's For

Use cases

Where embedded auth pays off the most.

SaaS products

Modern web apps that want a polished login experience without redirecting users off-domain. Email/password, magic links, and social — all themed to match the product.

Project management, analytics, dev tools

B2B dashboards

Internal-facing customer dashboards where SSO, RBAC, and audit logs matter. Embedded auth keeps the dashboard feeling integrated rather than bolted-on.

Admin consoles, billing portals, partner hubs

Embedded widgets

Chat boxes, support widgets, checkout extensions, and other surfaces that live inside someone else&apos;s page. A full-page redirect would break the host application.

Intercom-style chat, Stripe-style checkout

White-label products

Software resold under your customer&apos;s brand. The end-user must never see a vendor domain. CNAME-based custom domains keep auth on the customer&apos;s subdomain.

Agency platforms, OEM software, reseller portals

Enterprise portals

Customer or vendor portals that need SAML SSO, SCIM provisioning, and per-tenant configuration. One AuthFrame app per enterprise customer, with isolated user pools.

Supplier portals, partner ecosystems

Multi-tenant marketplaces

Platforms where each merchant or workspace needs its own user pool and branding. AuthFrame&apos;s multi-tenant model gives every tenant isolated users, themes, and audit trails.

Marketplaces, communities, course platforms
How We Compare

AuthFrame vs the alternatives

A direct comparison against the three most common identity options. We've tried to be fair — every product here has things it does well.

AuthFrame vs Auth0

CapabilityAuthFrameAuth0
Embedded iframe (first-class)
Primary mode
Universal Login is hosted
Hosted login redirect
CNAME custom domains
Paid tier only
Multi-tenant (orgs / apps)
RS256 JWTs + JWKS endpoint
Theming via tokens + CSS
Branding API + limited CSS
SAML SSO
Roadmap
Pricing predictability
Flat per-app
MAU-based, grows fast
Lock-in surface
Open data export

AuthFrame vs Clerk

CapabilityAuthFrameClerk
Framework-agnostic embed
React-first SDK
Iframe-based isolation
UI components run in-page
React / Next.js components
React wrapper available
White-label / brand removal
Paid tier
JWT verification via JWKS
Self-hostable
Pricing for high-volume MAU
Flat tiers
MAU-priced

AuthFrame vs Firebase Authentication

CapabilityAuthFrameFirebase Auth
Embedded iframe UI
FirebaseUI is in-page only
Vendor-neutral (no GCP lock-in)
Multi-tenant per-app branding
Identity Platform tier
Hostable custom domains
OIDC / SAML support
Identity Platform tier
Tight integration with Firestore / FCM
Per-app theming dashboard
Last updated 2026. Vendor capabilities change frequently — verify on the respective product pages before making a purchase decision.

Everything you need

Powerful auth features, zero backend work.

Embed in 2 Lines

Add an iframe to your HTML and listen for postMessage events. That's it.

Full CSS Control

Match your brand with theme tokens, custom CSS, live iframe preview, and 6 built-in presets.

RS256 JWT + JWKS

Industry-standard signed tokens. Verify with our public JWKS endpoint.

Multi-Tenant

One dashboard, unlimited apps. Each with its own users, themes, and settings.

5 Auth Methods

Email/password, magic links, OTP, Google OAuth, GitHub OAuth — toggle per app.

Enterprise Security

Rate limiting, brute-force protection, audit logs, encrypted secrets, CSP headers.

Frequently Asked

Technical FAQ

Answers to the questions engineers actually ask when evaluating an embedded auth provider.

Is iframe-based authentication secure?
Yes — when implemented correctly. The iframe runs on a separate origin, so the parent page cannot read the login form, cookies, or tokens. AuthFrame enforces strict frame-ancestors policies, signs postMessage payloads, validates origins on both sides, and stores refresh tokens in HttpOnly cookies that JavaScript cannot access. The risk profile is comparable to redirect-based hosted login, with the UX benefit of staying on your domain.
How does PKCE work in an embedded flow?
For OAuth providers (Google, GitHub, etc.), AuthFrame generates a code_verifier inside the iframe, hashes it to produce a code_challenge, and opens a popup window to the provider with the challenge attached. When the provider redirects back to our callback page, we exchange the code + original verifier for tokens server-side. The popup then closes and the result is posted back into the iframe. PKCE protects against authorization code interception even though the flow lives partly outside the iframe.
Does AuthFrame support SSO (SAML / OIDC)?
OIDC is supported for every social provider we ship (Google, GitHub, Microsoft, Apple) and via generic OIDC for custom enterprise IdPs. SAML is on the roadmap for the Business tier — if you need it before general availability, contact us for early access.
How are refresh tokens stored?
Refresh tokens are stored exclusively in HttpOnly, Secure, SameSite=None cookies scoped to the auth iframe origin. They are never readable by JavaScript in either the parent page or the iframe. Each refresh token is one-time-use: redeeming it issues a new refresh token and invalidates the old one. If a stolen token is replayed, the entire refresh family is revoked.
What happens if a browser blocks third-party cookies?
For Safari and other ITP-style browsers, AuthFrame supports CNAME-based custom domains. You point a subdomain like auth.yourapp.com to our service, we provision TLS automatically, and the iframe loads from a first-party origin relative to your app. Cookies set on that subdomain are first-party and not affected by third-party cookie restrictions.
How do I verify tokens on my backend?
AuthFrame issues RS256-signed JWTs. Your backend fetches our public keys once from /.well-known/jwks.json, caches them (we publish a Cache-Control of 1 hour), and verifies signatures locally using any standard JWT library. There is no callback to AuthFrame on the hot path — verification is a fast, in-process operation.
What is the access token lifetime?
Access tokens default to 15 minutes. Refresh tokens default to 30 days with rolling renewal — every successful refresh extends the window. Both lifetimes are configurable per application from the dashboard.
Can I customize the look and feel of the embed?
Yes. AuthFrame ships with theme tokens (colors, radii, font families, spacing) that map onto the entire UI. For deeper customization you can inject custom CSS that scopes to the iframe. A live preview in the dashboard shows your changes in real-time. Six built-in presets cover the common starting points (Default, Minimal, Dark, Brutalist, Glass, Corporate).
Is AuthFrame multi-tenant?
Yes — multi-tenancy is the core data model. One organization can have unlimited applications. Each application has its own user pool, theme, allowed domains, OAuth credentials, and audit log. Users in one application are not visible from another. This is the right model for both per-product separation and white-label per-customer isolation.
Can I migrate users in from another provider?
Yes. AuthFrame supports bulk user import via CSV or JSON, including bcrypt and argon2 password hashes (we re-hash on first signin if your existing hashes use weaker parameters). For OAuth users we preserve the provider linkage so they continue signing in with the same provider account without re-consent.
How do I handle logout?
Call the signout method on the parent SDK or post a signout message to the iframe. The iframe clears its refresh cookie, revokes the refresh family server-side, and posts a signed signout event back to the parent. If you have multiple tabs open, the BroadcastChannel API propagates the signout across all of them.
What about XSS on the parent page?
A successful XSS on your parent page can still read the access JWT (which lives in memory there). It cannot read the refresh token, which lives in an HttpOnly cookie on the iframe origin. So an XSS attacker is bounded to the access token lifetime (~15 minutes) rather than getting a persistent foothold. The mitigation against XSS is, as always, a strict CSP on your parent page.
Does AuthFrame support webhooks?
Yes. You can subscribe to events like user.created, user.signed_in, user.signed_out, password.reset.requested, mfa.enabled, etc. Webhooks are signed with HMAC-SHA256 and include a timestamp to prevent replay. We retry failed deliveries with exponential backoff for up to 24 hours.
Can I self-host AuthFrame?
Yes. The same Docker image we run in production is available for self-hosting on the Business and Enterprise tiers. You bring your own PostgreSQL, set a handful of environment variables, and run it behind your own reverse proxy. The dashboard, iframe, API, and JWKS all live in the same container.
How do you handle rate limiting and brute-force attempts?
Authentication endpoints are rate-limited per IP and per account. Repeated password failures trigger exponential backoff and account-level temporary lockouts. Magic link and OTP endpoints have stricter per-email limits to prevent enumeration. All rate-limit events are recorded in the audit log.
What data is in the access JWT?
A minimal set: sub (user id), aud (application id), iss (issuer), iat / exp / nbf, plus a small claims block with email, email_verified, and any custom claims you have configured. We deliberately keep tokens small — large JWTs cause issues with HTTP header limits in some proxies.
Do you support MFA / 2FA?
Yes — TOTP (compatible with Google Authenticator, 1Password, Authy) and WebAuthn (passkeys, security keys) are supported out of the box. SMS-based 2FA is available but discouraged given known SIM-swap risks. You can enforce MFA per application or leave it user-opt-in.
How do magic links work?
When a user requests a magic link, we issue a single-use, short-lived (15 minute default) signed token bound to the user&apos;s email and the requesting browser session. Clicking the link from any device verifies the token, completes the sign-in inside the iframe, and posts the JWT back. Tokens are invalidated immediately on use.
Is there a React or Next.js SDK?
Yes. The @authframe/react package exposes a provider, hooks (useUser, useSession, useSignIn), and a pre-built <AuthFrame /> component that handles the iframe lifecycle and postMessage protocol. The vanilla JS SDK works everywhere else.
What about GDPR / data residency?
Standard EU and US regions are available. You can pin all data for an application to a specific region from the dashboard, which scopes user records, audit logs, and session data to that region&apos;s database cluster. Data subject requests (export, delete) are exposed via API endpoints for programmatic compliance.
How does pricing scale?
Pricing is flat-tier based on the number of applications and the volume of monthly auth events, not strictly on MAU. This avoids the surprise bills that catch teams off-guard with MAU-based pricing as a free-tier launch goes viral. The full breakdown is on the pricing page.
What if I outgrow AuthFrame?
Your data is yours. The dashboard has a one-click export that includes all users, their hashed credentials, their OAuth identities, and the configuration of every application. The export is in a documented JSON format that any halfway competent identity team can re-import elsewhere. We do not believe in artificial lock-in.

Ready to ship auth?

Free plan includes 3 apps and 1,000 monthly auth events.

Get Started Free