Feature flags from the token
Turn features on by plan, entitlement, org, role or user, roll out by percentage and switch off in one click; your API and your UI read flags offline from the token.
- You get
- Features switched on by plan, organisation, role or percentage, read offline from the token in your API and your UI.
- For
- Backend developer, Frontend developer, Founder
- Time
- About 20 min
- Products
- Feature flagsBillingOrganisations and roles
Flags live per environment in the dashboard (Flags). A flag has a type (on/off, text, a number or JSON), a default, an on/off switch and rules. Your API and your browser app evaluate them offline, from the user's token and the environment's rules, which the SDK caches like signing keys.
1. Declare your flags
One file, shared by the API and the UI, like your roles. Keys and values are typed, and each flag has the default used until the environment has it:
import { defineFlags } from '@anchring/auth';
export const flags = defineFlags({
'new-editor': { default: false },
theme: { default: 'classic', variants: ['classic', 'compact'] },
});2. Read them
// API (Hono): from the verified token, offline
const auth = createAuth({ project: 'acme', env: process.env.AUTH_ENV ?? 'test', audience: 'acme-api', flags });
app.get('/api/editor', auth.guard({ flag: 'new-editor' }), handler);
const theme = await auth.flag('theme', c.var.user); // 'classic' | 'compact'
// Your own attributes (not in the token), for rules on "Attribute project"
const beta = await auth.flag('new-editor', c.var.user, { attributes: { project: 'acme' } });
// Browser: the signed-in user
const auth = createAuth({ project: 'acme', env: 'test', clientId: 'test_…', flags });
if (await auth.flag('new-editor')) showNewEditor();
const all = await auth.flags(); // every flag at onceauth.flag never throws: without the environment's rules (or for an unknown key) it gives the default. auth.guard({ flag }) answers 403 when the flag is off for the caller (denyStatus: 404 hides the route).
3. Target with rules
Rules are checked from the top, and the first that matches gives the value. A condition reads the token: plan, entitlement, billing status or country, the active organisation and the user's role in it, app roles, the user id, the email domain or any claim. Put what you target in your app's claims template, for example "billing": "{{billing}}" and "org": "{{org}}".
A rule's rollout slider gives the value to a share of the users it matches. The share is fixed per user (a hash of the flag key and the user id), so raising 20% to 30% keeps everyone already in. Roll out by organisation to move whole organisations together. The preview on the flag's page shows what a user with given claims gets, before you save.
4. Switch off
Turning a flag off gives everyone its default: the kill switch. Changes reach your apps within about 30 seconds (the rules' cache time), and every change is in the flag's change log with who made it and what it was before. From an alert or CI, use a server key with flags:write:
import { createAdminClient } from '@anchring/auth/admin';
const admin = createAdminClient(); // ANCHRING_PROJECT, ANCHRING_SERVER_KEY
await admin.flags.update('new-editor', { enabled: false });Going live
Promote to production copies flags and their rules. A new flag arrives switched off in production, and an existing one keeps its production switch. User and organisation ids differ between environments, so the preview points out rules that name them.
Every option, error and token type: the SDK README.