[GH-ISSUE #188] bug(permissionPolicy): denied permission reason can hide scope mismatch when a grant exists for capability #133

Closed
opened 2026-10-15 18:21:28 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @morluto on GitHub (Jul 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/188

Summary

evaluatePermission can return grant_revoked_or_consumed even when the actual failure is a scope mismatch (or other missing_* constraint), not a revoked/consumed grant.

Reproduction

  • Given a policy with at least one grant for the requested capability that is revoked/consumed (or otherwise excluded from candidates).
  • Use a request that does not satisfy that grant's scope (e.g. different root/origin/target details).
  • Call evaluatePermission.

The function currently:

  1. builds candidates by excluding revoked/consumed/expired/identity-mismatch grants,
  2. computes missing from candidates,
  3. sets reason to grant_revoked_or_consumed whenever candidates.length === 0 and there is any grant with the same capability, regardless of whether that grant covers the request.

Expected

If request constraints are not met by non-revoked grants, reason should be grant_required with actionable missing_* details.

Actual

reason can be grant_revoked_or_consumed even when no grant (including the revoked one) grants the requested capability under current constraints.

Impact

Users may be guided to revoke/consumption debugging paths while the permission is actually missing required scope roots/origins.

Reference

See src/domain/permissionPolicy.ts in evaluatePermission, around:

  • candidates filter (line ~138)
  • coveringGrant lookup (line ~156)
  • reason branch selecting grant_revoked_or_consumed (line ~172).
Originally created by @morluto on GitHub (Jul 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/188 ## Summary `evaluatePermission` can return `grant_revoked_or_consumed` even when the actual failure is a scope mismatch (or other `missing_*` constraint), not a revoked/consumed grant. ## Reproduction - Given a policy with at least one grant for the requested capability that is revoked/consumed (or otherwise excluded from `candidates`). - Use a request that does not satisfy that grant's scope (e.g. different root/origin/target details). - Call `evaluatePermission`. The function currently: 1. builds `candidates` by excluding revoked/consumed/expired/identity-mismatch grants, 2. computes `missing` from `candidates`, 3. sets reason to `grant_revoked_or_consumed` whenever `candidates.length === 0` and there is *any* grant with the same capability, regardless of whether that grant covers the request. ## Expected If request constraints are not met by non-revoked grants, reason should be `grant_required` with actionable `missing_*` details. ## Actual `reason` can be `grant_revoked_or_consumed` even when no grant (including the revoked one) grants the requested capability under current constraints. ## Impact Users may be guided to revoke/consumption debugging paths while the permission is actually missing required scope roots/origins. ## Reference See `src/domain/permissionPolicy.ts` in `evaluatePermission`, around: - `candidates` filter (line ~138) - `coveringGrant` lookup (line ~156) - reason branch selecting `grant_revoked_or_consumed` (line ~172).
bsakaguchi 2026-10-15 18:21:28 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#133
No description provided.