Verify identity tokens on your server
Your app sends the user's access token to your backend as Authorization: Bearer <token>. The token is an ES256 JWT that lasts fifteen minutes. Its issuer is <IDENTITY_ISSUER>/projects/<projectId>, its audience is the project ID, and it carries the user ID (sub), the session family (sid), the workspace (wid) and, when set, your own user ID (ext).
Both verifiers check the signature against the project's public keys (GET /v1/identity/jwks, fetched and cached), the ES256 algorithm, issuer, audience and expiry. Verification is networkless after the keys are cached. A verified token proves the person signed in when it was issued. It cannot show a revocation, such as a logout or a block, before it expires; to see that, call GET /me with the token.
The defaults point at Mocco's hosted service (https://www.mocco.club). On a self-hosted server, pass your IDENTITY_ISSUER as the issuer.
Node
import { createIdentityVerifier } from '@mocco/node';
const verifier = createIdentityVerifier({ projectId: 'your-project-uuid' });
// Anywhere you have a Request, Headers or a plain header object:
const user = await verifier.authenticate(request);
if (user === null) {
return new Response('Unauthorized', { status: 401 });
}
console.log(user.userId, user.externalId, user.expiresAt);authenticate reads the Authorization header and returns the claims, or null for a missing header, an API key (mk_…) or a token that fails verification. It never throws for a bad token. verify(token) takes the bare token and rejects when it fails. Claims are userId, sessionId, workspaceId, projectId, externalId (null when unset) and expiresAt. Build one verifier and share it, so the key cache is shared.
Rust
use mocco_identity::{Verifier, VerifierConfig};
let verifier = Verifier::new(VerifierConfig {
project_id: "your-project-uuid".to_owned(),
issuer: None,
jwks_url: None,
});
match verifier.verify(token).await {
Ok(claims) => println!("signed in as {}", claims.user_id),
Err(error) => println!("rejected: {error}"),
}With the axum feature, a MoccoUser extractor reads the header and answers 401 for anything that does not verify. The crate's README covers the errors, the key cache and custom key fetching. The crate is published manually for now.
When to ask Mocco instead
Use the verifier for routes where a fifteen-minute window is acceptable. For an action that must stop the moment a person is signed out or blocked, such as a payment or a deletion, also call GET /v1/identity/me with the token and your publishable key. It checks the live session and answers 401 invalid_session when it has been revoked.