Task: Refuse a token with no permissions

Table of Contents

This page documents a task in the Give a person's token the permissions they hold story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

A token that grants nothing is refused, and every permission check uses one matching rule, as the story's decisions 4 and 5 say. The party-choice token is refused everywhere but party selection.

2. Status

Field Value
State DONE
Parent story Give a person's token the permissions they hold
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-03

3. Acceptance

  • has_permission refuses a token with an empty permission list, and both checks use one matching rule that understands * and x::*.
  • Only a named constructor builds a context with no permission list.
  • A service's request context refuses a token with the select_party_only audience, which no signer or verifier rejects today.
  • Every new behaviour is proved by a test.

4. Plan

(Implementation strategy. Written when work starts; key decisions are distilled into the parent story's * Decisions at close, but the plan itself stays — it is the historical record of what we did.)

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
       

6. Notes

7. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario) that verify this task. Link new ones here as they're created; the scenario doc itself links back via its "Verifies task" field.

Scenario State Notes
     

8. PRs

PR Title
#2565 [service] Refuse a token with no permissions

9. Review

Comment summary File Decision Notes
       

10. Result

has_permission refuses a token whose permission list is empty. The database context's list became optional: a context built from a token carries the token's list, and a context with no list, which only context_factory builds for a service's own work, passes. with_tenant and with_party now keep the list they narrow, so a request's context is never trusted for want of one. grants in ores.security is the one matching rule, understanding a code, * and x::*, and both has_permission and authorization_service::check_permission use it; the database check no longer needs a sorted list and now honours component wildcards. make_request_context refuses the select_party_only audience by name, because no signer or verifier sets an audience.

Tests: five cases for grants; has_permission refusing an empty list, passing the service's own context, and narrowed contexts keeping their list; the request context refusing the party-choice token. The full build is clean with no warnings. The full ctest failed 5 suites on a database built before main added tables and columns (sandbox_id, curve_configurations and others); all five pass on a recreated database (refdata 286, trading 127, ore 637, reporting 49, analytics 53), as do service 46, iam 192 and security 64 under ctest. Live, with the probes in evidence/: the party-choice token is refused a parties read and refresh, the same session reads 5 parties after choosing a party, and the tenant live check passes 15 of 15 (evidence/refuse_task_live.out).

Emacs 29.3 (Org mode 9.6.15)