Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
356 lines
23 KiB
Markdown
356 lines
23 KiB
Markdown
# KEY39 private token producer and node-route decision packet
|
|
|
|
Proposal `KEY-WP-0039-T02/private-producer-handoff-v1`, source preparation only.
|
|
Lifecycle V5 is unchanged (manifest d1f997624db46693a7126a6eb6435f6b3a353d5bd67dcc8a539683e4b7147285).
|
|
This packet names concrete supported flows and a reviewable local handoff. It
|
|
supplies no admitted credential route, authenticated approval or native readiness.
|
|
T01 stays done and T02 open; no new workplan or task is created.
|
|
|
|
## Existing flows and exact owner choice
|
|
|
|
Choose existing `netkingdom-bootstrap-console` for the human class refusal if
|
|
NetKingdom/founder approve this one attended use of their existing client and
|
|
literal `http://127.0.0.1:8876/oidc/callback` listener. Its source registration is
|
|
public authorization_code, scopes openid/profile/email/groups, default audience
|
|
netkingdom-bootstrap-console. Request only `openid`; do not request approval or
|
|
OpenBao permissions. `keycape login` verifies RS256 issuer/access audience/scopes,
|
|
ID-token client audience/nonce and matching subject. It binds before emitting a
|
|
browser URL, validates exact callback host/path/state, uses S256 PKCE, and has a
|
|
five-minute attempt bound. The provider handles password/MFA. Fresh deployed
|
|
MFA/registration evidence is required; the handoff requires human aal2/mfa=true.
|
|
Do not infer MFA from the client fragment: it has no per-client mfaRequired pin.
|
|
Do not run the bootstrap console simultaneously on port8876. The same client's
|
|
localhost callback is not substituted: the CLI requires a literal loopback IP.
|
|
|
|
Concrete producer invocation after that decision, on the attended workstation:
|
|
|
|
```
|
|
keycape login --issuer https://kc.coulomb.social \
|
|
--client-id netkingdom-bootstrap-console --audience netkingdom-bootstrap-console \
|
|
--scope openid --redirect-uri http://127.0.0.1:8876/oidc/callback \
|
|
--out /OWNER-PRIVATE-TMPFS-DIR/key39-human.json
|
|
```
|
|
|
|
The private directory is new owner-controlled mode0700 tmpfs outside Git; the
|
|
CLI creates the file mode0600 exclusively. No invocation is performed here.
|
|
Current browser access-token lifetime is server TokenLifetime; per-client
|
|
TokenLifetime is used only for client_credentials. Do not promise a new one-minute
|
|
human lifetime by adding that field to a browser registration.
|
|
|
|
Alternative only if the owner rejects existing-client use: request one separately
|
|
reviewed public client `key39-negative-human`, audience of the same name, exact
|
|
callback `http://127.0.0.1:8877/oidc/callback`, scopes [openid], grantTypes
|
|
[authorization_code], mfaRequired true, no role/serviceSubject/secretRef. That
|
|
requires a new source registration, reviewed native merge/rollback and changed
|
|
handoff audience binding. It is not part of V5's six temporary clients and must
|
|
not silently enter that mutation. The current adapter intentionally refuses it.
|
|
Reuse of informed-decision-approver is unsuitable for this CLI: its registered
|
|
callback is HTTPS decisions.coulomb.social, not literal loopback. OpenBao admin
|
|
is another source-compatible callback but its admin relying-party purpose is
|
|
unnecessary for this probe and is not the selected plan.
|
|
|
|
Coding-agent producer is exactly the existing accepted source identity:
|
|
|
|
```
|
|
keycape service-token --issuer https://kc.coulomb.social \
|
|
--client-id codex-railiance-platform --audience codex-railiance-platform \
|
|
--scope openbao:login --secret-env KEYCAPE_CODEX_RAILIANCE_PLATFORM_CLIENT_SECRET \
|
|
--out /OWNER-PRIVATE-TMPFS-DIR/key39-agent.json
|
|
```
|
|
|
|
Subject service:codex:railiance-platform, tenant:platform, roles [coding-agent],
|
|
principal_type service; fifteen-minute JWT, no refresh or ID token. The secret
|
|
must arrive from an existing **admitted** owner-controlled delivery. No client
|
|
secret request or generation occurs here. A source fragment is not live
|
|
registration or consumer entitlement. The inspected Platform operational identity
|
|
is AppRole; its OpenBao token cannot substitute for this JWT. Its historical
|
|
coding-agent prose still names tenant:coulomb, whereas current KeyCape source
|
|
uses tenant:platform. Platform must reconcile its exact proposed/installed
|
|
metadata, not use that historical prose as evidence.
|
|
|
|
No reviewed coding-agent client-side custody reader/consumer delivery receipt
|
|
was found in the inspected CCR/registry sources. Platform must either return
|
|
exact existing admission coordinates and fresh live registration/delivery evidence
|
|
or own a new narrow custody/issuer/consumer admission proposal. Do not borrow
|
|
secrets-engine's credential, widen its role, read raw KV, or mint an ephemeral
|
|
coding-agent lookalike to manufacture this case. If unavailable, the joint
|
|
session remains blocked and coding-agent refusal inconclusive; V5 requires both
|
|
private token inputs and cannot silently skip the case.
|
|
|
|
## Private handoff adapter
|
|
|
|
`scripts/openbao_negative_private_handoff.py` adapts the two existing CLI files
|
|
to V5 private stdin JSON keys human_token and coding_agent_token. It makes no
|
|
network request, login, secret retrieval, registration, deployment or executor
|
|
launch. The source is Linux main-thread only. Before file consumption it requires
|
|
an inherited **writable pipe FD >=3**, never stdout/stderr, a new owner mode0700
|
|
non-symlink directory outside Git, single-link mode0600 regular files owned by
|
|
the current UID, bounded reads and unchanged inode/size/timestamps. JSON rejects
|
|
duplicate/nonfinite keys; token length is bounded. Both files must be distinct.
|
|
A second inode/metadata compare immediately precedes each unlink.
|
|
|
|
The adapter checks decoded issuer/audience/principal/agent claims and at least
|
|
300 seconds remaining lifetime, plus human MFA shape. These are not signature
|
|
verification or authenticated custody: its tests deliberately use unsigned
|
|
synthetic JWT shapes. The founder must run the pinned current KeyCape CLI and
|
|
retain exclusive custody continuously; arbitrary downloaded/preexisting files
|
|
are inadmissible despite matching mode or claims. CLI signature verification is
|
|
the issuer-verification boundary. Require a fresh remaining-lifetime check before
|
|
native execution and ensure token validity through the actual presentation; the
|
|
five-minute adapter floor is not a grant for a longer session.
|
|
|
|
Explicit `--consume-owner-files` authorizes removal of precisely these inspected
|
|
caller-owned files. After both load successfully, the adapter consumes them
|
|
before writing the pipe and closes its inherited endpoint on every exit. Partial
|
|
unlink failure records possible retained files; partial/broken/timed-out delivery
|
|
records unknown delivery and must stop before native mutation, with no retry.
|
|
Delivery has a hard five-second SIGALRM bound; preexisting timer refuses and
|
|
handler/timer state is restored. Receipts contain booleans and fixed failure
|
|
codes only; a pipe write completion does not prove downstream validation or native
|
|
acceptance. No stdout token path exists. A private pipe still requires a trusted
|
|
consumer: the adapter cannot authenticate its peer, approval JSON or native go.
|
|
|
|
The founder-reviewed launcher must create the pipe and start a pinned destination
|
|
wrapper before running the adapter with that endpoint inherited as FD3. The
|
|
wrapper may invoke the already approved SSH transport to railiance01 and forward
|
|
stdin without PTY, shell tracing, tee, terminal/stdout copies, token argv/env,
|
|
logging, agent custody or persistent remote files. The destination reads the
|
|
private JSON with V5; no additional file copy. Exact workstation producer and
|
|
node wrapper paths, hashes, SSH host identity/transport grant, consumer startup
|
|
order, refusal gating and receipt handling must be owner-reviewed first. This
|
|
packet does not ship or admit such a launcher and cannot claim a full handoff.
|
|
Token files must be consumed before starting V5; on failed preparation the owner
|
|
removes remaining exact files. This packet requires founder choice to admit the
|
|
two bounded caller-owned JWT files: V5's no-copy rule for generated six client
|
|
secrets is unchanged. Python memory/Unix unlink are not secure-zeroization claims;
|
|
use an owner tmpfs directory and process termination. Issued JWTs expire normally.
|
|
No issuer-side JWT revocation is claimed. Any OpenBao acceptance remains V5's
|
|
bounded self-revoke/Platform reconciliation obligation.
|
|
|
|
## Mandatory route and decision ordering
|
|
|
|
The child is a Linux main-thread process on railiance01 using its k3s kubeconfig.
|
|
Workstation loopback18200 tunnel evidence does not prove node loopback18200;
|
|
openbao.openbao.svc normally resolves from Pods, not necessarily the host. Keep
|
|
native proposal gated until Platform/NetKingdom verify one of V5's exact origins
|
|
**from the actual node process placement**, using a separately reviewed founder
|
|
port-forward path if required. Do not expand V5 origins or use workstation role
|
|
observations as route proof.
|
|
|
|
Before any token exchange, temporary credential generation, Secret creation,
|
|
registry/env mutation or restart, the owner preflight must run a bounded public
|
|
Bao health request from that exact placement to the selected origin. It follows
|
|
no redirect or ambient proxy, caps response bytes and total elapsed time, sends
|
|
no auth header and prints only normalized initialized/unsealed/health booleans.
|
|
Verify acceptable active/standby health semantics independently, current TLS or
|
|
local port-forward ownership, no unintended public bind and non-secret issuer
|
|
connectivity. No auth, KV/data path or raw error output. The V5 transport currently
|
|
allows login/revoke only; this additional public health/route preflight belongs
|
|
in the reviewed launcher/NetKingdom guard, not an unreviewed V5 edit.
|
|
|
|
Owner sequence: select source plan -> independent KeyCape/NetKingdom/Platform
|
|
reviews -> approved exact launcher plus route/health preflight -> admitted
|
|
producer/custody and human browser attempt -> private-pipe delivery -> destination
|
|
validates complete stdin/envelope/source/runtime/role receipts -> native action
|
|
only under fresh exact founder authorization -> V5 cleanup/revoke plus producer
|
|
cleanup. Any unavailable route/custody/client/complete input keeps T02 open.
|
|
|
|
## Exact acknowledgments still required
|
|
|
|
- KeyCape: selected client/claims/CLI verification, lifetime and MFA source;
|
|
this packet is preparation, not a formal source acknowledgment of a launcher.
|
|
- NetKingdom: actual existing registration/image, client reuse and callback
|
|
listener ownership, browser/workstation/node placement, guarded public health
|
|
preflight ordering and exact restart/cleanup runtime pins.
|
|
- Platform: coding-agent existing custody/consumer entitlement or new proposal,
|
|
corrected tenant metadata, route/port-forward ownership, fresh bounded role/
|
|
leeway/effective-policy observation, session revoke and unknown reconciliation.
|
|
- Founder: existing-client purpose reuse versus new registration, explicit private
|
|
tmpfs JWT-file allowance, admitted exact launcher/transport/target/window/cleanup
|
|
obligation and actual supervised custody. Source acceptance is not that go.
|
|
|
|
18 synthetic adapter checks pass: successful private write and file consumption,
|
|
stdout/stderr/regular/read-only FD refusal, explicit consumption, symlink/hardlink/
|
|
public mode/parent/Git/oversize/duplicate JSON refusal, wrong audience/MFA/tenant/
|
|
role/AppRole/expiry refusal, replacement before unlink, hard write timeout with
|
|
signal restoration and value-safe partial/broken delivery. Original V5/failed
|
|
review histories and all source/current owner records remain retained.
|
|
|
|
# V2 correction and exact child-ready integration
|
|
|
|
The V1 packet text above is retained history. Proposal
|
|
`KEY-WP-0039-T02/private-producer-handoff-v2` supersedes its unsafe no-ready
|
|
adapter and its precise-inode-removal wording. V1's immutable manifest239aaa
|
|
and NetKingdom consumer refusal a1ed14e6b2db1ae77c3fd638fd7e47b5bd50c25eebba418e31aba89bb4b7f88e
|
|
remain recorded as the same correction trial. The exact compatible consumer is
|
|
`KEY-WP-0039-T02/attended-lifecycle-v9-ready-input`, separately pinned below;
|
|
V5/V6/V7/V8 source/review history is never implicitly repinned. No owner admission
|
|
or founder go is supplied by V2.
|
|
|
|
The KeyCape launcher is `scripts/openbao_negative_private_launcher.py`. It
|
|
validates its own and its adjacent adapter's exact source hashes plus the local
|
|
copy of the exact remote envelope. The remote child/wrapper paths and hashes
|
|
must occur in that envelope; proposal/target/source owner receipts, finite
|
|
window/health pin and founder/file-allowance receipt references must match the
|
|
reviewed contract. These fields are procedural constraints only: editable JSON
|
|
cannot authenticate approval. The founder must authenticate/retain the actual
|
|
exact disposition and own this entire launcher/custody/host context.
|
|
|
|
The source launcher alone creates SSH stdin/stdout pipes, a fresh random256-bit
|
|
nonce and fixed direct SSH argv to railiance01. It uses no PTY, strict existing
|
|
host-key checking, batch mode, no agent forwarding, no remote forwarding, finite
|
|
connection/keepalive bounds, and a minimal environment that excludes confidential
|
|
client credentials. It does not create or request a certificate, token, credential
|
|
or route. This is a proposed **separate founder-admitted direct SSH profile**:
|
|
the normal warden silent lane has different stdout rules and is not silently
|
|
repurposed. The founder/transport owner must review actual node host identity,
|
|
SSH certificate/session entitlement and pinned remote paths before execution.
|
|
No SSH command was invoked during preparation.
|
|
|
|
On railiance01 the independently NetKingdom-owned pinned wrapper creates a
|
|
local dedicated child-ready pipe and launches the exact pinned Python child
|
|
with inherited SSH stdin. No invented extra SSH file-descriptor forwarding is
|
|
used. Only after exact source/envelope checks, original action-window start and
|
|
pinned public Bao health succeeds does the child emit a bounded value-free
|
|
marker to that local pipe, close it, and enter the V8 bounded private receiver.
|
|
The wrapper validates that local marker and forwards exactly one newline JSON
|
|
marker on SSH stdout. SSH stdout stays open until child completion; Key reads
|
|
only to the first newline, never waits for SSH stdout EOF. Child stdout/stderr
|
|
stay suppressed; protected receipt remains exclusive on the node.
|
|
|
|
Ready schema `key39-private-input-ready/v1` has exactly these keys:
|
|
schema, session_nonce, proposal_id, target, executor_sha256, envelope_sha256,
|
|
bao_health_identity_sha256, valid_until_epoch, receive_budget_seconds. Marker
|
|
must bind the new nonce and exact consumer proposal/target/source/envelope/health
|
|
pin and epoch; receive budget must be finite nonboolean, positive and <=15s.
|
|
Marker size is <=4096 bytes. An old/missing/malformed/mismatched/failed/expired
|
|
ready marker produces **zero token file loads, zero consumption, zero private
|
|
bytes**, then closes local endpoints. A readiness marker is not authentication,
|
|
JWT verification, custody admission, routing authority or a live grant. It is
|
|
trusted only because the reviewed launcher captures the intended pinned wrapper
|
|
under the separately admitted authenticated host/session context. There is no
|
|
standalone adapter CLI accepting a ready file, boolean or user-provided marker.
|
|
|
|
The adapter validates two distinct kernel pipe identities: private data endpoint
|
|
write-only, control endpoint read-only, each FD>=3 and each device/inode distinct
|
|
from stdin/stdout/stderr and from each other. Actual duplicates of stdout/stderr
|
|
are refused even when their descriptor number is >=3. Captured SSH stdout is a
|
|
separate control pipe owned by the launcher; it never becomes token output.
|
|
|
|
The launch preparation cap is5s. The adapter has one total5s deadline covering
|
|
ready wait, caller-file load, cleanup and delivery. After ready this existing
|
|
timer only clips downward against its remaining budget, received child budget
|
|
and current remaining approval lifetime. Advertised child budget is not compared
|
|
as <=current remaining wall time (transport necessarily consumes time); the
|
|
actual delivery timer clips to both. Before each write and after completion the
|
|
same absolute expiry/monotonic delivery bound is rechecked. No retries or clock
|
|
reset; stdin closes to provide complete EOF. A partial write, transport break or
|
|
expiry remains unknown and cannot be native proof. Launcher waits only for a
|
|
value-free child/transport exit under remaining action +300s cleanup +30s margin;
|
|
local transport teardown never proves remote custody or process reconciliation.
|
|
Native receipt/unknown-session acceptance remains Platform/NetKingdom's.
|
|
|
|
## Honest file-cleanup boundary
|
|
|
|
Owner mode0700/0600, no symlink/hardlink/Git and unchanged identity/size/time
|
|
checks remain. **The compare and unlink are not atomic inode-conditioned delete.**
|
|
Continuously exclusive same-UID custody of the directory, no concurrent writers
|
|
and no attacker sharing that UID are mandatory for this proposed file approach.
|
|
No helper boolean can prove that condition. The founder must control the new
|
|
private tmpfs directory/process context and retain exclusive custody; no shared
|
|
agent/shell/daemon may modify it. Any known interference requires abort and owner
|
|
reconciliation before another attempt.
|
|
|
|
V2 removes V1's exact-inode/atomic implications. Its retained stat-to-unlink race
|
|
check deliberately shows that a concurrent same-UID replacement can still be
|
|
removed; that is outside the admitted exclusive-custody assumption and is not
|
|
represented as a fixed filesystem capability. Even after nominal path removal,
|
|
receipts retain `atomic_inode_delete_guaranteed=false`,
|
|
`exclusive_same_uid_custody_required=true`, `credential_copy_cleanup_verified=false`
|
|
and `credential_files_remain_possible=true`. `caller_path_removal_completed`
|
|
means only these unlink calls completed under that assumption. It is not token
|
|
copy inventory, secure erase or cleanup proof. Owner verification/process
|
|
termination/tmpfs teardown remains required; issued JWTs expire normally.
|
|
If that exclusive context cannot be admitted, do not use these private files;
|
|
separately implement/review a process-to-process in-memory producer instead.
|
|
|
|
The existing human-client reuse versus new registration, live MFA, coding-agent
|
|
client-side custody/consumer delivery, exact authenticated launcher/SSH profile,
|
|
private tmpfs files/exclusive custody, actual node route/provider/role/leeway,
|
|
quiet restart window and fresh founder disposition are still unapproved choices.
|
|
This source packet does not resolve them. Source-pinned readiness eliminates
|
|
premature token transport only within the admitted trusted launcher context.
|
|
|
|
Exact compatible consumer manifest SHA256 84542ddcff00932fc7ce22dcb2626be8942a3c006c5098a62fdd6b2478d0cd14;
|
|
child 24b7b803e4eb7e6e7c0700a069dad0ec315ee7eb5538a88b9e56147f8fab5cdd;
|
|
node wrapper 76ac013d1a676a0dfa58aea1ce87b0c3e72483ccd21f586a22c5475e9132f6c1.
|
|
31 distinct supplied producer/launcher synthetic checks pass; 74 supplied
|
|
compatible consumer source checks pass. No actual SSH, login, tokens, custody
|
|
or native route was used. Fresh independent consumer and Platform source
|
|
reviews of this exact V2 and V9 remain necessary before founder choice.
|
|
|
|
# V3 remote-unknown reporting correction
|
|
|
|
Proposal `KEY-WP-0039-T02/private-producer-handoff-v3`. Exact NetKingdom V9
|
|
manifest84542ddc and child/wrapper bytes are unchanged; this is only a new Key
|
|
launcher reporting revision in the same preparation trial. Platform V2 pair
|
|
review finding RPF-KEY39-PAIR-V2-F01 is retained unchanged, SHA256
|
|
8353eb8aae11be8ce874887d6a5ca10bf37c6fba73c3f85f0644a7546dd7d33f.
|
|
|
|
After copying adapter outcome, `private_input_delivery_unknown=true` immediately
|
|
sets sticky `consumer_outcome_unknown=true` and `consumer_process_completed=false`
|
|
before any failure/early return. A complete payload can reach the remote child
|
|
before local write/EOF confirmation times out. Terminating local SSH cannot
|
|
prove that no remote operation occurred, that the child stopped or that remote
|
|
custody/cleanup completed. No retry or subsequent local success rewrites this
|
|
attempt. Native acceptance and unknown resolution stay independent owner duties.
|
|
|
|
33 distinct checks pass, including actual full kernel-pipe JSON write followed
|
|
by SIGALRM interruption before confirmation, and an actual4096-byte partial
|
|
write/timeout; both retain remote unknown after local terminate. No actual SSH,
|
|
protected consumer or credentials were involved. All V2/V1 source, unsuccessful
|
|
reviews and previous narrow issuer acknowledgments remain frozen history.
|
|
Exact source return and all prior native/client/custody/transport/file choices
|
|
remain required. Source reporting correction is not runtime admission.
|
|
|
|
# V4 source-acquisition and shared preparation deadline correction
|
|
|
|
Proposal `KEY-WP-0039-T02/private-producer-handoff-v4`, same trial. The exact
|
|
Net V9 manifest84542ddc and child/wrapper are unchanged. NetKingdom V3 consumer
|
|
refusal NET-PRODUCER-V3-F01 stays frozen, SHA256
|
|
38abf660701194f85934a076a0c01d3047e6bfe790e02ba1b0e4616e356634e6. V1/V2/V3 source and earlier acknowledgments/refusals remain history.
|
|
|
|
Actual CLI now starts one absolute monotonic5-second preparation deadline before
|
|
contract acquisition. Initial source read, source/envelope/hash checks and SSH
|
|
spawn then ready/file/consumption/write phase all use only remaining time from
|
|
that original deadline. Phase timers may disarm/rearm, but each is clipped to
|
|
original remaining time; launch never restarts the budget spent reading contract.
|
|
After ready, child receive budget and absolute approval expiry only clip further.
|
|
Once private input is delivered, existing separate action/cleanup completion
|
|
wait remains; it cannot renew preparation or mutation authority.
|
|
|
|
Contract/envelope reads use bounded4096-byte chunks, at most65536 bytes, absolute
|
|
paths, no observed symlink ancestry, O_NOFOLLOW/O_NONBLOCK, single-link regular
|
|
files with no group/world write, and stable device/inode/UID/mode/link/size/time
|
|
comparisons. FIFOs/devices/symlinks/empty/oversized files refuse before private
|
|
file access/SSH. Source digest reads share that path with at most262144 bytes.
|
|
All actual CLI source acquisition runs under the finite remaining preparation
|
|
alarm; a stalled filesystem call cannot escape this total deadline. Observed
|
|
path/source races refuse; continuously trusted exclusive custody remains required
|
|
and no atomic pathname/exec protection or authenticated metadata grant is claimed.
|
|
|
|
40 distinct producer/launcher checks pass, including actual CLI FIFO/symlink/
|
|
oversize refusal, delayed regular read under the hard timer with restored signals,
|
|
a main contract-read delay followed by launch delay that cannot renew the budget,
|
|
source drift/chunk bounds and earlier actual full/partialwrite stickyunknown.
|
|
Nine retained real paired handshake regressions also pass using actual pinned
|
|
Net wrapper and child main with only local fake SSH/health/execute substitutions:
|
|
no network, Kubernetes, protected credentials or native mutation. The original
|
|
Net fixture files are copied unchanged except the Key stage path, solely as
|
|
source regression evidence, never a new foreign formal owner review.
|
|
|
|
Fresh exact independent pair source returns and all unadmitted human/MFA/client/
|
|
coding-agent custody/consumer/directSSH/exclusive tmpfs/route/provider/role/leeway/
|
|
readiness-Argo/maintenance-exception/founder/native-acceptance duties still gate
|
|
use. No source-only helper choice, ready marker or editable approval JSON supplies
|
|
that authority. T01done/T02open; actual native outcome remains pending.
|