Skip to content

docs(authz): cross-service authorization — ratified decision + contract + test vectors - #79

Draft
phoebus-84 wants to merge 5 commits into
feat/atomic-propose-contributionfrom
docs/cross-service-authz
Draft

phoebus-84 wants to merge 5 commits into
feat/atomic-propose-contributionfrom
docs/cross-service-authz

Conversation

@phoebus-84

Copy link
Copy Markdown
Collaborator

What

Stacked on #77. Documents only — no code changes.

Captures the owner's ratified decisions on cross-service authorization and fixes the contract the first implementation slice will satisfy.

docs/cross-service-authz-decision.md

§7 is now Decisions taken (2026-10-14), not open questions:

  1. Direction E + D — authority in Zenflows (owns controllers/memberships/epochs); a thin PEP in each service from a shared library; one contract with shared test vectors, realized as a Go library (DPP, wallet, inbox, feedback) plus a small Elixir PDP side. The Go library is the PEP, never the PDP.
  2. Wallet issuance bound to a verified economic event — no more free AddDiff with an unbound owner.
  3. Balances are public — GET /token/... needs no authz (accepted behaviour, not a defect).
  4. Proxy stays a dumb forwarder — attaches no trusted principal; proxy work closed.
  5. First slice = the contract + authentication of the four unauthenticated DPP write handlers.

docs/cross-service-authz-contract.md

The implementation-independent contract: the authentication floor (§2), actions fixed by the handler (§3), the PDP request/response and non-negotiable properties — principal proven not header-asserted, parent from binding, fail closed (§4), and exactly what P0 ships vs. defers.

docs/cross-service-authz/

Shared test vectors both the Go PEP and the Elixir PDP suites consume:

  • authn.json — the P0 authentication floor, executable now against a PEP (stubbed VerifyDid/IsAuth).
  • contract.json — the PDP contract, marked pending until the Elixir PDP side exists (never a silent green).
  • README.md — vector schema and the runner contract.

A .gitignore entry whitelists docs/cross-service-authz/ (the repo ignores docs subdirectories by default).

Why draft / stacked

Per the standing constraint, nothing lands on main of zenflows/gui yet; this is the decision record that unblocks the first service slice (DPP write-auth), which will come as its own draft PR against the DPP repo.

Refs #74.

🤖 Generated with Claude Code

phoebus-84 and others added 3 commits October 14, 2026 18:14
…ctors

Records the owner's 2026-10-14 decisions on the cross-service authorization
direction and fixes the contract the first slice implements:

- cross-service-authz-decision.md: §7 is now "Decisions taken", not open
  questions. Direction E+D confirmed (authority in Zenflows, thin Go PEP +
  small Elixir PDP, one contract + shared vectors); wallet issuance bound to a
  verified economic event; balances public (no authz); proxy stays a dumb
  forwarder; first slice = contract + authn of the DPP writes.
- cross-service-authz-contract.md: the implementation-independent contract —
  the authn floor (§2), actions fixed by the handler (§3), the PDP
  request/response and non-negotiable properties (§4), and what P0 ships.
- docs/cross-service-authz/: shared test vectors (authn.json executable now,
  contract.json pending until the PDP exists) consumed by both the Go PEP and
  the Elixir PDP suites, plus a README with the schema and runner contract.

No code is changed by this commit. Refs #74.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…dates over the body)

The first-slice DPP work landed. Correct §5 to match what shipped: deletes are
object-bound by construction (the client signs the id the service verifies
against the path), updates are authenticated over the body with full object-id
binding deferred to the signed envelope. Names the shared helper
(authenticateWrite) and the follow-up that migrates the existing handlers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…vectors

Each contract vector now carries a `facts` block — the output the PDP's
fact-loader would produce from the database (controls_parent, epoch,
obligations, principal_proven, or a transport error). This lets the PDP's
pure decision function be driven directly by the vectors, without Postgres,
the way the Go PEP's authn vectors are stub-driven. Adds a
unknown-action-fails-closed vector so default-deny is pinned.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
phoebus-84 and others added 2 commits October 15, 2026 00:40
Specifies how the already-built Pdp decision point is exposed over the
wire and how the DPP enforcement point calls it for its four write
handlers, under the ratified contract.

- PDP transport: internal POST /authz/decide on the Plug router; a thin
  Pdp.Transport that re-verifies the user's signature itself (reusing
  Restroom.verify_graphql) and sets principal_proven from that result,
  never from a caller-supplied field; delegates to the pure Pdp.decision.
- DPP PEP -> PDP: new internal/authz package (pure request-builder +
  response-interpreter + thin HTTP client); binding.parent_id derived
  server-side from the stored DPP's ProductID; action fixed by the route.
- Trust model: PDP re-verifies user proof, no service credential, internal
  endpoint (owner's choice). Enforce now: deny/error -> 403.
- Honest limitations named: replay without the signed envelope, no service
  credential, fail-closed reach, grant coverage bounded by resource control.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…P wiring

Six bite-sized TDD tasks across two repos: pure Pdp.Transport.prepare and
the POST /authz/decide route (zenflows); pure authz request-builder/
interpreter, the PDP HTTP client, authorizeWrite and the four wired write
handlers (interfacer-dpp); env doc + draft-PR refresh. Carries the spec's
global constraints, a review-focus list pinned to task tests, and honest
notes where a property is integration-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant