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_idclaim 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.