Document exact native signer and CLI admission requirements
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
This commit is contained in:
parent
ff1a13dabd
commit
5a2099f400
6 changed files with 351 additions and 36 deletions
|
|
@ -23,20 +23,20 @@ $ getent hosts this-service-does-not-exist.flex-auth.svc.cluster.local
|
||||||
`*.svc.cluster.local` name answers with one unrelated public address. Sending
|
`*.svc.cluster.local` name answers with one unrelated public address. Sending
|
||||||
there ships the CheckRequest body and our bearer token to a third party.
|
there ships the CheckRequest body and our bearer token to a third party.
|
||||||
|
|
||||||
`flex-auth.decision-record.v1` supports a detached Ed25519 signature on the
|
As of source `ff1a13d` (2026-10-16), this consumer requires the producer's
|
||||||
producer side (FLEX-WP-0024), but this consumer does not yet verify it against
|
detached Ed25519 signature using independently admitted local keys and exact
|
||||||
independently admitted keys. Without that verification, every binding digest
|
signed evaluator/mode/policy pin. The complete CLI wheel-plus-helper bundle and
|
||||||
is either sent by us or published in flex-auth's repo, so a forger can
|
strict task handoff are implemented in source. Native signer custody, key/pin
|
||||||
reproduce those digests. Digests establish integrity of the binding, never
|
admission, installed placement and actual consumer receipts remain unaccepted;
|
||||||
authenticity of the source. As flex-auth put it in `FLEX-DEC-2026-010`:
|
source enforcement does not establish those facts. See
|
||||||
|
[the scoped native preparation](proposals/native-cli-admission/README.md).
|
||||||
|
|
||||||
> Fail-closed protects against a PDP that is ABSENT, not against one that LIES.
|
Historical 2026-10-12 finding: prior consumer source did not verify producer
|
||||||
|
signatures, so a forger could reproduce public request digests. The literal
|
||||||
The literal loopback address restriction limits the destination; it does not
|
loopback address restriction limited the destination and did not prove responder
|
||||||
prove responder identity. The operator must verify the cluster and named pod
|
identity. That source defect is repaired; FLEX-DEC-2026-010's historical warning that an absent
|
||||||
behind the port-forward. Signed consumer enforcement, independently admitted
|
PDP and a lying responder require different controls remains relevant. The
|
||||||
verification keys, rotation and downgrade tests remain open in SECRETS-WP-0014
|
independently admitted native trust and rollout obligations in SECRETS-WP-0014 T02/T03 remain open.
|
||||||
and Custodian G13. Producer support alone does not close that gap.
|
|
||||||
|
|
||||||
The Check client disables automatic redirects, environment/system proxies and
|
The Check client disables automatic redirects, environment/system proxies and
|
||||||
the process-global urllib opener. A 3xx response fails closed without contacting
|
the process-global urllib opener. A 3xx response fails closed without contacting
|
||||||
|
|
@ -51,9 +51,12 @@ apply when the approval flow invokes the PDP client.
|
||||||
Regression tests use disposable local HTTP servers and synthetic credentials;
|
Regression tests use disposable local HTTP servers and synthetic credentials;
|
||||||
they do not demonstrate identity or signature verification on the native pin.
|
they do not demonstrate identity or signature verification on the native pin.
|
||||||
|
|
||||||
## The supported path
|
## Historical transport procedure and current admission gate
|
||||||
|
|
||||||
Use literal loopback `kubectl port-forward` to the admitted named pod after
|
The following transport example records the earlier supported access shape; it
|
||||||
|
is incomplete for current native use without independently admitted signing trust,
|
||||||
|
the reviewed CLI bundle and exact owner configuration. It grants no token mint,
|
||||||
|
installation or live action. Use literal loopback `kubectl port-forward` to the admitted named pod after
|
||||||
verifying the cluster identity and pod identity. That path rides the Kubernetes
|
verifying the cluster identity and pod identity. That path rides the Kubernetes
|
||||||
API server's TLS with the operator's cluster credentials; the client cannot infer
|
API server's TLS with the operator's cluster credentials; the client cannot infer
|
||||||
that binding from its local URL. Note this
|
that binding from its local URL. Note this
|
||||||
|
|
@ -92,8 +95,10 @@ false` and no role bindings — it exists to be a caller identity and nothing el
|
||||||
|
|
||||||
v1 shipped and was deployed with no `input.tenant` rule at all; a `rotate` under
|
v1 shipped and was deployed with no `input.tenant` rule at all; a `rotate` under
|
||||||
`tenant:coulomb` returned **allow**. v2 supersedes rather than amends it so the
|
`tenant:coulomb` returned **allow**. v2 supersedes rather than amends it so the
|
||||||
change is visible in the version string, and this engine refuses a v1 decision
|
change is visible in the version string. Current consumer configuration and signed
|
||||||
outright. See `docs/tenant-alignment.md`.
|
trust must explicitly pin the admitted v2 artifact; the validator does not impose
|
||||||
|
a universal hard-coded package/version default. A v1 configuration is not admitted
|
||||||
|
by this proposal. See `docs/tenant-alignment.md`.
|
||||||
|
|
||||||
## The digest join, and why it is not a digest comparison
|
## The digest join, and why it is not a digest comparison
|
||||||
|
|
||||||
|
|
@ -114,19 +119,18 @@ and the fix follows it rather than inventing one:
|
||||||
> statement of what it hashed. To recompute independently, hash the same
|
> statement of what it hashed. To recompute independently, hash the same
|
||||||
> normalized tuple the binding carries.
|
> normalized tuple the binding carries.
|
||||||
|
|
||||||
`validate_decision_envelope` now does exactly that:
|
The bullets in earlier revisions described the September structured-enrichment
|
||||||
|
check. Current source has since moved to the producer's submitted-request replay
|
||||||
|
contract: `validate_decision_envelope` validates the exact submitted digest,
|
||||||
|
opaque enriched digest shape, approval-free correspondence, policy pin and
|
||||||
|
lifetime on an authenticated envelope. It does not independently reconstruct the
|
||||||
|
full enriched tuple or native five-field claim in the generic CLI path.
|
||||||
|
|
||||||
- **Structured correspondence.** Everything we proposed — tenant, action,
|
The separate strict `task_execution_handoff` additionally recomputes the evaluated
|
||||||
context, `subject.id`/`type`, `resource.id`/`type`/`system` and every
|
and approval-free digests, verifies exact descriptor/context/native claim joins
|
||||||
attribute we sent — must survive unchanged in the binding.
|
(including the served native digest), and binds signed enforced caller provenance.
|
||||||
- **Enrichment only where the contract permits it.** A ref may gain `type`,
|
That source seam is not an `execute-ccr` CLI command and does not admit the proposed
|
||||||
`tenant` and `attributes`; any other added field is refused. An enriched
|
service caller mapping or enable either task policy's runtime false gate.
|
||||||
`tenant` must be the request's tenant, so a cross-tenant binding cannot arrive
|
|
||||||
wearing our request's clothes.
|
|
||||||
- **Digest self-consistency.** `request_digest` is recomputed over the
|
|
||||||
normalized tuple the binding carries, per the contract's own instruction. It
|
|
||||||
is still checked — just for coherence of the binding rather than against
|
|
||||||
material we never sent.
|
|
||||||
|
|
||||||
The lesson worth keeping: the replay fixtures could not catch this, because
|
The lesson worth keeping: the replay fixtures could not catch this, because
|
||||||
`_request_from()` rebuilds the request from the binding, so the tests hashed the
|
`_request_from()` rebuilds the request from the binding, so the tests hashed the
|
||||||
|
|
|
||||||
158
docs/proposals/native-cli-admission/README.md
Normal file
158
docs/proposals/native-cli-admission/README.md
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
# Native CLI signer and consumer admission preparation
|
||||||
|
|
||||||
|
This proposal covers the existing lifecycle CLI authentication path under
|
||||||
|
SECRETS-WP-0014. It grants no installation, key retrieval, caller mint, approval
|
||||||
|
consume, OpenBao effect or task-policy activation. All native acceptance counts
|
||||||
|
below are zero. Exact missing owner inputs are in `proposal.json`.
|
||||||
|
|
||||||
|
## Current consumer and initial scope
|
||||||
|
|
||||||
|
At source `ff1a13d`, the workstation has the repository's editable v0.1.0 CLI
|
||||||
|
entrypoint at `/home/worsch/secrets-engine/.venv/bin/secrets-engine`, importing
|
||||||
|
`secrets_engine.cli:main`. There is no global `~/.local/bin/secrets-engine` or uv
|
||||||
|
managed Secrets tool. Presence-only inspection of this session found none of the
|
||||||
|
PDP/trust/approval/policy/configuration variables set. This says nothing about
|
||||||
|
other sessions, private owner configuration or a remote installation. No credential
|
||||||
|
file, private configuration or process environment was inspected.
|
||||||
|
|
||||||
|
Use a separately reviewed immutable wheel-plus-verifier bundle for proposed
|
||||||
|
adoption. The canonical source for the candidate build is **ff1a13d**, containing
|
||||||
|
both CLI packaging and strict R2 handoff; earlier c80-based proof bundles are
|
||||||
|
intermediate source evidence. Custodian `decision-native-preparation/` retains the
|
||||||
|
exact canonical bundle manifest and hashes. Nothing was installed by this step.
|
||||||
|
|
||||||
|
Initial stage is signer-only existing lifecycle-pin admission plus offline
|
||||||
|
verification of captured native signed allow and deny records. Capturing those
|
||||||
|
records later needs its own admitted caller and exact source operation; this
|
||||||
|
proposal does not grant that capture. Use Access's one receipt verifier,
|
||||||
|
`tools/verify_native_signer_receipt.py`, with its reviewed admission file rather
|
||||||
|
than creating another consumer verifier or canonicalization implementation.
|
||||||
|
That tool is separate Access source preparation; its exact integrated revision
|
||||||
|
and reviewed admission file remain owner inputs, not part of this CLI install.
|
||||||
|
|
||||||
|
The producer-owned offline pin is `secrets-engine.catalog-lane.lifecycle` v2,
|
||||||
|
`sha256:bd11c5fe77ce6439c65fea225ad6b71d2110efc5e7b5bc9b499c59cd0a53b8b4`,
|
||||||
|
evaluator `flex-auth/local`, mode `standalone`. A source digest is not proof of the
|
||||||
|
live image's source or policy. Access's live metadata records the current pin has
|
||||||
|
no signer arguments/mounts; no production kid/public key/fingerprint/custody
|
||||||
|
receipt or candidate signed-runtime OCI digest is admitted. The proposed signer
|
||||||
|
custody route is draft/nonresolvable. Do not fill those gaps from fixture keys or
|
||||||
|
from the same responder's keys endpoint. The independent receipt must bind signer
|
||||||
|
purpose/custody to this exact consumer pin and declare any sharing. A shared key
|
||||||
|
plus the generic evaluator name cannot prove an individual pod's identity; the
|
||||||
|
owner-bound tunnel and rollout identity still require separate verification.
|
||||||
|
|
||||||
|
`lifecycle-trust.template.json` uses the existing runtime trust schema and the
|
||||||
|
producer-owned source pin, but deliberately has an empty key map. It **must
|
||||||
|
refuse** before caller credential access. It is not a deployable trust file. A
|
||||||
|
future owner-admitted copy must contain the independently authenticated actual
|
||||||
|
kid/key and exact pin, with its public-key fingerprint/custody provenance retained
|
||||||
|
outside this unadmitted template. The task-policy coordinate is not admitted here.
|
||||||
|
|
||||||
|
## Exact PEP denominator
|
||||||
|
|
||||||
|
The initial shared authentication implementation is one Check client reached
|
||||||
|
through `authorize_action` and `_require_lane_approval`. Native protected-effect
|
||||||
|
coverage remains **0 of 11 serving CLI call sites across 10 handlers**, not one
|
||||||
|
PEP per catalog row. The current lifecycle policy's action vocabulary has twelve
|
||||||
|
values; that is a separate count from handler/call-site coverage.
|
||||||
|
|
||||||
|
| CLI path | Handler / delegated authorization site | PDP action |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| apply, live only | `cmd_apply` | apply |
|
||||||
|
| provision | `cmd_provision` | provision |
|
||||||
|
| rotate, live only | `cmd_rotate` | rotate |
|
||||||
|
| verify | `cmd_verify` | verify |
|
||||||
|
| handoff | `cmd_handoff` | handoff |
|
||||||
|
| wrap | `cmd_wrap` | wrap |
|
||||||
|
| exec primary | `cmd_exec`, primary gate | exec |
|
||||||
|
| exec companion | `cmd_exec`, delegated companion gate | exec for each companion; separate claim/CAS, same call site |
|
||||||
|
| revoke, live only | `cmd_revoke` | deactivate |
|
||||||
|
| lifecycle compromise/reactivate, live only | `_cmd_lifecycle_state` | selected compromise/reactivate; local state mutation |
|
||||||
|
| lifecycle suspend/deactivate/destroy, live only | `cmd_lifecycle` | selected operation |
|
||||||
|
|
||||||
|
`session revoke` is a separate stance/readiness-controlled backend path without
|
||||||
|
this served Check/CAS chain; it is excluded from this signer acceptance and still
|
||||||
|
refuses production under its stance. `service-auth probe-openbao` is an explicit
|
||||||
|
identity/login-self probe, not protected task adoption. `route` performs existing
|
||||||
|
backend readiness metadata probes through its ambient backend resolver; it is not
|
||||||
|
closed by this signer proposal. Dry-run/plan/catalog/audit/source evidence commands
|
||||||
|
are not protected-effect proof. These exclusions must remain visible in any claim
|
||||||
|
about the whole repository's PEP coverage.
|
||||||
|
|
||||||
|
The existing CLI handlers still use the generic `require_production_consume`
|
||||||
|
response contract. Strict R2 task consumption is a separate owner API, not a
|
||||||
|
retrofit of all eleven CLI sites. Native effect acceptance must review the actual
|
||||||
|
selected handler/consume contract and caller scope rather than borrow the task
|
||||||
|
fixture proof.
|
||||||
|
|
||||||
|
No production effect is authorized merely because a handler shares the signed
|
||||||
|
client. In particular, configured `service-jwt` still refuses protected CLI work
|
||||||
|
before approval/CAS/backend because CCR38 is identity-only. Do not select
|
||||||
|
bootstrap/env, alter the stance or enable unsafe-demo to manufacture acceptance.
|
||||||
|
|
||||||
|
## Owner-controlled placement and minimum configuration
|
||||||
|
|
||||||
|
The deploying owner must select the runtime UID, fresh release prefix, configuration
|
||||||
|
parent and exact runtime paths; none is agreed by this proposal. The future
|
||||||
|
admitted executable is `<prefix>/bin/secrets-engine`, whose wrapper fixes the
|
||||||
|
bundle helper and checks its digest before CLI import. The helper's source/binary
|
||||||
|
hash is artifact integrity, not independent package or key admission. Do not use
|
||||||
|
the editable checkout, a rolling alias, a synthetic test prefix or an internal
|
||||||
|
venv entrypoint as if it were that admission.
|
||||||
|
|
||||||
|
Explicit absolute owner-admitted catalog, policy, `SECRETS_ENGINE_PEP_STANCE`,
|
||||||
|
trust and evidence/outbox locations are needed. Installed-package defaults fall
|
||||||
|
back to working-directory metadata and are not an admitted native configuration.
|
||||||
|
The total existing stance remains prod fail_closed. Config needs the exact
|
||||||
|
producer policy/version, service subject, loopback owner-bound PDP tunnel and
|
||||||
|
separately admitted bounded audience `flex-auth` caller-file lifetime. Approval
|
||||||
|
endpoint and its existing separately scoped credential delivery must be admitted
|
||||||
|
independently. Both approval credential providers may not be configured together.
|
||||||
|
The bundle helper is not selected by an ambient override. Runtime credentials and
|
||||||
|
keys are not placed in this proposal or release bundle.
|
||||||
|
|
||||||
|
Acceptance order is: admit exact package/source/install/config; obtain independent
|
||||||
|
signer/key/pin custody return and exact signed producer rollout candidate; under
|
||||||
|
that separately reviewed rollout capture bounded native records; run Access's
|
||||||
|
single offline receipt verifier against the fixed installed helper and admitted
|
||||||
|
trust; prove forged/altered/unknown/unsigned/wrong-pin/expired refusal and exact
|
||||||
|
old/new-key overlap then removed-key refusal. Also close the producer's missing
|
||||||
|
native durable log/outbox/audit path under its owner. No install or rollout is
|
||||||
|
performed here, and shared-source tests do not fill native effect coverage.
|
||||||
|
|
||||||
|
Rollback retains the reviewed signed producer and admitted overlap or stops the
|
||||||
|
consumer. Rolling back to an unsigned image is an outage, not permission to turn
|
||||||
|
off verification. Removing keys, changing policy pins or restoring removed keys
|
||||||
|
needs exact owner review; no discovery/cached-key fallback or blind consume retry.
|
||||||
|
|
||||||
|
## Separate task-execution gap
|
||||||
|
|
||||||
|
Strict `task_execution_handoff` exists and Platform's independently confirmed
|
||||||
|
journal/native fixture path has actual source-server proof. Neither creates an
|
||||||
|
existing `execute-ccr` CLI command: the current parser has none. Proposed task
|
||||||
|
caller mapping/request join, policy admission, production source/Plan/grant and
|
||||||
|
installation/journal/cleanup placement remain separate owner decisions. Both
|
||||||
|
Access task-policy runtime false gates remain unchanged; lifecycle apply is not
|
||||||
|
a substitute for execute-ccr. Platform has selected no fresh approved real
|
||||||
|
CCR/catalogue/descriptor/grant. CCR42 is in_flight and lacks a matching Secrets
|
||||||
|
catalog; synthetic CCR2/issue-core fixture bytes and temporary paths are not native
|
||||||
|
inputs. Actual before/after bytes for the exact metadata targets and independent
|
||||||
|
readback/cleanup receipts must come from Platform's eventual owner-selected plan.
|
||||||
|
|
||||||
|
For future server-owned Approval facts, strict R2 deliberately requires the
|
||||||
|
returned binding context to equal the originally submitted context. B1 caller
|
||||||
|
join remains signed-DENY and must preserve that context. Replacing the carried
|
||||||
|
claim with a freshly observed blob would refuse because its freshness fields
|
||||||
|
change; no generic equality relaxation is proposed. Access's current review
|
||||||
|
preference is to validate fresh authoritative facts out of band while retaining
|
||||||
|
the submitted context, with reviewed producer-owned signed source/receipt evidence.
|
||||||
|
Exact stable fact/freshness and provenance correspondence requires Approval and
|
||||||
|
Access review before B2/B3; no new fields or behavior are implemented here.
|
||||||
|
|
||||||
|
The Approval owner's pending `approval-fact-contract/consumer-contract.md` and
|
||||||
|
`golden-vectors.json` in the Custodian target evidence name this correspondence.
|
||||||
|
They require both original/fresh windows and exact nonfreshness authority facts.
|
||||||
|
Their Python native numeric canonical vectors still need producer conformance;
|
||||||
|
no silent digest translation or new target numeric restriction is admitted.
|
||||||
|
The proposal pins those owner artifacts for review, not as B2 implementation.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"schema": "secrets-engine.pdp-trust.v1",
|
||||||
|
"evaluator": "flex-auth/local",
|
||||||
|
"mode": "standalone",
|
||||||
|
"policy_package": "secrets-engine.catalog-lane.lifecycle",
|
||||||
|
"policy_version": "v2",
|
||||||
|
"policy_package_digest": "sha256:bd11c5fe77ce6439c65fea225ad6b71d2110efc5e7b5bc9b499c59cd0a53b8b4",
|
||||||
|
"keys": {}
|
||||||
|
}
|
||||||
133
docs/proposals/native-cli-admission/proposal.json
Normal file
133
docs/proposals/native-cli-admission/proposal.json
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
{
|
||||||
|
"proposal_id": "SECRETS-WP-0014-native-cli-20261016",
|
||||||
|
"status": "preparation only; not installable or executable authorization",
|
||||||
|
"source_base": "ff1a13dabd44ba02ddd6bc26ad75568f6d2e6225",
|
||||||
|
"workplans": [
|
||||||
|
"SECRETS-WP-0014-T02",
|
||||||
|
"SECRETS-WP-0014-T03",
|
||||||
|
"SECRETS-WP-0013-T01",
|
||||||
|
"SECRETS-WP-0013-T03"
|
||||||
|
],
|
||||||
|
"initial_scope": {
|
||||||
|
"producer": "existing flex-auth/flex-auth-secrets-engine lifecycle pin",
|
||||||
|
"consumer": "existing Secrets CLI serving authorization workflow, prospective reviewed release-bundle entrypoint only",
|
||||||
|
"stage1": "independent signer/package/trust admission and offline captured native allow+deny verification; zero protected effects",
|
||||||
|
"native_effects_admitted": 0,
|
||||||
|
"task_execution_enabled": false
|
||||||
|
},
|
||||||
|
"owner_returns": {
|
||||||
|
"access": "Custodian docs/changes/netkingdom-target-2026-10-16/access-native-preparation/native-admission-proposal-r1.json and source-policy-pins.json",
|
||||||
|
"platform": "No selected actual approved CCR/catalog/Plan/descriptor/grant/install placement; CCR-2026-0042 remains in_flight without matching catalog. Disposable source proofs are not production inputs."
|
||||||
|
},
|
||||||
|
"producer_pin": {
|
||||||
|
"evaluator": "flex-auth/local",
|
||||||
|
"mode": "standalone",
|
||||||
|
"policy_package": "secrets-engine.catalog-lane.lifecycle",
|
||||||
|
"policy_version": "v2",
|
||||||
|
"policy_package_digest": "sha256:bd11c5fe77ce6439c65fea225ad6b71d2110efc5e7b5bc9b499c59cd0a53b8b4"
|
||||||
|
},
|
||||||
|
"independent_admission": {
|
||||||
|
"production_kid": null,
|
||||||
|
"public_key": null,
|
||||||
|
"public_key_sha256": null,
|
||||||
|
"custody_receipt": null,
|
||||||
|
"candidate_producer_oci_digest": null,
|
||||||
|
"rule": "No responder keys endpoint, synthetic fixture key or deployment metadata substitutes for independent owner admission",
|
||||||
|
"receipt_verifier_integrated_revision": null,
|
||||||
|
"signer_purpose_pin_and_sharing_receipt": null
|
||||||
|
},
|
||||||
|
"placement": {
|
||||||
|
"owner": "Secrets consumer/deploying owner; exact runtime UID and paths not yet agreed",
|
||||||
|
"cli_release_prefix": null,
|
||||||
|
"cli_entrypoint": "<admitted-prefix>/bin/secrets-engine",
|
||||||
|
"fixed_verifier": "<admitted-prefix>/libexec/secrets-engine-pdp-verify",
|
||||||
|
"config_parent": null,
|
||||||
|
"trust_file": null,
|
||||||
|
"catalog_directory": null,
|
||||||
|
"policy_directory": null,
|
||||||
|
"pep_stance_file": null,
|
||||||
|
"evidence_directory": null,
|
||||||
|
"constraints": [
|
||||||
|
"new owner-controlled immutable release prefix; no overwrite or rolling source alias",
|
||||||
|
"absolute independently reviewed config/catalog/policy/stance/trust paths; no working-directory defaults for native use",
|
||||||
|
"trust regular non-symlink, not group/world writable; key admission not file-presence inference",
|
||||||
|
"owner retains manifest/admission/installation receipts and same-UID control boundary"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configuration_contract": {
|
||||||
|
"SECRETS_ENGINE_PDP_URL": "literal loopback bare origin bound to independently verified cluster and named producer pod; exact native port awaiting owner placement",
|
||||||
|
"SECRETS_ENGINE_PDP_TOKEN_FILE": "admitted bounded Secrets ServiceAccount caller file outside Git; no mint/read here",
|
||||||
|
"SECRETS_ENGINE_PDP_TRUST_FILE": "absolute independently admitted lifecycle trust path; empty-key template deliberately refuses",
|
||||||
|
"SECRETS_ENGINE_PDP_VERIFIER": "bundle wrapper fixes installed helper; no ambient override or source-checkout helper",
|
||||||
|
"SECRETS_ENGINE_AUTHORIZATION_SUBJECT_ID": "secrets-engine",
|
||||||
|
"SECRETS_ENGINE_AUTHORIZATION_SUBJECT_TYPE": "service",
|
||||||
|
"SECRETS_ENGINE_AUTHORIZATION_POLICY_PACKAGE": "secrets-engine.catalog-lane.lifecycle",
|
||||||
|
"SECRETS_ENGINE_AUTHORIZATION_POLICY_VERSION": "v2",
|
||||||
|
"SECRETS_ENGINE_APPROVAL_URL": "independently admitted Approval endpoint/owner-bound tunnel; not yet supplied for this session",
|
||||||
|
"SECRETS_ENGINE_APPROVAL_CLIENT_SECRET_FILE": "separately admitted attended provider lifetime from existing custody contract; no read here",
|
||||||
|
"SECRETS_ENGINE_APPROVAL_TOKEN_FILE": "unset when client-secret provider selected; no simultaneous providers",
|
||||||
|
"SECRETS_ENGINE_CATALOG": "absolute owner-admitted metadata directory; initial actual lane unselected",
|
||||||
|
"SECRETS_ENGINE_POLICIES": "absolute owner-admitted metadata/policy directory",
|
||||||
|
"SECRETS_ENGINE_PEP_STANCE": "absolute hash-pinned existing total stance map; prod remains fail_closed",
|
||||||
|
"SECRETS_ENGINE_EVIDENCE": "absolute owner-private evidence/outbox path with declared custody/delivery",
|
||||||
|
"SECRETS_ENGINE_UNSAFE_DEMO": "unset; no native exception",
|
||||||
|
"backend_provider": "no new selection/entitlement; configured service-jwt protected handlers remain blocked; do not switch to bootstrap/env as workaround"
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"admit": "owner reviews independent new kid/public key/custody receipt and bounded overlap, preserving exact issuer/policy artifact pin",
|
||||||
|
"roll": "separate exact producer candidate digest/seed projection rollout with native signed receipts; never fetch discovery keys",
|
||||||
|
"remove": "after new-key native receipt/consumer acceptance, remove old kid and prove old-key refusal",
|
||||||
|
"rollback": "retain reviewed signed producer/key overlap or stop/refuse. An unsigned old deployment is an outage; never disable consumer verification, restore removed key without review, relax pin, widen backend grants or blind retry consumed operation"
|
||||||
|
},
|
||||||
|
"task_mapping_gap": {
|
||||||
|
"existing_cli_execute_ccr_command": false,
|
||||||
|
"source_handoff": "secrets_engine.task_execution_handoff authorize_task_execution/consume_task_execution",
|
||||||
|
"platform_source_mediator": "railiance-platform/scripts/task_execution_mediator.py run_native_fixture_task; source proof only",
|
||||||
|
"unadmitted_inputs": [
|
||||||
|
"real service caller-to-subject server mapping and request/service binding join",
|
||||||
|
"actual task policy candidate and independently reviewed source/runtime admission; both false gates unchanged",
|
||||||
|
"owner-selected fresh approved CCR/catalog/execution-grant, compiled Plan/whole descriptor and operation UUID",
|
||||||
|
"independent expected-before/after bytes for exact two metadata targets and actual estate/backend origin",
|
||||||
|
"actual source/Plan/install/journal/cleanup placement and trusted provider endpoints/credentials/custody",
|
||||||
|
"load-bearing audit/outbox cadence and durable receipt correlation",
|
||||||
|
"Approval/Access reviewed out-of-band fresh-fact versus original carried-claim correspondence and signed provenance; strict context equality remains unchanged"
|
||||||
|
],
|
||||||
|
"approval_fact_interface_review": {
|
||||||
|
"status": "review preference only; no implementation/admission",
|
||||||
|
"preserve": "strict binding.context equality and original submitted/approval-free/native joins",
|
||||||
|
"direction": "Access prefers out-of-band server-fetched authoritative fact checking while retaining original carried context, then reviewed producer-owned signed provenance/audit evidence",
|
||||||
|
"required_review": [
|
||||||
|
"Approval fact/freshness semantic correspondence",
|
||||||
|
"Access source receipt/provenance binding and exact request digests"
|
||||||
|
],
|
||||||
|
"b1": "signed-DENY caller join only; no context replacement",
|
||||||
|
"b2_b3": "not enabled or implemented here"
|
||||||
|
},
|
||||||
|
"approval_fact_contract": {
|
||||||
|
"artifact": "the-custodian/docs/changes/netkingdom-target-2026-10-16/approval-fact-contract/consumer-contract.md",
|
||||||
|
"sha256": "3dfb7987a4d9fe461b917cfa5bae7beef61bc4d9a4561fdded3e90128f5966de",
|
||||||
|
"vectors_artifact": "the-custodian/docs/changes/netkingdom-target-2026-10-16/approval-fact-contract/golden-vectors.json",
|
||||||
|
"vectors_sha256": "dfb0a8810cd91847d7af6a7af6a51607a67a66fad7b86fc57365308c36bd9323",
|
||||||
|
"status": "owner source contract pending integration; no Go conformance or B2 behavior admitted",
|
||||||
|
"required": "preserve original fact/context/freshness, independently validate fresh fact window and exact nonfreshness authority; do not translate native numeric digests or invent target restrictions"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"approval_state": "no owner assent, key admission, install, caller token, operation grant or live change requested/executed by this preparation",
|
||||||
|
"denominator": {
|
||||||
|
"shared_check_implementation": 1,
|
||||||
|
"serving_cli_call_sites": 11,
|
||||||
|
"serving_cli_handlers": 10,
|
||||||
|
"lifecycle_pdp_action_values": 12,
|
||||||
|
"native_effect_call_sites_accepted": 0,
|
||||||
|
"excluded": [
|
||||||
|
"session revoke stance-only backend path",
|
||||||
|
"service-auth explicit identity probes",
|
||||||
|
"route ambient-backend readiness probes",
|
||||||
|
"dry-run/non-effect reporting"
|
||||||
|
],
|
||||||
|
"task_cli_command_count": 0,
|
||||||
|
"platform_source_mediator_native_acceptance": false,
|
||||||
|
"generic_cli_consume_is_strict_task_handoff": false,
|
||||||
|
"effect_acceptance_required": "Review actual selected handler/generic consume response and caller scope separately; strict Platform fixture proof does not close existing CLI effects"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -119,13 +119,12 @@ def _require_lane_approval(
|
||||||
):
|
):
|
||||||
"""Apply published PEP stance, resolve lane approval, then CAS-consume.
|
"""Apply published PEP stance, resolve lane approval, then CAS-consume.
|
||||||
|
|
||||||
Production ``fail_closed`` is read from ``pep-stance.yaml``. The durable
|
Production ``fail_closed`` is read from ``pep-stance.yaml``. A configured
|
||||||
access-engine decision record is not served yet, so that row refuses live
|
serving path requires a fresh approval claim and independently authenticated
|
||||||
production work. If that residue is ever bypassed, GH-DEC-2026-003 still
|
signed PDP envelope, then successful CAS before the backend. Missing runtime
|
||||||
requires a successful approval-engine consume before any OpenBao call.
|
trust/configuration still refuses production; source support is not native
|
||||||
The three-factor unsafe-demo exception is not a stance row and is not a
|
admission. Build/test engine-unreachable residue retains the explicit legacy
|
||||||
consume path. Build/test ``fail_open`` still requires the existing
|
lane check. The three-factor unsafe-demo exception grants no native adoption.
|
||||||
lane-approval check — a tracked gap until SECRETS-WP-0008-T02.
|
|
||||||
"""
|
"""
|
||||||
# Steps 1 and 2 first: a validated claim and decision are what make the
|
# Steps 1 and 2 first: a validated claim and decision are what make the
|
||||||
# unreachable-engine residue inapplicable. Absent configuration returns
|
# unreachable-engine residue inapplicable. Absent configuration returns
|
||||||
|
|
|
||||||
|
|
@ -102,3 +102,15 @@ admitted signer, reject forgery/downgrade, rotate without accepting removed keys
|
||||||
and preserve request/approval binding, lifetime and single-use consumption.
|
and preserve request/approval binding, lifetime and single-use consumption.
|
||||||
Retain rollback and failure evidence. Update CUST-WP-0080 G13 only with these
|
Retain rollback and failure evidence. Update CUST-WP-0080 G13 only with these
|
||||||
native receipts; do not equate passing transport tests with closure.
|
native receipts; do not equate passing transport tests with closure.
|
||||||
|
|
||||||
|
|
||||||
|
2026-10-16 native preparation (no rollout): `docs/proposals/native-cli-admission/`
|
||||||
|
now scopes the existing CLI/lifecycle signer stage, exact delegated PEP denominator,
|
||||||
|
independent key/policy admission, owner-controlled bundle/config placement and
|
||||||
|
rotation/rollback refusal. Canonical ff1a13d (packaging plus strict handoff) was
|
||||||
|
rebuilt in an isolated clean checkout; artifact receipts are in Custodian
|
||||||
|
`decision-native-preparation/`. Production kid/public fingerprint/custody receipt,
|
||||||
|
producer candidate OCI and actual runtime/config placement remain missing. The
|
||||||
|
empty-key trust template deliberately refuses. No install, key read, caller mint,
|
||||||
|
protected effect, policy switch or trust admission occurred. T02 remains progress,
|
||||||
|
T03 wait; task source/live obligations remain separately in SECRETS-WP-0013.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue