Sections

Authentication for satellite apps

Let the apps in your catalog trust Frontdoor sign-in with a shared cookie, a forwarded token or token introspection.

On this page

A satellite app is an app in the Frontdoor catalog that relies on Frontdoor for authentication. Admins pick its connection mode in the app editor (see Apps and connection modes); this page covers what the satellite has to do.

Choose a pattern

Pick the most restrictive pattern that fits your deployment.

Pattern When to use What the satellite needs
Shared cookie (mode=shared-cookie) The satellite is hosted under a subdomain of BASE_DOMAIN. Read the frontdoor_token httpOnly cookie and verify it locally with the shared JWT_SECRET.
Redirect with shared secret (mode=redirect) The satellite is on a different domain, run by the same team. Receive the short-lived token by GET query string or POST form, and verify it locally with the shared JWT_SECRET.
Redirect with introspection (mode=redirect) The satellite is on a different domain and should not hold Frontdoor's secret: a third party, a lower-trust environment, or to limit the damage of a leak. Receive the short-lived token, then POST it to /api/auth/verify-sso-token with its own slug as expected_aud. No shared secret.

Both redirect patterns use the same app mode (mode=redirect); they differ only in how the satellite verifies the token.

Sharing the secret

An app that holds JWT_SECRET can verify Frontdoor tokens, but it could also sign them, including session tokens. Share the secret only with fully trusted apps and use introspection for the others.

Frontdoor accepts as sessions only tokens signed with HS256, carrying its issuer (JWT_ISSUER, default frontdoor) and no audience. A satellite that verifies tokens locally must expect the same issuer.

Verify a token with introspection

POST /api/auth/verify-sso-token is a server-to-server introspection endpoint, inspired by RFC 7662 and scoped to this flow. In one call Frontdoor checks the signature, expiration, issuer, audience, that the user is active and that the app is active.

You do not need an API key: holding a valid token for the requested expected_aud is the authorization.

curl -sX POST https://frontdoor.contoso.com/api/auth/verify-sso-token \
  -H 'Content-Type: application/json' \
  -d '{"token":"<jwt>","expected_aud":"<your-app-slug>"}'

A valid token returns 200:

{
  "valid": true,
  "user": { "id": "...", "email": "...", "name": "...", "role": "user" },
  "aud": "<your-app-slug>",
  "exp": 1745740300
}

Errors

Status error Meaning
400 bad_request token or expected_aud is missing or malformed (slug format).
401 invalid_token Bad signature or expired token (intentionally indistinguishable).
401 invalid_issuer The token was not issued by this Frontdoor.
401 user_not_found_or_inactive The token's sub does not match an active user.
403 audience_mismatch The token was replayed across apps. Frontdoor logs the caller as a warning.
403 app_inactive expected_aud matches an app that has been deactivated.
429 too_many_requests Rate limit tripped (120 requests per minute per IP).

Scope the local session

Use exp to limit the satellite's own session, so it never outlives the Frontdoor token:

local session lifetime = min(default_session_ttl, exp - now)

Check the session from another origin

A page that only needs to know whether the user is signed in, without being an app in the catalog, can call /api/auth/me with credentials: 'include' once its origin is in CORS_ALLOWED_ORIGINS. See Cross-origin session checks.

Impersonation and satellites

When an admin acts as a user in Frontdoor, the session lives in a separate host-only cookie (frontdoor_impersonation) used only on requests from Frontdoor itself. The shared frontdoor_token cookie never changes, so shared-cookie satellites and cross-origin session checks keep seeing the admin, never the impersonated user. While impersonating, apps cannot be opened and no SSO token is issued.