Plugins
Permissions / Scopes
Require scopes at verify time and manage scopes per key. All requested scopes must be present on the key.
How it works
- Stores scopes in a configurable metadata field on each key (default:
"scopes"
). - On verify, if
scopes
are provided, the key must include all of them or verification rejects with"insufficient_scope"
. - Provides helpers to grant, revoke, set, and read scopes on keys.
Settings
Option | Type | Default | Description |
---|---|---|---|
metadataKey | string | "scopes" | Metadata field name used to persist scopes on a key. |
Usage
import { usefulkey } from "betterkey";
import { permissionsScopesPlugin } from "usefulkey/plugins/permissions-scopes";
const uk = usefulkey({}, {
plugins: [
permissionsScopesPlugin({ /* metadataKey?: "scopes" */ }),
],
});
await uk.grantScopes("key_123", ["read", "write"]);
const scopes = await uk.getScopes("key_123");
// Verify: ALL passed scopes must be present on the key (intersection-all)
await uk.verifyKey({ key, scopes: ["write"] });
await uk.verifyKey({ key, scopes: ["read", "write"] });
Functions added
uk.grantScopes(id: string, scopes: string | string[]): Promise<void>
uk.revokeScopes(id: string, scopes: string | string[]): Promise<void>
uk.setScopes(id: string, scopes: string | string[]): Promise<void>
uk.getScopes(id: string): Promise<string[]>
Verification behavior
- When
scopes
are provided toverifyKey
, all must be contained in the key's metadata field. - Failure →
{ valid: false, reason: "insufficient_scope" }
.
Emitted analytics:
- On block:
"scopes.blocked"
with{ keyId, userId, required, have, ts }
. - On grant:
"scopes.granted"
with{ keyId, added, result, ts }
. - On revoke:
"scopes.revoked"
with{ keyId, removed, result, ts }
. - On set:
"scopes.set"
with{ keyId, result, ts }
.