Bound approval transport and refuse redirects and proxies

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
tegwick 2026-10-11 16:45:18 +02:00
parent 2eb045bfbf
commit b428ffecb1
8 changed files with 552 additions and 16 deletions

View file

@ -0,0 +1,86 @@
# Approval Engine confirmation transport repair owner review
```yaml
reviewer: approval-engine-owner (agent approval-engine, codex)
decision: approved
comment: >-
Approved for bounded provider source repair only, under the persisted
APPROVAL-WP-ADHOC-2026-10-11-T02 completed preparation record in
2eb045bfbfab08ce3a642d6f0ee3800af1151873, work record SHA256
3e09a565dca3b7ffcff8bed209e39f56a158dcaa63945007a096f244b9d86088.
Review performed from approval-engine's actual checkout with its AGENTS.md
and INTENT.md loaded. Purpose, Claim Shape and Consumption Ordering require
authenticated exact approval facts and fail-closed use evidence. The unchanged
source revisions listed below fix default redirect/proxy/response/timeout and
credential-file boundaries without adding PDP semantics or execution authority.
No other owner role is reviewed. Actual admitted mediator approval:read/consume
identity, custody, server/transport origin, ingress or native request acceptance
remains unproved. This review approves no credential, grant, privileged replay,
deployment, production execution, T-06 proof or adoption closure.
```
Exact reviewed source revisions (SHA256):
- approval_engine/pep.py:
4f82931accc27cf6eb03e5266f644d117bb1bd954c4683145a630878b3c33e24
- approval_engine/http_transport.py:
ffd948f71fe12873bfc321ad3ea363065146c0cb1607b1d93e74e03875b9bfdb
- tests/test_pep.py:
ef063f10d76c79413e2e3ee932759d0364a6b31e9bae32a0aaa3e951e5e90f88
- tests/test_execution_confirmation.py:
c8c7565e52af40fc4f49a1c29705dc19be1c1d4924ca92cf72fcd884beba09e9
- tests/test_confirmation_transport.py:
b59e5f8014d89523675734072fbc3344cb135fc1d8febc57023631733aeefd02
- docs/task-execution-consumption-contract.md:
f70f764fc67d1f16e87a59ec73de8f4b4adac3985f68a1234cfd0e609d94823b
The original T01 acknowledgement and Custodian redirect counterexample are
preserved as history. The original inherited urllib transport did forward bearer
authentication across an origin change and accept redirected JSON; this repair
does not erase that failed outcome or imply an earlier native route was safe.
The default SDK transport now invokes a fixed provider source child with -I and
an empty environment. Bearer material is confined to private process pipes,
never argv or diagnostics. ProxyHandler({}) rejects environment proxy routing;
NoRedirect refuses every redirect without a second request. Returned origin and
status must match the original request and 200; content/encoding/length limits
and strict duplicate-key/nonfinite/UTF-8/object JSON parsing refuse ambiguity.
No error body is needed or exposed. The parent's bounded subprocess call can
terminate DNS/header/read/error-close hangs without signals in an application's
main thread. The fixed child does not fork descendants or retry. Threaded SDK
invocation remains supported. This is not a general sandbox or a custody-isolated
execution process: it still runs as its owner and creates no permission.
Credential reread uses non-following descriptor traversal and a bounded regular
local file read. Symlink components/final hardlinks, special files, public or
group-writable modes, unrelated ownership, oversized and malformed tokens refuse.
Current/root-owned protected group-readable files remain supported. A projected
symlink layout must be explicitly corrected by its custody owner, never followed
or replaced by an inferred provider. Source validation does not admit any real
credential path, and the subprocess timeout is the network-child bound, not a
claim that arbitrary remote filesystems or operating-system scheduling cannot
block outside that child.
Explicit opener injection remains a trusted owner test-adapter seam. It does not
provide the default child's no-redirect/no-proxy/content/deadline guarantees.
An injected urllib.urlopen must not be admitted for production authoritative
confirmation; caller-selected transport is unacceptable. HTTP support remains
for separately reviewed private estate origins and does not attest their actual
identity or substitute for a TLS/ingress/native reachability receipt.
Validation evidence for the exact hashes above: 51 new synthetic transport cases
and 270 staged full tests passed; only the existing JWT test-key warning remains.
Cross-origin GET/POST 301/302/303/307/308 received zero requests or bearer headers
at the second server; environment proxies received none; slow headers, dribbled
bodies and error bodies stopped within the local worker-thread test budget;
status/content/size/JSON/error and credential guards refused. Exceptional adapter
close raised only a closed provider error. These tests establish local source
behavior, not deployment or an actual admitted mediator runtime.
Before any protected effect, the independently admitted mediator must validate
a fresh exact approval claim and Access decision, match the returned original
consumption tuple, and persist confirmation in a separate live one-shot journal.
Timeouts remain unknown and never authorize retry. Idempotent historical use
never permits a second execution; original approval/PDP/operation deadlines
remain effective. No consumer flag, source hash, local receipt or this review
attests authority. Existing residual/native/adoption task statuses are unchanged.

View file

@ -141,3 +141,51 @@ change, wrong act/target/actor/principal/purpose/digest/decision refusal, strict
booleans/time, denied read, filtered evidence and idempotency after expiry with
terminal revoke/supersede refusal. Staged full suite: 219 passed, one existing
JWT short-test-key warning. No production HTTP/DB/OpenBao call or native action.
## Transport repair proposal after local redirect counterexample
The original source review above does not attest the inherited transport's
authoritative reachability. A later synthetic two-origin counterexample proved
that urllib's previous default followed a redirect, forwarded Authorization and
accepted its JSON. This is retained as a failed transport outcome, not rewritten
into a success. Bounded source repair is a new demand under
APPROVAL-WP-ADHOC-2026-10-11-T02, without residual promotion or native admission.
The staged default ApprovalHTTPClient transport uses the fixed provider-owned
http_transport.py child via the current Python executable with -I. Request data,
including bearer material, travels only through private process pipes, never
argv, logs or diagnostic output. The child receives an empty environment; environment proxy settings are ignored, every
redirect refuses without issuing another request, status must be exactly 200,
Content-Type must be a single application/json with UTF-8 (or no charset),
compressed/oversized/inconsistent responses refuse, and duplicate-key/non-finite/
malformed/non-object JSON refuses. Backend/error bodies are not read or exposed.
Public errors contain closed provider messages and numeric status only.
The parent's subprocess timeout covers DNS/connect/TLS/header/body/error-close
and process cleanup for the fixed child, which has no retry or subprocess
descendants. It avoids SIGALRM and multiprocessing-spawn main-guard requirements
so default SDK calls remain usable in worker threads and ordinary scripts.
The token is read from a bounded local regular file using nonblocking/no-follow
descriptor traversal: no symlink component, final hardlink, other-readable or
group-writable mode, non-current/non-root owner, FIFO/directory or oversized
credential is accepted. Restrictive current/root-owned group-readable files
(such as 0440) are permitted; unknown projected/symlink credential layouts must
be corrected by the custody owner, never silently followed or substituted.
Only ASCII non-whitespace bearer content is admitted; credential errors do not
republish paths or values. The file is reopened every request, retaining rotation.
The explicit opener injection is retained solely as a trusted owner test-adapter
seam; it does not inherit isolated/default transport admission or total deadline
guarantees. Supplying urllib.urlopen as an injected opener recreates its own
redirect/proxy behavior and must not be admitted as production execution
confirmation. Native mediator implementation must use this fixed default or a
separately reviewed equivalent; caller-selected transport code is unacceptable.
The default code still supports HTTP for reviewed private estate routes; source
validation does not prove TLS, the actual server origin, deployed custody/read
scope or ingress admission. No native identity/profile is widened.
After a timeout/refusal, consume remains potentially unknown and cannot be
retried to infer absence. Fresh exact claim/PDP validation, returned original
consumption correspondence and separate one-shot journal remain required.
This is a transport repair only, never an execution authority or replay service.