Interface: RouteMeta
Defined in: http/src/route.ts:92
What a route declares about itself for other plugins to enforce.
Open by design — the index signature keeps every existing meta compiling, and applications legitimately put their own keys here. What it adds is the shape of the keys the toolkit does know: meta: { can: 123 } is now an error, and an editor can complete the names.
Plugins declare their own keys by augmentation, the same pattern BasaltHooks uses:
declare module '@basaltkit/http' {
interface RouteMeta {
can?: string | string[]
}
}What this does NOT catch is a misspelt key: subcribed: 'pro' still compiles, because the index signature has to accept unknown names. That gap is closed at boot instead — the adapters refuse to start on a guard key with no plugin behind it, and subscriptionsPlugin refuses on a plan that is not in the catalogue.
Indexable
> [key: string]: unknown
Properties
account?
> optional account?: boolean
Defined in: auth/src/index.ts:54
The route is about the caller's own account (sign-in, profile, MFA, accepting an invitation), not a tenant's data: tenant-membership guards (@basaltkit/teams' tenantMembershipPlugin) let non-members through.
apiKey?
> optional apiKey?: boolean
Defined in: auth/src/apikeys-plugin.ts:32
false makes the route session-only: requests authenticated with an API key are refused (403 AUTH_APIKEY_NOT_ALLOWED), whatever the key's scopes. Key management and MFA routes declare it.
audience?
> optional audience?: string
Defined in: permissions/src/index.ts:87
Which surface this route belongs to — 'portal', 'public', whatever the application calls them. Enforced by permissionsPlugin when audiences is configured.
A permission is a capability, not a surface: matter:read cannot tell "read my own case in the portal" from "read the case with the litigation strategy in it". This says which one a route is.
auth?
> optional auth?: boolean
Defined in: auth/src/index.ts:43
true requires a session; false opts a route out.
can?
> optional can?: CanMeta
Defined in: permissions/src/index.ts:77
Permission(s) the caller must hold. Enforced by permissionsPlugin.
'projects:read'— an RBAC permission;{ permission: 'projects:update', resource: (input) => load(input.params.id) }— the guard loads the resource and the registered policy decides (gate.authorize(user, permission, resource)); the handler reads it back with canResource;- an array of either — ALL of them are required.
feature?
> optional feature?: string
Defined in: subscriptions/src/plugin.ts:27
Feature the plan must include.
mfa?
> optional mfa?: boolean
Defined in: auth/src/index.ts:48
true: the route requires a credential obtained with a second factor (step-up). false: exempt from authPlugin({ requireMfa }).
subscribed?
> optional subscribed?: string
Defined in: subscriptions/src/plugin.ts:25
Plan the billable must be on. Checked against the catalogue at boot.