Skip to content

Grants

A grant attaches a permission pattern to a subject with a boolean value: true is an allow, false is an explicit deny.

import type { PermissionGrant } from "vperms";
interface PermissionGrant {
permission: string;
value: boolean;
}

setPermission upserts a grant; unsetPermission removes it:

await vperms.setPermission("workspace", "user", "posts.read", true); // allow
await vperms.setPermission("workspace", "user", "posts.delete", false); // deny
await vperms.unsetPermission("workspace", "user", "posts.read"); // remove

setPermission is an upsert: calling it again with the same permission replaces the value. There is at most one grant per (subject, permission) pair.

When two grants match a requested permission with the same specificity, depth and layer, an explicit deny wins over an allow. This makes it safe to add a deny that cancels an inherited allow without removing it.

The adapter exposes the raw grants of a subject:

import { VeguiPermsMemoryAdapter } from "vperms";
const adapter = new VeguiPermsMemoryAdapter();
await adapter.grantPermission("workspace", "user", "posts.read", true);
await adapter.findSubjectGrants("workspace", "user");
// [{ permission: "posts.read", value: true }]

Grants returned by an adapter are plain data. All validation, matching, inheritance and precedence happen in the service and the core engine — never in the adapter.

Grants are attached to a subject but can be reached by its descendants. A subject inherits the grants of every id listed in its parents (plus virtual default parents). Continue with Inheritance to see how the engine walks them.