# Approval consumption (PEP) Status: engine consumer implemented; live production remains fail-closed until a durable consume binding is served. Normative protocol: `gate-house/docs/contracts/approval-consumption.md` (`GH-DEC-2026-003`). Implementation surface: `approval-engine/docs/approval-consumption.md`. This document records how secrets-engine, as the PEP for OpenBao writes, consumes that protocol. It does not redefine it. ## Sequence ```text 1. PIP GET /v1/approvals/{id}/claim 2. PDP access-engine Check / decide → ALLOW 3. PEP POST /v1/approvals/{id}/consume → CAS 4. PEP OpenBao call → only after consume succeeds ``` Every live privileged production handler passes `_require_lane_approval`, which calls `require_production_consume` before `OpenBaoClient.resolve`. Dry-run and `plan` do not consume. Build/test remain fail-open relative to approval-engine. The three-factor unsafe-demo exception is not a consume path. ## Fail closed | Condition | Result | | --- | --- | | No served consume binding | refuse; no OpenBao | | Missing `SECRETS_ENGINE_APPROVAL_URL` or token file | refuse; no OpenBao | | HTTP 409 / different digest | refuse; no OpenBao | | Same digest after consume | idempotent success; OpenBao may proceed | | 401/403/404/503/unreachable | refuse; no OpenBao | | Side effect fails after consume | approval is spent; no unconsume | The consume response is mutation evidence (`status=consumed` plus the presented digest). It is not a permission. Evidence records approval id, digest, idempotence, and consumed-at only. No token, secret, or accessor. ## What this does not do - It does not enable live production. Unreachable-engine stance still fail-closes production until an access-engine decision record is served (`SECRETS-WP-0007-T04` / `SECRETS-WP-0008-T02`). - It does not render or cache an authorization decision. - It does not infer consumption from a decision record or from local evidence.