Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 994874@bnt-lap001 Assistant-Session: 6017c416-d619-47eb-bd1a-f670a02d7d87
7.5 KiB
Bounded Execution Admission and the PDP — access-engine owner answer
Answer to NetKingdom NK-WP-0056-T02 (owner request
net-kingdom/docs/proposals/2026-10-31-nk56-t02-owner-requests.md, section
"access-engine"), for the proposed standard
net-kingdom/canon/standards/bounded-execution-admission_v0.1.md (BEA v0.1).
Date: 2026-10-31. Status: owner answer and proposal. The founder and the named
owners decide; nothing here is enabled or deployed.
Follow-on work: workplans/FLEX-WP-0040-bounded-execution-pdp-gate.md.
What exists today (from source)
| Fact | Evidence |
|---|---|
| access-engine is the estate's only PDP and validates approvals as input claims; it never owns, mutates or consumes the approval object | SCOPE.md (One-liner, Out of Scope: approval object is approval-engine's) |
A typed task-execution path exists on /v1/check. It requires TokenReview caller mapping, a fixed owner-installed Approval reader (GET /v1/approvals/{UUID}/claim, no consume) and original/fresh claim correspondence before policy runs |
docs/trusted-service-task-source.md, internal/taskexecution/approval_source.go, internal/taskexecution/service_input.go |
That path is hard-wired to one consumer: subject secrets-engine, transport principal system:serviceaccount:secrets-engine:secrets-engine, contract SECRETS-EXEC-20261011-v1, operation metadata-apply-ccr, exactly six OpenBao operations |
examples/secrets-engine-service-task-execution-v2/policy_package.md (status proposed) |
The v2 policy requires approval.consumed == false at decision time |
same file, candidate_matches |
The older secrets-engine apply rule ignores execution_contract content: an allow there is not exact task authority |
internal/policy/secrets_execution_gap_test.go (gap characterization test) |
| The Approval claim adapter carries id, native binding and PDP digest; it carries no approver assurance level | third_party/approvalfact (pinned copy of approval-engine/adapters/go/approvalfact/claim.go) |
Human callers on the typed path must present aal2 + MFA from key-cape, at most 300 s old; that is the caller's assurance, not the approver's |
internal/taskexecution/identity.go |
| No chart, runtime admission or credential custody is enabled for the typed path | docs/trusted-service-task-source.md |
So the mechanics a BEA gate needs exist in one consumer-specific shape. There
is no bounded-execution action, no namespace for admissions, no caller mapping
for service:nk-bind-executor, and no evaluator for BEA's scope_ceiling or
plan.steps.
Q1 — Should a PDP decision gate executor operations?
Answer: yes, in scope, recommended for production; not required for the pilot.
A decision "executor X may run operation O on target T under admission A" is the kind of decision this repository exists to make (SCOPE: estate's only PDP), and reading the admission as an approval claim through approval-engine matches the existing boundary (approval-engine owns the object, access-engine validates it as input). It adds what local enforcement cannot: an independent evaluator outside the executor's own code, a signed decision record per step with policy version and request digest, and a single place to revoke or narrow executor authority across admissions.
Two shape points we propose (they change the request NetKingdom sketched):
- Two decisions, not one per step against an unconsumed claim. The current
typed path demands
consumed == false. BEA consumes once before the first step (BEA-C6/C7). Proposed:start— before consume: claim valid, unconsumed, approver human/aal2, executor == admission executor, now insidewindow, admission digest matches the claim's target. ALLOW is the precondition for the consume call.execute-step— after consume: claim consumed exactly once, by this executor, inside the window; the step id, operation, target and requiredmode/scopematch the digested plan and lie insidescope_ceiling. This needs approval-engine to exposeconsumed_byandconsumed_atin the claim (question for approval-engine, alongside NK's question 3).
- The PDP never consumes. Consume stays the executor's call to
approval-engine, as today (
approval_source.go: "no policy, retry, consume or effect lives here").
Q2 — What is needed, who owns it, timeline
| Item | Status | Proposal |
|---|---|---|
Action vocabulary start, execute-step on resource type bounded-execution-admission, system net-kingdom |
needs change | access-engine adds; vocabulary only, no allow |
Typed path generalised from the single secrets-engine mapping to an owner-installed caller map (first entry system:serviceaccount:sso:nk-bind-executor → service:nk-bind-executor) |
needs change | access-engine; keeps the existing secrets-engine behaviour byte-identical |
Admission input: the executor submits the admission document; access-engine recomputes its digest and requires equality with the claim's target.admission_digest |
needs change | access-engine; canonical digest rule must match NK's BEA digest definition |
execution_contract coverage: evaluate step id/operation/target/mode/scope against plan.steps and scope_ceiling, plus window and blast-radius (max_concurrent) |
needs change | in the new pack; the old apply gap (see test) is not reused and stays characterised |
Approver assurance aal2 (BEA-C4) |
missing input | approval-engine must carry approver assurance in the claim; access-engine will not infer it |
consumed_by / consumed_at in the claim |
missing input | approval-engine |
Policy pack net-kingdom.bounded-execution |
proposal | Pack mechanics and fixtures: access-engine. Semantic content (what a ceiling admits): NetKingdom as BEA standard owner, reviewed by gate-house for authority ceilings. Founder to confirm owner |
| Deployment of a pin serving the pack, caller trust, Approval reader credential | gated | founder/platform admission, as for every pin; not in this workplan's authority |
Timeline (proposal). Source work (vocabulary, generalised caller map,
pack with fixtures, DENY-by-default until inputs exist) can be done in about one
to two weeks of repository work once approval-engine answers the claim-field
questions. It lands as proposed, evaluated only in tests. A live gate follows
FLEX-WP-0039 (per-pin readiness and policy import) and a founder rollout
decision. Realistic: source-ready mid/late November 2026, live after the pilot.
It does not block the pilot window in the BEA example (2026-11-03).
Q3 — Pilot with local enforcement only
Answer: acceptable, with conditions.
- The executor's validator (BEA-C1..C7 against the carrier) plus a namespaced Kubernetes Role and narrowly scoped OpenBao/LLDAP credentials are the enforcement for T06. That is a consumer-side PEP and is the consumer's to own.
- The pilot must not claim PDP gating. Its receipt should state the PDP
decision as
not-evaluated(no decision id), so later evidence cannot be mistaken for a flex-auth ALLOW. - Do not call the existing secrets-engine
applyrule or the generic/v1/checkas a stand-in: the former ignoresexecution_contract, the latter refuses task execution. - When the gate goes live, the executor's stance on PDP unavailability is fail-closed (declared by the consumer, per SCOPE "Out of Scope: fail-open").
- Revisit after the pilot: the second admission should not run without the PDP gate unless the founder records an explicit exception.