Skip to main content

Audiences & tokens

An application is an audience

Every access token is minted for a specific audience — the service that will verify it. In Latch Vector that audience is an application: you register one, give it an identifier (a URI by convention, e.g. https://api.yourcompany.com), and configure your services with that value as their SSO_AUDIENCE.

A token minted for https://api.acme.com is only valid at services that verify against https://api.acme.com. One application per service, or per group of services that trust the same tokens.

Access tokens

  • Format: signed JWT, RS256. Verify with the JWKS the service publishes — the SDKs do this for you and pin the algorithm.
  • Lifetime: short (15 minutes). Don't try to extend it; refresh instead.
  • Claims: the subject (user), their organization, and the permissions granted to them in that org. A device_id claim is present for device sessions.
{
"sub": "8123",
"org": "1000042",
"aud": "https://api.acme.com",
"permissions": ["USER_MANAGE", "invoice.approve"],
"exp": 1735689600
}

The management token

Some calls (creating users, roles, applications…) are management calls. They use an ordinary user access token minted with the audience omitted — you get one by logging in with audience set equal to the issuer:

const sso = new SsoClient({ issuer, audience: issuer }); // aud omitted on the wire
const { tokens } = await sso.login(serviceEmail, servicePassword);
const mgmt = new ManagementClient({ issuer, token: tokens.accessToken });

The signed-in account needs the relevant permissions (USER_MANAGE, ORG_MANAGE, ROLE_MANAGE, CLIENT_MANAGE, AUDIT_VIEW). Use a dedicated service account, not a person.

Refresh tokens

A refresh token is an opaque selector.verifier string — not a JWT. It is:

  • Single-use and rotating — every refresh returns a new one and kills the old.
  • Reuse-detected — replaying a rotated token is treated as a compromise and revokes the whole session family (RFC 9700 containment).
  • Longer-lived than the access token — see Sessions & refresh.

Machine-to-machine

For server-to-server access with no user, register an API client and use the OAuth 2.0 client credentials grant at POST /oauth2/token. You get an access token scoped to the client's granted scopes.