Skip to content

microVM JIT credential mint + jail staging - #11878

Closed
gunbai-bot[bot] wants to merge 46 commits into
mainfrom
mb816
Closed

gunbai-bot[bot] wants to merge 46 commits into
mainfrom
mb816

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session keen-bear-791.
Pushing to mb816 advances this PR.

Worker attestation

Before flipping this PR to ready for review, confirm each item:

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (replace the TODO below).
  • Tests run: name the command (e.g. npm test, cargo test) and the result.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises (no fork/cherry-pick I did not make).
  • No secrets / credentials / large binaries staged.

Summary

TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.

Test plan

  • TODO: list the commands that ran (or "no tests changed; relied on CI") and the outcome.

gunbc-ci-auto-heal and others added 30 commits September 19, 2026 02:56
Close jit_mint_http_realization_frontier and jail_jit_device_staging_frontier.

- extdeps.auth.jws: RFC 7515 compact JWS signing input + RS256 (RFC 7518 3.3).
- extdeps.tools.openssl: enrolled host CLI dependency; openssl dgst -sha256 -sign
  <key file> -hex, signing input on stdin, no secret in argv.
- extdeps.github: POST app/installations/{id}/access_tokens and org
  generate-jitconfig as REST operations on the #10923 performer.
- gunbc.github_effect_perform: the effect home; perform_organization_jit_mint
  signs the App JWT on the host with the controller-custodied key, mints the
  installation token and the JIT config, and returns a typed performance
  (commit-ambiguous generate is its own arm).
- gunbc.runner_attempt_launch: admits a credential only from a delivered,
  attempt-bound, floor-to-ceiling mint; the jit device and the jailer are one
  plan arm, so no admitted credential means no device and no VMM. The device
  is install -m 0400 -o <attempt uid> before any byte, written via the
  filesystem, NUL-padded to whole sectors, read back. Registration id and
  runner name are recorded on the launch.
- Drop the out-of-jail jit.img path fork (runner_microvm_attempt /
  runner_jit_mint / runner_jit_perform): the device location has one owner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… receipt

Adds gunbc.microvm_controller_app_key_converge, enrolled as fleet-converge mode
microvm_controller_app_key_converge (one runner host per dispatch). It reads
gunbai_ci_app_pem_secret through the typed fetch_secret_ref_credential over the
run's WIF token, ensures the key directory is root:root with no group/other bits,
writes the key through converge_typed_remote_file under sudo at mode 0400 (new
RemoteFileModeOwnerRead arm), removes the far-side staging sibling and reads its
absence back, then reads back owner, mode, directory, ancestors and bytes
(far-side cmp against the SM version). The receipt never carries the bytes.

The runner-owned /etc/actions-runner/app.pem is untouched and recorded as the
custody this narrows. Nothing selects the microVM path for the floor job.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…y, HostMintAdmission checker

- Credential size refusals carry ByteSize and compare through measure_le again.
- ci_spec's two App-JWT preludes take the RS256 header from extdeps.auth.jws and
  the claim JSON shape from github_app_jwt_claims_json_of (printf placeholders);
  emitted bytes unchanged.
- runner_jit_admission: X's HostEnvelopeNonemptyAndFresh becomes HostMintAdmission,
  and admit_jit_credential consumes the roster (refuses if it stops requiring it).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…erge mode

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…_devices alias

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… scope

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…eNameRead)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ack mode from one row (review 68264)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…re Secret (review 68283)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ion body (parse: annotation at module-item grain only)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… keep clock notes attached (review 68318)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e_destination from the resolved arms

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… prelude consumes jws/claims authorities

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…Ref/JwsSignOutcome); openssl is one handler in gunbc.jws_signer_realize (CRYPTO-0/PRIMITIVE-EGRESS-0 shape condition)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ntent on the jail device

- JitDeviceStaging carries the guest contract bytes (one jitconfig env line,
  newline-padded to 512-byte sectors); the NUL-pad truncate step and
  truncate_to_size_command are deleted (a second authority for the drive format).
- Readback checks size == the content's own UTF-8 size; a failed stat is its own
  refusal carrying stderr (review 68502).
- Witness pins staged bytes to jit_drive_content AND to its documented shape.
- Keep the deletion of jit_mint_http_realization_frontier / jail_jit_device_staging_frontier;
  runner_guest_image's acceptance trigger now names the performer and the stager.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…igning-key ref

#11677 wrapped the path in JwsSigningKeyRef HostKeyFile, deleting the bare
lifecycle_controller_app_key_path this module imported, so both the entry and its
witness failed to resolve. signing_key_file_path matches the one arm that names a
file on this host.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…(review 68653 note)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…h fork (reviews 68668, 68670)

- jit_credential_bytes uses runner_microvm jit_drive_utf8_size, the same measure
  the readback uses; string_length counted code points and labelled them bytes.
  New claim: 65536 two-byte code points are at the ceiling in characters and over
  it in bytes, and are refused.
- JitMintPlan.endpoint_path was produced and discarded (the POST path is the
  operation's own template), so the field and org_generate_jitconfig_path go; the
  org stays an operation input, which is what keeps a caller off another org.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…kspace staging) into #11677

Resolution keeps both sides: the JIT fields and device staging on LaunchAuthorized,
and #11675's tap-grain egress (no nft_ruleset field), guest network boot args, and
workspace staging gate. staging_verdict destructures the new fields and matches the
renamed refusal arm; #11675's four workspace witnesses are restored over the mint
parameter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…eceipt

The workspace gate (#11675) and the jit device (this PR) landed on opposite
sides of a merge, and the join took only the workspace observation: a mint
accepted, LaunchAuthorized built, the credential device failed to stage or never
staged, workspace ready -> jailer admitted. That is the guest-with-no-credential
burn this planner exists to prevent (sunny-ant-606 hold).

- attempt_staging_verdict(plan, jit, workspace) replaces staging_verdict. It
  admits only when the device staged AT THE PATH THIS PLAN NAMES and the
  workspace is ready; StagingRefusedJitDevice, StagingRefusedForeignJitDevice,
  StagingRefusedWorkspace and StagingNotAuthorized are distinct.
- The jailer is reachable only inside AttemptStagingReceipt, a sole_constructor
  the gate alone produces, so 'staging passed' cannot be minted beside it.
- Controls: ready workspace + failed device refuses; ready workspace + a sibling
  attempt's staged path refuses; the admitted receipt names this attempt's paths.
- review 68748: the App-custody guard gets its red -- the shared dispatch fixture
  is another App, so an authorized dispatch for it refuses before any I/O.
- jws.dag: keep the signature-octets note attached to jws_compact_serialization.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbc-ci-auto-heal and others added 16 commits September 20, 2026 04:15
… enrolment) into #11677

Resolution: the plan keeps my JIT fields, device staging and both-stagings gate,
and takes #11672's RunnerMicroVmShape parameter, runner_microvm_workspace_grant
and with_boot_arg rename. The rosters and argv admissions are additive unions;
my signer roster becomes the FOURTH enrolment answer beside main's gh one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… unterminated function body)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rations carried through merges

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ledger-Repair-Judged: docs/design-rung-drops.md
Ledger-Rows-Repaired: docs/design-rung-drops.md namespace_wave_admission_wall_removed
Heal-Candidate-Run: 35490123999
#11677's jail-interior device does not leave #11670's teardown join importing a deleted symbol
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ion/merry-bear-816

# Conflicts:
#	.github/workflows/fleet-converge.yml
#	dag/gunbc/fleet/fleet_converge_workflow.dag
…ion/merry-bear-816

# Conflicts:
#	.github/workflows/fleet-converge.yml
#	dag/gunbc/fleet/fleet_converge_workflow.dag
# Conflicts:
#	.github/workflows/fleet-converge.yml
…idence)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	.github/workflows/fleet-converge.yml
#	dag/gunbc/fleet/fleet_converge_workflow.dag
It moved to gunbc.actions_run_binding; the stale import resolved only under a
compiler built before that move.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	.github/workflows/fleet-converge.yml
#	dag/gunbc/fleet/fleet_converge_workflow.dag
@gunbai-bot

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Closing: this PR was opened automatically from a local working branch (mb816) that the session auto-push published by accident. It is not a change proposal — the actual work is #11679 (MicroVM controller App-key custody converge), whose main-merge conflict I resolved and pushed to session/merry-bear-816. Deleting the stray branch.

— sent from keen-bear-791

@gunbai-bot gunbai-bot Bot closed this Sep 20, 2026
@gunbai-bot
gunbai-bot Bot deleted the mb816 branch September 20, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants