With NODE_ENV=production + OpenFGA authorization and a custom (non-NHS) domain pack, object reads 500 instead of returning an authorized/empty result:
- { enzyme(id:"...") { ... } } and { enzymes { ... } } both return INTERNAL_SERVER_ERROR with extensions.openfoundry.code = "CHECK_FAILED" (retryable: true).
- The write authorization on the same store works: an action mapped to check(user, can_validate, enzyme:) correctly denies without a tuple and allows after a reviewer tuple is written.
- Writing a viewer tuple for the user/object does not resolve it — the read still 500s.
- In dev mode (authz stub) the same read queries succeed.
This points to the read-side authorization (field-level visibility check or listObjects) throwing rather than returning a boolean deny, when resolving relations for a custom domain-pack model.
Reproduce
- Prod mode; custom pack with object type enzyme (FGA relations viewer, can_validate, ...).
- Create an object via a governed action; write user: viewer enzyme:.
- Query { enzyme(id) {...} } -> CHECK_FAILED 500.
Suspected area
AuthorizationService.check / listObjects usage in read resolvers or the field-redaction path (packages/security/src/authz/authorization-service.ts, resolver generator) — likely a thrown client error surfacing as CHECK_FAILED instead of a deny.
Context
Found during a domain-pack PoC (custom genscript.bio pack). Write-side governance (create / validate / ReBAC deny→allow / immutable audit) works end-to-end; only the read path 500s.
With NODE_ENV=production + OpenFGA authorization and a custom (non-NHS) domain pack, object reads 500 instead of returning an authorized/empty result:
This points to the read-side authorization (field-level visibility check or listObjects) throwing rather than returning a boolean deny, when resolving relations for a custom domain-pack model.
Reproduce
Suspected area
AuthorizationService.check / listObjects usage in read resolvers or the field-redaction path (packages/security/src/authz/authorization-service.ts, resolver generator) — likely a thrown client error surfacing as CHECK_FAILED instead of a deny.
Context
Found during a domain-pack PoC (custom genscript.bio pack). Write-side governance (create / validate / ReBAC deny→allow / immutable audit) works end-to-end; only the read path 500s.