From 3ab497e0a76b7b05a1f6c5911378a4362918a4c5 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 7 Sep 2026 00:20:59 +0200 Subject: [PATCH] Record that pdp_digest does not authenticate the decision flex-auth reported that its response channel is unauthenticated: pins serve plain HTTP and the envelope carries no signature, so a responder knowing the published package id and version can return a well-formed allow that passes every check a consumer makes. Their framing is the useful one -- fail-closed protects against a PDP that is absent, not against one that lies. That lands directly on this engine's correspondence chain. Matching pdp_digest proves two artifacts describe one request; it proves nothing about whether the decision is genuine, and an approval whose pdp_digest matches a forged decision matches perfectly. Every input to the comparison is either sent by the caller or published by the PDP. Our doc already said what pdp_digest cannot cover but did not say this, which is the limit most easily mistaken for coverage -- the digest chain looks like it closes authenticity and does not. Stated plainly, with the fix named as the PDP's to make (FLEX-WP-0024, signing the envelope) rather than something a consumer can recover. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01PM5HnEAhokxdfcPqBNpT7D Assistant: claude-code Assistant-Model: opus Assistant-Process: 715850@bnt-lap001 Assistant-Session: eb557e93-7cb1-45d0-9e57-7d15b3edc60e --- docs/approval-claim.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/approval-claim.md b/docs/approval-claim.md index 7bf83bd..8cb0323 100644 --- a/docs/approval-claim.md +++ b/docs/approval-claim.md @@ -148,6 +148,27 @@ produces a confident wrong answer, and comparing two digests derived under different rules fails open in the direction of accepting a claim bound to a different request. +**`pdp_digest` does not authenticate the decision.** This is the limit most +easily mistaken for coverage, so it is stated plainly: matching +`claim.binding.pdp_digest` against the PDP's published digest proves the two +artifacts describe *one request*. It proves nothing about whether the decision +is genuine. **An approval whose `pdp_digest` matches a forged decision matches +perfectly** — every input to the comparison is either sent by the caller or +published by the PDP, so a responder that knows a package id and version can +return a well-formed allow that passes every check a consumer makes. + +Fail-closed protects against a PDP that is *absent*, not against one that +*lies*. The distinction matters because the digest chain looks like it closes +this and does not: a consumer that verified correspondence has verified +correspondence, not authenticity. + +Closing it is the PDP's to do, by signing the decision envelope — +`FLEX-WP-0024`, reported by flex-auth against its own interest after finding its +response channel served plain HTTP with no envelope signature. Until a signature +exists and a consumer verifies it, treat a matching `pdp_digest` as evidence +that the right request was approved, never as evidence that the decision came +from the PDP. + ### The comparison target at execute time The issue-time description above is unchanged: this engine records the