Skip to content

Connect your existing login

When your organization already has a login, EdgeKit can read it instead of signing users in itself. Your login is then EdgeKit’s identity provider, and the credential it gives a signed-in user is the external credential. EdgeKit verifies that credential on each request and never stores it. Sites read it in the external_only and dual id modes; see Choose who signs users in.

EdgeKit sets up the connection for your organization. This page says what EdgeKit needs from your login and what it does with what it receives.

  • From a browser: in a cookie your login sets on your own domain. You tell EdgeKit the cookie’s names. Only those exact names are read, and when several are present, the first name on your list wins even if it does not verify. The cookie must reach the /edgekit/ mount, so it must be set on the domain your pages are served from.
  • From a native app: in the body of POST /v1/id/session/exchange, as subject_token, at a dual site only. See Move users off your existing login.

EdgeKit never reads the external credential from Authorization: on EdgeKit ID routes that header only ever carries an EdgeKit session token.

EdgeKit verifies the credential one of two ways.

Your login issues a JSON Web Token in the profile below, and EdgeKit verifies it with your key, without calling your login.

Header:

  • alg: the one algorithm you chose, RS256, ES256 or HS256. A token naming another algorithm, or none, is refused before any key is looked up.
  • typ: edgekit-id+jwt. This keeps your login’s own ID or access tokens from being accepted here.
  • kid: the key id, for RS256 and ES256. It may be left out while your key set holds one key; with several keys, a token without it is refused.

Claims, all required:

  • iss: your issuer, exactly as EdgeKit has it.
  • sub: the person’s id in your login. It is what links them to their EdgeKit user from then on.
  • aud: the value EdgeKit gives you for this site. Every external_only or dual site has its own, and no two sites share one, so a token issued for one site is refused on another.
  • iat and exp. A token is refused once iat is older than its age limit, whatever exp says: 1 hour unless EdgeKit set another, and never more than 24 hours. Clocks may disagree by 60 seconds unless EdgeKit set another tolerance, never more than 5 minutes.

Plus the claims EdgeKit maps, below: by default email and email_verified.

{
"iss": "https://login.example.com",
"sub": "user-6475b8",
"aud": "<the aud value EdgeKit gave you for this site>",
"iat": 1792310400,
"exp": 1792314000,
"email": "ada@example.com",
"email_verified": true,
"membership_level": "premium"
}

Keys:

  • RS256 and ES256: EdgeKit fetches your public keys from your key set URL and keeps them for up to an hour. A token signed with a key id EdgeKit has not seen makes it fetch the set again, so you rotate keys without telling EdgeKit. EdgeKit never fetches a key from a URL inside the token.
  • HS256: you and EdgeKit hold the same secret, at least 32 bytes. Changing it means giving EdgeKit the new one.

If your login’s cookie is opaque, EdgeKit can ask your login’s session endpoint instead. For every request that needs the user, EdgeKit sends a GET to that endpoint with the request’s whole Cookie header, or a native app’s token in x-session-token, and waits up to 3 seconds. Nothing is cached, so at an external_only site every page view that asks who the user is makes one call to your endpoint.

  • 200 with a JSON body names the user. The person’s id is read from where you tell EdgeKit. The expiry is read from expires_at or exp, or else taken as the age limit.
  • 401 or 403 means nobody is signed in.
  • 429 means your endpoint is limiting EdgeKit. A timeout, any other status or a body that is not JSON means your endpoint could not be reached.

When your endpoint is down or limiting EdgeKit, users read as signed out until it recovers. At an external_only site, decide then answers your paying users as anonymous devices.

The person’s id in your login, sub, is the key. The first time EdgeKit sees an id, it finds or creates their user:

  1. If a user already holds the credential’s email address and the credential says the address is verified, EdgeKit links the id to that user. The user keeps their grants, memberships and history.
  2. If no user holds the address, EdgeKit creates one with that address, verified only if the credential says so. The new user is attached to this site, or to every site when your organization attaches new users everywhere. A verified address at a domain on a user organization’s auto-join list gives them a seat; see User organizations.
  3. If a user holds the address but the credential does not say it is verified, EdgeKit refuses: it never merges on an unverified address, and two users cannot share one. The person reads as signed out, and the refusal is recorded as identity.adoption_refused in Identity › Audience › Observability.
  4. A credential with no email address creates no user.

email_verified counts only when it is the JSON value true. The string "true" does not.

From then on EdgeKit matches on the id alone. At an external_only site, a new address in a later credential moves the user’s address, unless another user holds it.

If a user later proves an address with an EdgeKit code or link, a link to your login that never vouched for that address is cut. The person can still return through your login if it asserts the address as verified.

EdgeKit reads only the claims you map, and ignores every other claim in the credential.

Mapped to Default What EdgeKit does with it
The person’s id sub Links the credential to its user.
Email email Finds or creates the user the first time.
Email verified email_verified Decides whether an existing user may be linked.
A trait None Checked against your declared traits at deploy. Not written to the user’s record.
An external.* fact None Read by your rules at external_only sites. Never stored, never a grant.

A dotted path reads a nested claim, such as identity.id. A deploy is refused when a claim is mapped to a trait you have not declared, to a list trait, or to an external.* fact that is not declared. A new user’s display name is the claim mapped to a trait called name, or else the part of their address before the @.

  • With HS256, EdgeKit holds your signing secret. Anyone holding the secret can sign a credential your sites accept, so EdgeKit could sign in as any of your users. Choose RS256 or ES256, where EdgeKit holds only your public key, if that is not acceptable.
  • A loose email_verified hands over existing users. If your login says email_verified: true for an address the person does not control, EdgeKit links them to the user who holds that address, with that user’s grants, and nothing records it as anything but an ordinary first sign-in. Assert it only for addresses your login has proven.
  • EdgeKit cannot revoke your login’s credential. At an external_only site EdgeKit holds no session to end, so a token your login signs stays good until it expires or reaches its age limit, whichever comes first. Keep the limit short.

At a dual site you give EdgeKit your login’s sign-out page, and POST /v1/id/sign-out answers it as logoutUrl; a deploy is refused without it. See Move users off your existing login.