Skip to content

fix(e2e): map the verifier's grammar at its entry sites; single-source issuer/audience - #15

Merged
y1o1 merged 2 commits into
developfrom
fix/e2e-vocabulary-seams
Aug 28, 2026
Merged

fix(e2e): map the verifier's grammar at its entry sites; single-source issuer/audience#15
y1o1 merged 2 commits into
developfrom
fix/e2e-vocabulary-seams

Conversation

@y1o1

@y1o1 y1o1 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Closes #12 (parent: #11). Merge after #14 — the new comments link docs/claims-contract.md, which #14 introduces.

What

Three ownership mappings, one homonym disambiguation, one drift-pattern kill:

  1. tests/abac/application.conf — the collector pipeline (PayloadScopeCollector / PayloadSubjectIdCollector / ResourceActionScopeRuleCollector) is the provider→verifier claim mapping machinery, and now says so: each block states which module owns the vocabulary it names, in the same style as the annotated oauth.jwt block above it.
  2. tests/provider/clients.yamlread:project / read:project.member sit under the provider-vocabulary key allowedScopes but are written in the verifier's {action}:{resourceType} grammar. The header now names the grammar owner (auth.policy-verifier) vs the string owner (this registration), and marks the audience URL as the one deliberate second copy (volume-mounted, out of compose interpolation's reach).
  3. tests/shared/oauthFlow.jsverify()'s defaults (resource='project:1', action='read') and authorize()'s default scope (read:project) are two spellings of one value via the verifier's derivation rule (auth.policy-verifier#117). The invariant is now in verify()'s docblock.
  4. resource homonym — same parameter name, two protocols in one file: authorize()'s RFC 8707 indicator URI vs verify()'s dot-notation resource string. Decision: comment-only, no rename — both params mirror load-bearing wire fields exactly (the verifier 400s unknown body keys; the RFC 8707 query param is literally resource). Both docblocks now carry the disambiguation.
  5. Issuer/audience single-sourcingoauthFlow.js's fallback literals silently duplicated the compose literals, the exact two-definitions drift 4ea0484 closed for the secret. Now: one export OAUTH_JWT_ISSUER/AUDIENCE in the Makefile → ${VAR:?run via make test-e2e} in compose → requireEnv in the tests, no fallbacks.

Verification

  • node --check tests/shared/oauthFlow.js, YAML parse of clients.yaml.
  • docker compose config resolves with the Makefile-exported env and fails without it (the :?err guards work).
  • Runtime path unchanged — comments + env plumbing only. CI's e2e run is the executable check.

Note: running vitest outside make test-e2e now fails at import for issuer/audience too — intended, same doctrine the secret already had.

🤖 Generated with Claude Code

…e issuer/audience

The verifier's {action}:{resourceType} scope grammar entered this repo
at four sites but carried its ownership statement at exactly one
(tests/abac/index.test.js). The other three absorbed it silently:

- tests/abac/application.conf: the collector pipeline — the actual
  provider→verifier claim mapping — had zero comments while the
  oauth.jwt block above it was fully annotated. Each block now states
  which module owns the vocabulary it names.
- tests/provider/clients.yaml: read:project / read:project.member sit
  under the provider-vocabulary key allowedScopes but are written in
  the verifier's grammar. The header now says who owns the grammar and
  who owns the strings.
- tests/shared/oauthFlow.js: verify()'s defaults and authorize()'s
  default scope are two spellings of one value via the verifier's
  derivation rule (auth.policy-verifier#117); the invariant is now in
  verify()'s docblock.

Also flagged the resource homonym in both docblocks: authorize()'s
resource is the RFC 8707 indicator URI, verify()'s is the verifier's
dot-notation resource string. Both mirror their wire fields exactly, so
neither is renamed — the comment is the fix.

And killed the last two-definitions drift: ISSUER/AUDIENCE fallback
literals in oauthFlow.js duplicated the compose literals — the exact
pattern 4ea0484 closed for the secret. Both are now exported once from
the Makefile, interpolated into compose with :?err guards, and read via
requireEnv with no fallback. The clients.yaml audience stays as the one
deliberate copy (volume-mounted, out of interpolation's reach) and says
so.

Verified: node --check, YAML parse, compose config resolves with the
Makefile env and fails without it. Runtime path unchanged — comments
plus env plumbing only; CI's e2e run is the executable check.

Closes #12

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 28, 2026 12:19

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the maintainability of the cross-component E2E suite by (1) documenting where the policy-verifier’s scope/resource grammar enters the umbrella tests, and (2) eliminating issuer/audience literal drift by single-sourcing JWT env values via the Makefile → compose interpolation → test-process env requirements.

Changes:

  • Single-source OAUTH_JWT_ISSUER / OAUTH_JWT_AUDIENCE alongside OAUTH_JWT_SECRET (Makefile exports, compose :? guards, tests require env with no fallbacks).
  • Add ownership/grammar mapping comments at the verifier-grammar entry sites (application.conf, clients.yaml, and oauthFlow.js), including disambiguation of the resource homonym (RFC 8707 vs verifier /verify body field).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/shared/oauthFlow.js Removes issuer/audience fallbacks, adds verifier-grammar invariant + resource homonym documentation.
tests/provider/clients.yaml Documents that allowedScopes strings are written in the verifier’s {action}:{resourceType} grammar and calls out the deliberate audience “second copy”.
tests/docker-compose.yml Switches issuer/audience to required compose interpolation (${VAR:?…}) to prevent drift.
tests/abac/application.conf Annotates the collector pipeline as provider→verifier claim mapping and documents vocabulary ownership.
Makefile Exports OAUTH_JWT_ISSUER / OAUTH_JWT_AUDIENCE as the single source of truth for compose + test processes.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/shared/oauthFlow.js
…Makefile as source of truth

The message still said make test-e2e 'exports it from
tests/docker-compose.yml'; compose only interpolates the values now,
the single definition is the Makefile's export block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@y1o1
y1o1 merged commit d963dea into develop Aug 28, 2026
1 check passed
@y1o1
y1o1 deleted the fix/e2e-vocabulary-seams branch August 28, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[test/docs] The verifier's scope grammar enters at four sites but is mapped at one — plus a resource homonym and duplicated issuer/audience literals

2 participants