Mints a user token for one signed-in user of your app. Call it from your backend, never from the app: it needs a secret key.
A user token reaches one project and one app user, and lasts at most one hour. Its scp claim lists what it may be used for, and is ["vps"] today: user tokens are accepted by the VPS operations only, once VPS launches, and every other operation refuses them. Treat the token as opaque.
Deleting or expiring the secret key that minted a token revokes the token too. There is no other way to revoke one.
Mint only for a user your backend has signed in. If you need more protection against automated clients, your endpoint can first check App Attest (iOS), Play Integrity (Android) or Meta's attestation (Quest).
Limits, always enforced: 1,200 tokens a minute per key, and 60 an hour per key and app user. A backend can cache a token per app user until shortly before expires_at.
Your backend
Mint a token for the signed-in user and return it to the app:
const r = await fetch("https://platform.reactvision.xyz/functions/v1/app-user-tokens", {
method: "POST",
headers: { "x-api-key": process.env.RV_SECRET_KEY!, "content-type": "application/json" },
body: JSON.stringify({ project_id: PROJECT_ID, app_user_id: user.id }),
})
const { token, expires_at } = await r.json() // hand both to the signed-in app user
Your app (Viro, once VPS launches)
Viro calls credentials before every VPS request, so cache the token until it is close to expiring: