Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
113 lines
6.9 KiB
Markdown
113 lines
6.9 KiB
Markdown
# Strict Secrets service task-execution handoff
|
|
|
|
This is a narrow source seam for existing SECRETS-WP-0013, not a native grant or
|
|
an execute-ccr CLI. Both Access runtime-deny policy variants remain unchanged.
|
|
The proposed service subject/transport mapping and the complete native executor
|
|
still need independent owner admission. Positive source fixtures do not admit
|
|
that mapping, a policy, a caller, a production key or an OpenBao entitlement.
|
|
|
|
Platform's trusted owner process calls:
|
|
|
|
```python
|
|
from secrets_engine.task_execution_handoff import (
|
|
authorize_task_execution, consume_task_execution,
|
|
)
|
|
authorization = authorize_task_execution(cfg, entry, execution_contract=contract)
|
|
record = authorization.as_owner_handoff()
|
|
# Independently bind exact owner Plan/descriptor; reserve durable one-shot journal.
|
|
# Persist pending strict-CAS intent before calling:
|
|
consumption = consume_task_execution(cfg, authorization)
|
|
# Independently GET-confirm exact original consumption with Approval Engine's
|
|
# ExecutionConfirmationClient before journaling consume-confirmed/native work.
|
|
```
|
|
|
|
Preparation uses the existing empty fields/policy_targets/auth_targets defaults
|
|
and existing build_action_request/claim/Check validators. No caller-selected
|
|
transport, authorizer callback, policy result or raw handoff mapping is accepted.
|
|
The normal authorizer retains detached serialized request, claim and authenticated
|
|
Go-typed envelope snapshots; its existing evidence output does not expose them.
|
|
The narrow adapter reuses the validators, rather than evaluating a policy.
|
|
|
|
The adapter checks the exact descriptor in the signed context, full evaluated and
|
|
submitted request digests, approval-free digest, exact five-field native act and
|
|
native binding digest, service subject/resource/tenant correspondence and original
|
|
decision/approval/deadline bounds. Initiating/represented subject is strictly
|
|
`secrets-engine` of type `service`; the execution actor is `service:secrets-engine`.
|
|
Signed caller provenance must report `enforce`, the proposed exact Secrets
|
|
ServiceAccount principal, `flex-auth` audience and live expiry bounding the
|
|
operation deadline. This consumes the signed PDP's caller attestation; it does
|
|
not independently perform TokenReview or promote the proposed server mapping.
|
|
Human/delegation/projected-identity flags cannot substitute for this service seam.
|
|
The later typed execution builder now propagates the fixed Access public
|
|
service_actor_binding before approval issue; it is not caller authentication.
|
|
No source-policy activation is added.
|
|
|
|
`as_owner_handoff()` returns a detached non-secret mapping with:
|
|
|
|
- execution_contract
|
|
- approval_id, request_digest, decision_id
|
|
- native_binding, approval_binding_digest, submitted_request_digest
|
|
- decision_not_before, decision_expires_at, approval_expires_at
|
|
|
|
The exact native binding is derived from the signed evaluated request using the
|
|
published Approval five-field mapping, and is compared to the served claim.
|
|
Descriptor/CCR/grant/source/catalog/target correspondence is retained end to end;
|
|
Platform still independently compiles its owner Plan and grant from owner bytes.
|
|
The mapping is evidence for that join, never a transferable bearer authorization.
|
|
|
|
Consumption accepts only the module-created opaque prepared object in that same
|
|
trusted owner process. It fixes source/config coordinates, reauthenticates using
|
|
currently admitted responder keys, and rechecks claim/decision/descriptor/caller
|
|
freshness before reading the CAS credential. Each object is reserved once before
|
|
CAS/revalidation and cannot retry after any failure or unknown outcome. Its
|
|
process-local guard complements Platform's durable cross-process journal; it is
|
|
not a replacement for that journal or process isolation.
|
|
|
|
The strict response path uses the existing CAS transport but rejects duplicate,
|
|
nonfinite or excessively deep JSON, missing/mismatched approval and decision IDs,
|
|
wrong digest/status, missing or nonboolean idempotence, historical idempotent
|
|
success, verdict fields and absent/naive/invalid consumption timestamps. The
|
|
consumption instant and post-CAS freshness must remain inside the original
|
|
bounds. No field is coerced or filled from the submitted binding. A late/uncertain
|
|
CAS may have occurred; it never licenses retry or protected native work.
|
|
|
|
The returned immutable TaskExecutionConsumption contains exact approval_id,
|
|
request_digest, decision_id, consumed_at and explicit false idempotent. It proves
|
|
only the strict CAS response observed by Secrets. Platform must independently
|
|
confirm original durable consumption using Approval's real provider client,
|
|
journal it, then recheck its exact Plan, owner sources, grant and deadlines before
|
|
any native operation. Neither a dataclass nor a caller-supplied boolean admits
|
|
execution. Existing generic CLI CAS behavior is otherwise unchanged.
|
|
|
|
|
|
2026-10-16 retained-registry preapproval source preparation adds
|
|
`prepare_task_approval(cfg, entry, execution_contract=contract)`. It calls the
|
|
existing signed Check client with the original claim-free typed proposal and
|
|
accepts only a signed DENY normalization record. This neither authorizes nor
|
|
consumes an operation. No registry algorithm is copied and no registry is emptied.
|
|
|
|
The detached `as_owner_handoff()` returns `original_request`,
|
|
`submitted_request_digest`, authoritative `native_binding`,
|
|
`approval_binding_digest`, normalization `decision_id`, `execution_contract`, and
|
|
signed `registry_snapshot_digest`. Exact original context (including JSON kinds),
|
|
submitted digest, recomputed evaluated digest, explicit approval-free digest,
|
|
policy/key admission, service/caller identity, decision time and deadline are
|
|
checked. Registry digest is evidence from the admitted signer; this method does
|
|
not independently grant registry/config admission. The caller uses the returned
|
|
native act and approval-free digest for normal Approval issuance and human entry.
|
|
It preserves the original proposal; final authorize_task_execution builds that
|
|
same proposal and attaches only the original issued claim. Access normalizes
|
|
again and independently joins current source facts. Changed evaluated facts or
|
|
native target refuse before CAS. A normalization DENY object/mapping is never
|
|
accepted by consume_task_execution.
|
|
|
|
Normalization decision_time must be valid and nonfuture; there is deliberately
|
|
no invented standalone normalization TTL. The DENY receipt is not permission and
|
|
cannot discharge final signed ALLOW or source validation. Expired original task/
|
|
caller bounds refuse at preparation; a stale normalization's changed evaluated
|
|
facts refuse when Access independently checks the original issued claim against
|
|
the current retained registry. Unchanged historical normalization can only supply
|
|
public issue metadata; it cannot itself produce a CAS/native admission. The actual
|
|
source-server drift proof restarts Access with changed authoritative subject
|
|
roles after preapproval and observes final refusal with no new ALLOW record, no
|
|
CAS and unconsumed Approval state.
|