Skip to main content

Add a Policy

Add authorization for a new resource in four steps.

1. Create the Tegata

Write authz/document-access.tegata.json:

{
"tegata": "0.1",
"policy": { "id": "document-access" },
"attributes": {
"subject.user_id": "string",
"resource.owner_id": "string"
},
"rules": [
{
"id": "allow-member-access-own-document",
"effect": "allow",
"subject": { "roles": ["member"] },
"actions": ["view", "edit"],
"resource": { "type": "document" },
"relationships": [
{ "label": "ownership", "subject_attribute": "user_id", "op": "eq", "resource_attribute": "owner_id" }
]
}
]
}

relationships compare a subject attribute with a resource attribute — see the Tegata Schema for every field and the evaluation rules.

2. Update the vocabulary (if needed)

If authz/vocabulary.json exists, add any new words — undeclared ones are rejected at compile time:

{ "roles": ["member"], "actions": ["view", "edit"], "resource_types": ["document"], "attributes": {} }

3. Compile

npx ninka compile

Regenerates authz/out/, including a typed entry in types.gen.ts. See Generated Files.

4. Call check()

import { check, policies } from "@/lib/authz";

const allowed = await check(policies.documentAccess, {
subject: { properties: { roles: session.user.roles, user_id: session.user.id } },
action: { name: "edit" },
resource: { type: "document", properties: { owner_id: doc.ownerId } },
});
if (!allowed) return NextResponse.json({ error: "forbidden" }, { status: 403 });

Done.

See also