Docs / Guides

Stable

Verify the selection token

Validate the signed account selection before using the chosen DID, handle, or PDS hint.

Fetch Atmosphere’s public JWKS.Verify signature, type, issuer, audience, state, return URI, expiry, and replay.Treat the token as account selection, not an OAuth credential.

Server

Use the verifier helper

Callback verification
import {
  fetchAtmosphereLoginPublicJwkForToken,
  verifyAtmosphereLoginCallback,
} from "https://login.atmosphereaccount.com/atmosphere-login-server.js";

const callbackUrl = new URL(request.url);
const selectionToken = callbackUrl.searchParams.get("selection_token");
if (!selectionToken) throw new Error("Missing selection token");

const publicJwk = await fetchAtmosphereLoginPublicJwkForToken(
  selectionToken,
  "https://login.atmosphereaccount.com",
);

const result = await verifyAtmosphereLoginCallback({
  url: callbackUrl,
  publicJwk,
  expectedIssuer: "https://login.atmosphereaccount.com",
  expectedClientId: "https://app.example.com/oauth/client-metadata.json",
  expectedState,
  expectedReturnUri: "https://app.example.com/auth/atmosphere/selected",
  replayStore,
});

if (!result.ok) throw new Error(result.error);
const loginHint = result.claims.handle || result.claims.sub;

Claims to bind

ClaimRequired check
issExpected Atmosphere deployment.
audYour registered client_id.
subSelected DID; use as durable account identity.
handleDisplay/login hint only; handles can change.
return_uriExact callback receiving the token.
stateFresh nonce from the initiating request.
exp / iatShort token lifetime and no future-issued token.
jtiReject replay until expiry.
Selection is not authorization

The selection token proves the user chose an account in Atmosphere. It does not give your app repository access, blob upload access, or a PDS session.

On this page

Next steps

Keep building