Context
AuthZ checks currently live in the data layer (DB methods in postgres.go). This means any internal system caller (seed imports, deployment state updates, background tasks) must wrap its context with WithSystemContext to avoid 403s. This pattern is fragile — a missing WithSystemContext silently fails in production.
Proposal
Move AuthZ checks from the data layer to the API layer (handlers/middleware).
Addendum: We should likely move it to the service layer internal/registry/service/
This way:
- API traffic is still enforced through AuthZ
- Internal system callers access the DB directly without needing auth bypass
We originally placed AuthZ at the data layer to prevent accidentally exposing un-gated handlers. This tradeoff should be weighed against the existing fragility. Missing handler/service-layer gates are easily catchable through tests and code review, while missing WithSystemContext calls can surface as silent runtime failures.
Example
When writing to a resource (permission write), we have a side effect of doing version lookups (permission read). A user with only write permission gets 403'd because the DB method internally requires read as well.
Moving the check to the API layer would let us check based on the actual user action (the HTTP method + resource path), not internal implementation details.
Context
AuthZ checks currently live in the data layer (DB methods in postgres.go). This means any internal system caller (seed imports, deployment state updates, background tasks) must wrap its context with WithSystemContext to avoid 403s. This pattern is fragile — a missing WithSystemContext silently fails in production.
Proposal
Move AuthZ checks from the data layer to the API layer (handlers/middleware).
Addendum: We should likely move it to the service layer
internal/registry/service/This way:
- API traffic is still enforced through AuthZ
- Internal system callers access the DB directly without needing auth bypass
We originally placed AuthZ at the data layer to prevent accidentally exposing un-gated handlers. This tradeoff should be weighed against the existing fragility. Missing handler/service-layer gates are easily catchable through tests and code review, while missing
WithSystemContextcalls can surface as silent runtime failures.Example
When writing to a resource (permission
write), we have a side effect of doing version lookups (permissionread). A user with onlywritepermission gets 403'd because the DB method internally requiresreadas well.Moving the check to the API layer would let us check based on the actual user action (the HTTP method + resource path), not internal implementation details.