Repository navigation
SECURITY: a plane never receives a credential's bytes (credential-field refs, template refs); a member's env resolves at spawn - #727
Merged
Conversation
…} filled crosses as its secret reference; a member's env resolves at spawn SECURITY rulings (2026-10-07): - a SecretRef only at a credential field; - url, command, args, cwd and token_url keep load-time interpolation (no 1.5.5 narrowing); - a credential filled in part is a template reference; - a member's env resolves at the spawn. Carried onto predev from the orphaned stack (#684 on #599 on #559): it no longer rides P1b. Every crossing predev hands a door plane is bound: the door validate and facing probe, DoorOwned::bytes, the stage-3g validate blob, serve.rs handed_settings (open and the apply refresh) and the owned sections at open. The test plane records the open and refresh blobs it is handed (its refresh now answers a snapshot). - busbar-kernel config::filled. The interpolation's structural check walks the real and placeholder trees in step; it records each scalar `${VAR}` filled. A record holds the path, the variables, whole or part, the value as written and a per-process keyed digest; it never holds the value. - plane_bound replaces a value only at a CREDENTIAL position, and only while the value keeps its digest. A credential position is any of: - a credential key (api_key, token, client_secret, subject_token, password, secret, private_key, authorization, bearer, and the other token names); - an entry of a program's `env` map; - anything inside the kernel-owned `upstream_credentials` block. A whole value becomes `{ env: VAR }`. A part becomes a template reference (`{ module: template, settings: { text: "Bearer ${VAR}" } }`). Every other position crosses as interpolated. Nothing is refused. - Bound blobs: the door's validate settings and facing probe, DoorOwned::bytes, the stage-3g validate blob of a plane's verb sections, and serve.rs `crossed` (open and both refresh paths) plus the owned sections. - busbar-contract: - SecretRef::template / template_text / resolve_template (SECRET_MODULE_TEMPLATE); - Program::secret_env holds a program's `env` references as references. - busbar-core-connector: install_spawn_secrets. Connection::spawn resolves `secret_env` there and nowhere earlier, a template's every `${VAR}` filled in place. A reference that does not resolve is refused, naming the variable and the source, never a value. - plugin-loader: member_programs no longer resolves `env` at the declare (MemberSecretFn and install_member_secrets removed). The root installs the linked secret resolver into the connector instead. REDs: - root planes_tests `an_interpolated_credential_reaches_a_door_plane_as_its_reference_never_its_bytes`; - kernel filled_tests; - connector `a_members_secret_environment_resolves_at_the_spawn` and `a_member_whose_secret_environment_does_not_resolve_is_not_spawned`; - contract `a_template_reference_resolves_each_variable_in_place` and `a_programs_secret_environment_is_held_as_its_reference`.
…not tie its output to its input)
…gram resolved at the spawn, not a RootCfg type
MattJackson
enabled auto-merge
October 10, 2026 06:08
This was referenced Oct 10, 2026
promote into
|
| gate | row | detail |
|---|---|---|
| test:xtask-selftest | ::xtask selftest kind-isolation |
|
| test:xtask-selftest | ::xtask selftest plane-purity |
|
| test:xtask-selftest | ::xtask selftest no-deferral-strict-done |
|
| test:xtask-selftest | ::xtask selftest plane-purity-strict |
|
| test:xtask-selftest | ::xtask selftest unconstructed |
|
| test:xtask-selftest | ::xtask selftest structure-lint |
|
| test:xtask-selftest | ::xtask selftest plane-transport-neutrality |
|
| construction | one-pick-site |
3 production call site(s) of 'pick_among(' (ceiling 2): crates/busbar-kernel-egress/src/walk.rs:358; crates/busbar-llm/src/engine/exhaustion/fallback.rs:120; crates/busbar-llm/src/engine/pipeline.rs:8 |
| kind-isolation | kind-isolation:deps |
3 finding(s), 92 shipped edge instance(s) over 29 class(es), 92 declaration(s); 55 '[[dep]]' row(s), 0 question(s): unlisted-dep-edge legacy -> plane busbar-llm -> busbar-plane-llm is a shipped edge w |
| kind-isolation-ship | kind-isolation:deps |
8 finding(s) over 92 shipped edge(s): ship-edge kernel -> store busbar-kernel -> busbar-store-memory is 'not-allowed': the architecture grants no kernel -> store edge, and the ship criterion is the ar |
| kind-isolation-ship | kind-isolation:test-deps |
5 finding(s) over 31 test edge(s): ship-edge cleanliness -> export busbar-core-admin -> busbar-export-prometheus is 'not-allowed': the architecture grants no cleanliness -> export edge, and the ship c |
| kind-isolation-ship | kind-isolation:faces |
2 finding(s) over 40 crate(s): foreign-entry crates/busbar busbar is kind 'root' and implements 'Transport' 1 time(s) in shipped source — the entry face of kind 'transport'. A trait implementation is |
| kind-isolation-ship | kind-isolation:legacy-drain |
3 finding(s): transitional-live qa/kind-isolation.toml 'busbar-a2a -> busbar-core-admin' (legacy drain: the retiring A2A engine's tests drive the admin surface that drained into the cleanliness tier) |
| ship-ready | ship-ready:ship-twin |
'kind-isolation-ship' is not green: kind-isolation:deps (a dependency the architecture does not grant is still in the graph); kind-isolation:test-deps (a dependency the architecture does not grant is |
| structure-lint | structure-lint:plane-dup:unledgered |
22 finding(s): PLANE-DUPLICATE (module): 'config.rs' — a2a:crates/busbar-a2a/src/a2a/config.rs decisions:crates/busbar-plane-decisions/src/config.rs voice:crates/busbar-voice/src/config.rs (the ledger |
tests passed: 24853, failed: 0. Run: https://github.com/GetBusbar/busbar/actions/runs/38348625115 . Artifact verdict-d39006c974a6bb30975ce674e42da480090a9e28 (failures.json, junit.xml, raw.log; 90 days).
…utralize test URLs
kind-isolation:law0 (18 -> 24, back to 18):
- Program::secret_env -> Program::env_refs. `secret_env` spells the secret-env
plugin's kind-qualified id: the new busbar-core-connector x secret cell and
the busbar-contract / busbar-kernel / busbar-plugin-loader x secret rises.
- SECRET_MODULE_TEMPLATE is "env-template", not "template": as a module-name
constant it made every "template" literal a secret instance name, including
the kernel's prompt `template` field in the config-schema snapshot.
- The kernel's new filled.rs / filled_tests.rs build `{ env: VAR }`, the
template reference and the program `env` key through the contract
(SecretRef, SECRET_MODULE_ENV, PROGRAM_KEYS) rather than as literals
(busbar-kernel x instance:secret back to 117).
- busbar-plugin-loader x instance:secret 111 -> 110: dispatch/plugin.rs no
longer edits a member's `env` map in place (law0-slack, lowered as the row
prescribes).
config-schema:snapshot-drift / selftest config-schema: the snapshot gains the
new `type SpawnSecretFn` alias (busbar-core-connector compose.rs).
instance-noun-neutrality:mcp: the filled / serve_planes test URLs end /v1, not /mcp.
Proved on Latchkey: gate kind-isolation (law0 at 18 findings, all standing
base offenders), gate config-schema (snapshot-drift PASS; baseline rows red
only because the dev checkout has no v1.5.3 tag), gate
instance-noun-neutrality (green), selftest config-schema (only failures are
the same missing-v1.5.3 baseline), busbar-kernel test target compiles. The
Latchkey run budget ran out before kind-isolation-ship (same law0 rule as
kind-isolation) and the contract/connector/loader/root test runs.
…ation:law0 30 -> 21) The law0 figure is hits off the [[law0]] ceilings, not findings. Against the base (50a31fb) this PR added 9 instance:secret hits: busbar +5 (four "env" literals in serve_planes.rs, and the fixture's new `extern "C" fn refresh`, whose "C" is the `c` secret alias), busbar-contract +4 (three "env" literals in conn_tests.rs and the SECRET_MODULE_TEMPLATE "env-template" declaration). - busbar-contract: the member program's `env` registration key is now one constant, conn::PROGRAM_ENV_KEY; PROGRAM_KEYS and Program::from_settings read it instead of spelling "env". - Tests write the `{ env: VAR }` reference through SECRET_MODULE_ENV and the member env key through PROGRAM_ENV_KEY (serve_planes.rs, conn_tests.rs, connector.rs). Net per cell against the base: busbar x instance:secret 37 -> 37, busbar-contract x instance:secret 133 -> 133; the remaining +1 in each (the fixture's `extern "C"`, the "env-template" declaration) is offset by the literals the constant replaces. No ceiling changes. Proof: `busbar-release dev cargo xtask gate kind-isolation` was refused by the Latchkey run budget (4000/4000). The counts above come from a line-for-line port of the gate's literal scanner (instances.rs literals/decoded_line/ join_adjacent_literals) run on base and candidate; it reproduces CI's own per-cell readings exactly (busbar 37 -> 42, busbar-contract 133 -> 137). Compilation and the touched tests are left to CI.
…et-refs # Conflicts: # crates/busbar-kernel/src/plane/door.rs
MattJackson
disabled auto-merge
October 10, 2026 09:58
MattJackson
added this pull request to the merge queue
Oct 10, 2026
MattJackson
removed this pull request from the merge queue due to a manual request
Oct 10, 2026
…not the declare predev's member_secret_tests.rs (plugin-loader) and root/tests/secret_source.rs (busbar) still installed the loader's declare-time resolver (install_member_secrets), which this branch replaced with the connector's spawn-time one (install_spawn_secrets); neither compiled (E0425), which broke build:check/clippy/workspace-compile and every test row that builds them. - member_secret_tests.rs: brings its own env_reference (the linked env source, as before); the member is declared with its reference unresolved (Program::env_refs, no value, nothing of the source's refusal handed to the table); the test table models the connector's spawn (a reference that does not resolve refuses the open), and the plugin still reads only ConnError::Refused's fixed text, nothing of the source. - secret_source.rs: installs the spawn resolver; the request-time cases are unchanged (the member is never spawned, the caller's render is clean). Across an apply, the program spawned while its reference resolved keeps serving the unchanged member (its value lives only in the child), and the caller's render stays clean of the source. Not proved on Latchkey: the run budget is spent (RUN_CAP), so the PR's CI is the proof. The xtask selftest rows (blocking-ffi, tracing, response-header, settings-leak) show no failure detail in the run log beyond the compile errors; they are expected to clear with the build. kind-isolation:law0 reads the same 11 hits / 5 findings as predev (#751); its armed red is the whole-row judgement of the turnstile build CI ran, which busbar-release 5a1380d replaced with the per-cell one (the one cell this branch moves, busbar-plugin-loader x instance:secret, sits at its new row of 110).
Collaborator
Author
|
Claim released by busbar-release: the |
…program through its carrier (host io.spawn), so a member's env references resolve inside the host's spawn and never cross into the carrier's destination
…kind-qualified secret id in the neutral connector: kind-isolation:law0 busbar-core-connector x secret back to none)
…dev's bound() hands it (no-silent-skip: a missing cdylib fails the cell, never skips it)
…lane the settings settings_of builds (the pools-map plane keyed at the root, any other at its section) and adds the pools-map plane's refresh crossing, so every crossing binds its credential positions at the settings' own path (settings_path): open, the config-apply refresh and the pools-map refresh
…instance:secret = 109 (predev OpenOnce -1 plus this PR's env-resolve -1, both cited)
…&["test_plane"]) the signatures now take
MattJackson
added a commit
that referenced
this pull request
Oct 13, 2026
Brings predev 350e107 (#727). Conflict: qa/kind-isolation.toml, busbar-plugin-loader x instance:secret: predev's row (109, its two drains cited) kept, with this PR's own delta applied: the extern-ABI scanner fix, -86 as measured on #787's tree (111 -> 25), so 109 - 86 = 23. Neither predev drain is an extern ABI string. The earlier 25 assumed #671's drain was one; predev's cite names it as the OpenOnce move, so it was not.
MattJackson
added a commit
that referenced
this pull request
Oct 13, 2026
Brings predev 350e107 (#727: a plane never receives secret bytes; open and handed_settings take the settings path). Conflict: crates/busbar/src/root/tests/serve_planes.rs, where both sides appended a test: this branch's catalog-route cell and predev's plane-bound credential cell are both kept; every open call there takes predev's path argument.
MattJackson
added a commit
that referenced
this pull request
Oct 13, 2026
…erged tree's shapes - main.rs config-apply DoorReach lends the shared resolver as Arc<dyn SecretResolve>, as boot does; - root tests door_steps own_reach, the a2a door's root cells: DoorReach names models: None; - serve_door_far: DoorFar names shown: None; - serve_planes: refreshed takes the resolver as Arc<dyn SecretResolve>; - kernel tests/plane_driver: Pick::Exhausted states its detail; REFUSAL_KERNEL is no longer used.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SECURITY. A door plane is handed a secret reference where it used to be handed a credential's plaintext. Carried onto predev from the orphaned #684 (it sat on #599 → #559 → #554 → #546 → p6-d2-kernel, whose #526 closed unmerged). Supersedes #684.
Authority.
BUSBAR-1.6.0.mdPart 0, THE DESIGN §6 "Trust boundary" (l.828-834 at predev 9c0a394): "A plane never receives secret bytes. Logs, audit records and metrics carry a secret's reference, never its value." Part 3 §4 (l.2415): "the plane passes a ref and NEVER holds plaintext". SECURITY rulings, 2026-10-07:What was wrong on predev.
${VAR}is spliced into the config text before it is parsed. Its plaintext then reached a door plane at every crossing:validate;opensettings and owned sections;refresh;A member's
envwas also resolved at the declare, not at the spawn.Changes
config::filled:${VAR}it filled. A record holds the path, the variables, the value as written and a per-process keyed digest. It never holds the value.plane_boundputs a reference at each credential position:{env: VAR}for a whole value, a template reference for a part. Only a value that still matches its digest is replaced.plane/door.rssettings_of, used by the doorvalidate(both paths) and the facing probe;DoorOwned::bytes;root/boot.rsvalidate_dealt(a plane's verb seats);root/serve.rshanded_settings, used byopenand the config-apply refresh;open.SecretRef::template/template_text/resolve_template, andProgram::secret_env.install_spawn_secrets.Connection::spawnresolves a member'ssecret_envat the spawn, and nowhere earlier.install_member_secretsandMemberSecretFnare removed. The root installs the linked secret resolver into the connector instead.openandrefreshto disk, and itsrefreshnow returns a snapshot.What changed from #684's diff. #684 bound the crossings that P1b (#670) had routed through the deal's strip. P1b is not on predev, so this binds the crossings predev has:
handed_settingsand the door'ssettings_of. It does not strip reserved keys; that is P1b, which is its own task. Its test plane drops thepool_affinityblob, which belongs to P1b-a.REDs
an_interpolated_credential_reaches_a_door_plane_as_its_reference_never_its_bytes: the open, owned and refresh blobs carry no plaintext and no resolved reference;filled_tests;a_members_secret_environment_resolves_at_the_spawnanda_member_whose_secret_environment_does_not_resolve_is_not_spawned;a_template_reference_resolves_each_variable_in_placeanda_programs_secret_environment_is_held_as_its_reference.Proof (Latchkey, this tree)
cargo check --workspace --all-targetsclippy -p busbar-contract --all-targets -D warningsclippy -p busbar-core-connector --all-targets -D warningsclippy -p busbar-kernel --all-targets -D warningsclippy -p busbar-plugin-loader --all-targets -D warningsclippy -p busbar --all-targets -D warningstest -p busbar-contracttest -p busbar-kerneltest -p busbar-core-connectortest -p busbar-plugin-loadertest -p busbarserve-framed-wildpublication under one-process cargo test). The 23rd is the new cell, refused by that same leaked publication ("admin route ... overlaps serve-framed-wild"); CI's test:workspace runs under nextest, one process per testRED: shown by #684 on its own base (
an_interpolated_credential...read the plaintext at all three blobs before the binding). On a Latchkey runner the one-test filter does not build the example cdylib, so the red/green pair for this cell is CI's.