Register Permissions
When implementing a new Prisma model or guarded Nest route in this
repo, register the matching {resource}:{action} in the permissions catalog.
Do not ship the route until the drift check is green.
Canonical checklist (commands, artifacts, deploy):
docs/permissions.md.
AuthZ stays in the Permissions pillar (Check(subject, action, resource) →
OpenFGA). Coarse Entra roles (@Roles) stay in SingleSignOn. Do not embed
AuthZ rules in Contact/Tenant/etc.
When this skill applies
Run it if any of these is true:
- New Prisma model / table that will be a guarded resource
- New or changed Nest controller method that
PermissionsGuardshould authorize - New HTTP
METHOD+ Nestroute.paththat is not already ininfra/openfga/permissions.manifest.json
Skip when the change is docs-only, CI-only, or a public unauthenticated route that is intentionally not in the catalog.
Register
Dry-run first, then apply (from the repo root):
pnpm permissions:register -- --method PATCH --path /contacts/:id \
--action update --resourceType contact --resourceIdParam id
pnpm permissions:register -- --apply --method PATCH --path /contacts/:id \
--action update --resourceType contact --resourceIdParam id
--path must match Nest route.path (not the global /api prefix).
--resourceIdParam is the path param OpenFGA uses as the object id.
This updates both copies of permissions.manifest.json, appends a define
(or new type) in infra/openfga/model.fga, and best-effort patches
infra/openfga/model.json. Do not hand-edit a private mapPermission in
PermissionsGuard.
Done
pnpm permissions:checkexits 0 (CIci-api.ymlruns the same check).- Manifest has an entry for the guarded
METHOD+ Nestroute.path. actionexists onresourceTypeinmodel.fga.- When infra is available, push the model (
infra/deploy-openfga.ps1— seedocs/permissions.md).
A PR that adds a guarded route without a catalog entry is not done.
Related
docs/permissions.mdengineering/backend— Nest/Prisma baselinepillars/permissions/README.md