8000 T38 — Run the egress gate and bep_host in an EGW process apart from the proxy · Issue #2285 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

T38 — Run the egress gate and bep_host in an EGW process apart from the proxy #2285

Open

Description

@norrietaylor

Task

slice size difficulty model who estimated lines
Proxy as the operator, VM as its own user L unknown ground strongest an agent 880 (520 code, 360 tests)

The proxy runs as the login user, and the EGW process, gvproxy and the VM run as separate processes sharing no writable state, as dedicated unprivileged users where the vm-users drop-in is installed.

Covers:

  • BEP-047

Layers:

  • egw:
    • crates/minvmd/src/cmd/egw.rs (new): the fixed minvmd subcommand the EGW process runs as minimal-gvproxy: reads the token, the box table, row withdrawals and attachments from the supervisor channel on descriptor 0, binds <gate dir>/gvproxy-gate.sock at 0660 group minimal-vmm, dials the switch socket and gvproxy-bep.sock, drops every frame and refuses every publish request until the first complete table, and exits when the channel closes (re-planned 2026-10-25 against the landed T57 design, docs(design): split-user VMM provider directory and socket ownership (T57) #2546)
    • crates/minvmd/src/cmd/mod.rs: module line
    • crates/minvmd/src/main.rs: the hidden EGW subcommand
    • crates/minvmd/src/net/egress_gate.rs: the gate runs in the EGW process, fed by the supervisor channel in place of in-process state
    • crates/minvmd/src/net/bep_stub.rs: the stand-in's credential check expects the minimal-gvproxy peer
    • crates/minvmd/src/cmd/run.rs: spawns the EGW process through sudo -n -u minimal-gvproxy in its own process group where the vm-users drop-in is installed, and as a separate login-user process where it is not (gominimal/arch#143), hands it the supervisor channel (a socketpair on descriptor 0), and stops it with the design's sequence: shutdown(SHUT_WR), SIGTERM relayed by sudo, the stop rule, a 5 second bound, and the fail-closed result when no exit comes
    • crates/bep/src/listener.rs: bep serve binds gvproxy-bep.sock at 0660 group minimal-gvproxy, admits the minimal-gvproxy uid in place of its own and keeps the token check
    • cargo nextest run -p minvmd bep_and_gvproxy_are_separate_processes_and_users
    • cargo nextest run -p minvmd egw_withdrawal_waits_for_the_observed_exit_and_fails_closed

Waits on:

Plan block
### T38 — Run the egress gate and bep_host in an EGW process apart from the proxy
  slice: S8
  kind: integration
  covers: BEP-047
  size: L
  est: 520 code, 360 tests
  executor: agent
  difficulty: unknown ground
  model: strongest
  diagnostics: when the EGW process cannot start, or exits while boxes run, the VM host daemon fails closed: the withdrawal answer is failed, the VMM child stops, a later registration is refused, and the daemon exits non-zero with a line naming the EGW process
  observability: one info log line at start naming the user each of the proxy, the EGW process, gvproxy and the VM runs as
  layers:
    - egw:
      - crates/minvmd/src/cmd/egw.rs (new): the fixed `minvmd` subcommand the EGW process runs as `minimal-gvproxy`: reads the token, the box table, row withdrawals and attachments from the supervisor channel on descriptor 0, binds `<gate dir>/gvproxy-gate.sock` at 0660 group `minimal-vmm`, dials the switch socket and `gvproxy-bep.sock`, drops every frame and refuses every publish request until the first complete table, and exits when the channel closes (re-planned 2026-10-25 against the landed T57 design, #2546)
      - crates/minvmd/src/cmd/mod.rs: module line
      - crates/minvmd/src/main.rs: the hidden EGW subcommand
      - crates/minvmd/src/net/egress_gate.rs: the gate runs in the EGW process, fed by the supervisor channel in place of in-process state
      - crates/minvmd/src/net/bep_stub.rs: the stand-in's credential check expects the `minimal-gvproxy` peer
      - crates/minvmd/src/cmd/run.rs: spawns the EGW process through `sudo -n -u minimal-gvproxy` in its own process group where the vm-users drop-in is installed, and as a separate login-user process where it is not (gominimal/arch#143), hands it the supervisor channel (a `socketpair` on descriptor 0), and stops it with the design's sequence: `shutdown(SHUT_WR)`, SIGTERM relayed by `sudo`, the stop rule, a 5 second bound, and the fail-closed result when no exit comes
      - crates/bep/src/listener.rs: `bep serve` binds `gvproxy-bep.sock` at 0660 group `minimal-gvproxy`, admits the `minimal-gvproxy` uid in place of its own and keeps the token check
      test: cargo nextest run -p minvmd bep_and_gvproxy_are_separate_processes_and_users
      test: cargo nextest run -p minvmd egw_withdrawal_waits_for_the_observed_exit_and_fails_closed
  produces: none
  consumes: none
  proof: The proxy runs as the login user, and the EGW process, gvproxy and the VM run as separate processes sharing no writable state, as dedicated unprivileged users where the vm-users drop-in is installed.
  depends on:
    - blocked by T19
    - blocked by T57
    - blocked by T65
    - blocked by T66

Generated by Claude Code

Activity

  1. added
    kind:taskA task the plan skill rendered; the body carries ## Task
    size:M200 to 500 net lines; one PR
    model:strongestThe strongest model available: unknown ground, or large work that needs care
    on Oct 17, 2026
  2. minimal-foundry commented on Oct 24, 2026

    @minimal-foundry
    Contributor

    **The coder changed nothing: noop: the task cannot be done inside its layers, and two of its layer notes contradict each other. All seven layer paths exist at the branch head. No path is marked (new).

    1. The VMM child cannot run as another user unless files outside the layers change. minvmd __krun-vmm (crates/minvmd/src/cmd/vmm_child.rs) opens the kernel, rootfs and initramfs (image.rs). It creates the data volume (volume.rs, ensure_sparse_raw), writes the boot log, and registers the vsock UDS paths: the marker socket, the guest report door, the telemetry door, the gate socket (vm.rs:452) and the ssh bridge socket. All of these are in the provider dir. sock::prepare_socket_dir makes that dir 0700, and sock::verify_provider_dir_ownership requires it to be owned by the caller's uid. sock::enforce_socket_permissions makes each socket 0600, so min, running as the login user, cannot reach a bridge socket that a dedicated-user VMM binds. A VMM started through sudo -n -u <user> fails at its fir…[truncated]. No pull request was opened.**

    branch agent/2285-run-gvproxy-and-the-vm-as-a-dedicated-unprivileg · epic #1501

    Updated 2026-10-24T23:57:45.508Z.

  3. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  4. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  5. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  6. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  7. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  8. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  9. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 24, 2026
  10. 1 remaining item

  11. changed the title [-]T38 — Run gvproxy and the VM as a dedicated unprivileged user apart from the proxy[/-] [+]T38 — Run the egress gate and bep_host in an EGW process apart from the proxy[/+] on Oct 25, 2026
  12. added
    size:L500 to 900 net lines; one PR, and the ceiling
    and removed
    size:M200 to 500 net lines; one PR
    on Oct 25, 2026
  13. norrietaylor commented on Oct 25, 2026

    @norrietaylor
    MemberAuthor

    Re-planned and split on 2026-10-25 by the epic owner's decision, against the design T57 landed in #2546 (docs/design/2026-10-25-split-user-vmm-provider-dir.md). Arch ruled a three-user model there: the egress gate and switch::bep_host run in an EGW process as minimal-gvproxy, fed by a supervisor channel, with a sudoers stop rule and a fail-closed stop sequence. Its "What T38 changes" section touches about 14 files, past the runtime's ten-file cap, so the work is now two tasks:

    S8's observable now names three dedicated users, matching the ruling. The old two-user layers (and the crates/bep/src/control.rs widening, which the design leaves unchanged) are gone. needs-human is removed; the runtime dispatches this task once #2560 lands.


    Generated by Claude Code

  14. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 25, 2026
  15. norrietaylor commented on Oct 25, 2026

    @norrietaylor
    MemberAuthor

    Held by the epic owner on 2026-10-25 until arch rules on gominimal/arch#143 (where minvmd, gvproxy and the provider dir live when the default install is per-user). T38 now also waits on #2566 (T66, the sudo -n spawns), split from T65.


    Generated by Claude Code

  16. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 25, 2026
  17. norrietaylor commented on Oct 26, 2026

    @norrietaylor
    MemberAuthor

    Amended on 2026-10-26 after the epic owner's ruling on gominimal/arch#143 (https://github.com/gominimal/arch/issues/143#issuecomment-6409882754). The EGW process runs as minimal-gvproxy where the vm-users drop-in is installed, and as a separate login-user process where it is not. The proof and S8's observable say the same. The hold on arch#143 is lifted. This task still waits on #2566 (T66).


    Generated by Claude Code

  18. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 26, 2026
  19. norrietaylor commented on Oct 31, 2026

    @norrietaylor
    MemberAuthor

    Deferred on 2026-10-31 by the owner in the #1501 close-out. This task leaves slice S8 (#2256) and the #1501 plan. The split-user work moves to the follow-on epic gominimal/inbox#1184, with BEP-047, which spec 24 moves to Non-goals in #2768. This issue stays open for that epic to take.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadat 5356 a

Metadata

Assignees

No one assigned

    Labels

    kind:taskA task the plan skill rendered; the body carries ## Taskmodel:strongestThe strongest model available: unknown ground, or large work that needs careplan:integrationOwns the seam of a slice; its proof is the slice's observablesize:L500 to 900 net lines; one PR, and the ceiling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0