Skip to content

Epic: controlled egress, credentials and outward actions #1645

Open
22 of 25 issues completed
Open

Description

@schlessera

Part of #1636. Guardrail classes: G2 (data exfiltration), G5 (outward actions) and G6 (untrusted input and persistence).

Outcome

Agent workers:

  • see no brain secrets;
  • reach the network only through a recorded, limitable proxy;
  • send policy-restricted paths only to the providers the policy allows.

Outward actions taken in the user's name ask first unless the policy allows them. These include git push, GitHub posts, mail, bookings and payments. A session that ingested untrusted content runs under tighter egress and outward rules, and its steering writes are flagged.

Why now

#1636 ruling 4 asks for egress recording and limits. The maintainer's 2026-10-11 additions add outward actions, untrusted input and data-to-provider routing.

Shared context

Constraints and non-goals

  • No TLS interception.
  • Inside the brain, nothing is outward.
  • This epic does not widen autonomous authority.
  • Off-proxy egress tightening for tainted sessions is not available and is documented as such.

Binding rulings

Breakdown

Delivered: #1664 (outward approval), #1665 (private network, egress proxy and host relays for Claude and Pi), #1666 (provider keys withheld from workers), #1667 (session taint), #1674 (sync mirror), #1677 and #1894 (separate-UID workers), #2633 (/var masks), #2284, and the native maintenance prerequisites (#2250, #2268, #2270, #2296, #2297, #2300, #2301, #2312, #2343, #2345, #2347, #2354). #1668 closed after its last required 0.44.0 delivery, #2725 in merged #2917 (800d965ba), under the explicit maintainer completion ruling; the mount-record and masked fallback-CLI investigations remain standalone 0.45.0 follow-ups #2701/#2865, not repaired by that closure.

Remaining:

  1. ui-server: let the user mark a file untrusted so reading it taints the session #2673 — let the user mark a file untrusted so reading it taints the session (p0; revision 3 plus unchanged revision 2 approved, implementation/proof open).
  2. ui-sdk: the worker socket walk misses a socket bind-mounted onto a file path #2745 — the worker socket walk misses a socket bind-mounted onto a file path.
  3. backends: run the Claude turn egress relay on hosts without managed native storage #2654 — run the Claude turn egress relay on hosts without managed native storage (p2, deferred follow-up; not required for the managed-storage outcome).

Definition of done

  • The egress measurement table is committed, and egress is recorded and limitable on managed-storage hosts for Claude and Pi, with the inactive state reported elsewhere.
  • A governed worker holds no provider credential its own inference does not need.
  • Outward actions appear in the journal as irreversible and ask first unless the policy allows them.
  • A tainted session runs under the tighter rules and flags its steering writes.
  • Epic: policy-restricted content reaches only allowed providers #1668's definition of done is met.

2026-10-24: consolidated to the current outcome, rulings, remaining children and definition of done; #1665, #1666 and #1667 are closed, so the old prerequisite chain and stacked "Current" handoffs are gone. The dated handoffs moved to a comment.

2026-10-24 continued triage at main dc5d3c73282c29a3f0098306d398743ee18ec791: Refreshed HOST_MASKS to its declaration; all managed-storage egress, residual-disclosure, provider-routing and user-marked-input prerequisites remain. Existing child needs and deferred non-managed work stay scoped; no new worker or provider proof.

2026-10-24 triage at main af6300478a07379178bd30221a31c0b917df2283: Refreshed moved current-source pointers by inspecting their named anchors. Historical receipts retain their source identities; scope, rulings, priorities and outstanding prerequisites are preserved. No runtime result or readiness is inferred from this navigation repair.

2026-10-24 triage at main e1ab485669565554ca6cb61ce5d130303647230f: Updated the active #2673 handoff to the new approved interaction while preserving all G6 policy/disclosure rulings. The child is implementation-ready; no taint-mark delivery or epic completion is claimed.

2026-10-25 triage at main c670449d3bf1b0639e50ce554d728961f4313add: Reconciled the recorded #1668 completion ruling with the delivered #2725 cache relocation and verified squash ancestry. Removed that closed child from remaining work while preserving standalone follow-ups, the native child history and the other open G6/socket/egress obligations. This does not close the parent or claim a new integrated test run.

Activity

  1. added
    area: ui-sdkWire protocol, runtime schemas, the server and client SDK surfaces.
    area: ui-serverHono app factory: turn coordinator, auth, session catalog, routes, cron.
    area: backendsAgentBackend implementations and the seam they share.
    priority: p1Scheduled into the current or next milestone.
    epicA tracking issue. The work lives in its sub-issues; this one is never coded directly.
    securityAuth, isolation, egress, secrets, or anything in the threat model.
    on Oct 11, 2026
  2. added
    type: featA new capability or a change in user-visible behaviour.
    on Oct 11, 2026
  3. schlessera commented on Oct 11, 2026

    @schlessera
    OwnerAuthor

    2026-10-11 triage: Classified the native child epic as feat and verified its source/draft provenance. Preserved its independently preparable work and real child prerequisites without inventing a need or epic readiness.

  4. 33 remaining items

  5. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    2026-10-22 maintainer-ruling reconciliation: #2633 selects option A, masking all of /var (including /var/tmp) for governed, strict and maintenance workers. Updated the active handoff to remove the obsolete pending A/B/C decision. Child implementation, fixture controls, compatibility/isolation proof and the existing decision-record amendment remain outstanding; the epic is not ready or complete. Preserved ownership and #2284’s explicit stop.

  6. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    2026-10-22 triage: recorded #1665’s later managed-storage-only activation ruling and attached #2654 as the separate non-managed Claude relay follow-up. The open #2645 composition is its actual prerequisite. This preserves the narrowed current P0 scope, the separate p2 follow-up, all-/var masking and #2284’s stop; it does not claim stack delivery, startup qualification or epic completion.

  7. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    2026-10-22 triage: reconciled #2284’s closure through merged #2558 and the later option (c) ruling, replacing obsolete active stop/unresolved wording. Legacy fallback now refuses before spawn under active/retained/unknown provider folder policy; the pre-policy admitted-descendant limitation remains explicit. The fresh scoped delivery does not qualify the stopped mitigation or prove universal writer lifetime, and #1668/full epic acceptance remain open. Preserved other ownership, P0 requirements and release attribution; no new native/hosted proof.

  8. schlessera commented on Oct 22, 2026

    @schlessera
    OwnerAuthor

    2026-10-22 delivery reconciliation at main aeaaf7794b6be41fde4e01bef78ce3f1a5828ac6: #2633 is closed through merged #2657 (5b34b6f2460bda675ea0302e0bb90119c1f4ba81). HOST_MASKS (packages/ui-sdk/src/server/worker-launcher.ts:136) now masks all of /var, including tmp/spool and future layouts, for governed, strict and credential-free maintenance workers. Explicit required runtime files remain read-only binds; relocated fixtures preserve independent socket/database/token controls. The merged PR records complete filesystem socket-walk and mutation receipts; these are attributed worker results, not new triage runtime proof. This delivers the selected option A, without establishing #1665’s remaining relay/activation qualification or completing this epic. Existing #2654 follow-up scope and #2284’s refusal boundary/pre-policy-writer limitation remain unchanged.

  9. schlessera commented on Oct 23, 2026

    @schlessera
    OwnerAuthor

    2026-10-23 triage at main f3c6fdc9f9c6321fda5a384cf8cfd8bf2e4846da: folded merged managed-storage subscription-Claude egress and #1667 taint delivery into the active dependency handoff. Preserved #1665’s Pi/API-key/mail/native-record remainder, its owner and settled October 23 Pi rulings, #1666→#1673, #1668 and native #2673’s unapproved design. #2654’s prerequisite is delivered. Attributed PR/native/mutation receipts are not a fresh triage run or complete security outcome; this epic stays open without agent-ready.

  10. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    History moved out of the body on 2026-10-24, when the body was consolidated. These sections were current at their dates; the body now holds the current rulings and breakdown.

    Current identity delivery — 2026-10-16

    #1677 is delivered by #2069 / 7d1a31d09b96739a85bff5151cc2e1300c9ac4d0 for 0.44.0. The optional configured helper/broker now provides verified separate-UID execution, authenticated descriptor authority, bounded retained mounts/private-file readers, native checkpoint/stage integration, verified-tree signalling and owned cleanup/accounting. Public hosting-template #18 owns production packaging; brain-kit ships the protocol and test fixtures. No-helper mode retains explicit shared-UID/mask-only disclosure, and option E retains best-effort recovery, external-reference and physical-reclamation limits. The earlier dated pending-implementation statements are historical.

    #1666 supported inference credentials and #1668 policy routing remain open; #1667’s taint enforcement is delivered, with user-marked files remaining in native #2673. #2284’s selected no-fallback-under-folder-policy boundary is delivered through #2558; the documented pre-policy admitted-descendant limitation remains. #1665 is reopened under retained ownership for its unfinished ordinary-inference delivery; consume the current owner handoff below. Identity delivery neither completes these nor widens autonomous authority.

    Current coordinated dependency handoff — 2026-10-23

    The P0 #1636 outcome still requires the complete #1645 security/egress and #1646 paid-provider budget outcomes. The remaining required-output chain is #1665, #1666, #1668 and #2673; #2284’s selected refusal boundary is delivered. #1646 still requires #1673 downstream of #1666. Preserve P0 across these actual prerequisites, release attribution and independent ownership.

    Merged #2399/#2644/#2645 deliver durable egress recording, first-party measurements and default proxy/host-relay activation for governed and strict subscription-Claude turns on managed native storage (086db5b20dd091f1a2864507eacf6dd207b74560). Pi, API-key Claude and non-managed hosts retain the stated coverage gaps. #1665 remains open under its existing owner for Pi/API-key relay consumers, built-in mail-submission outward defaults and native-harness per-connection assertions; no acceptance criterion is reduced. #2654 is the explicitly approved non-managed-host follow-up and its #2645 prerequisite is now merged. #1666 remains blocked on #1665; #1673 remains downstream of #1666.

    #1667 is closed through merged #2676 (8f7430cd6): web tools, inbox/workspace reads, external MCP results, the existing shell rule and non-relay proxy connections establish sticky session taint. Both backends ignore outward.allow while tainted; where the proxy is active, new connections must also match taint.egress.allow or an already-contacted host. Off-proxy egress tightening remains explicitly unavailable. User-marked files were split by maintainer ruling into native #2673, which remains needs: design; its current prompt is usable and no UX choice is approved here. #1668 routing remains open and no longer waits on #1665’s undelivered remainder.

    The October 23 Pi relay ruling is already recorded on #1665 (comment 6360183688): native host getAuth on each dispatch, credential-shaped placeholders, qualified API-key/OAuth matrix, exact-origin checks, and actionable refusal before launch for command-sourced or unsupported credentials on managed storage. It authorizes the owner’s implementation and durable record; it is not merged Pi delivery or a new unresolved decision.

    #2361 is merged and closes its five native maintenance prerequisites. #2364 is now closed by #2616 (cb86cb7c623328b8a6b2cc42a1baa9e514b5ac1b). Its bounded trusted read collects only nested .gitattributes below validated server-owned withheld directories in the retained checkpoint, preserving private modes and worker authority. The decision record and attributed native controls are delivered; that correction does not complete egress or the integrated security outcome. #2284 is now closed through #2558 (6c5a4f40219c05e7f621b554589d1c19c16b2273) under the later option (c) ruling. The earlier automatic-review stop remains historical; delivery is the fresh scoped no-fallback-under-folder-policy correction, not acceptance of the stopped mitigation or universal descendant-lifetime proof. No complete security, paid-CLI or integrated programme outcome is claimed. Earlier dated closure/handoff statements are historical.

    Current triage handoff — 2026-10-11

    Source inspected at main 02d4eb0ce37f621764a80636e8ac95b9b4d19d3c. That earlier snapshot predates #1676. The record and supersession notes are now delivered; consume the delivered-record handoff below. Do not imply its runtime outcome is implemented. Verified inference-relay.ts:25-33 supplies an observe hook and workerCommand applies unshare-net only to restricted turns at :143. A proxy plan is not proof every first-party path is captured. #1665 explicitly measures first and truthfully gates default-on/coverage; this investigation can start without inventing a complete table or new permission policy. Credentials, outward actions, taint and provider-route copies require actual denial/runtime proof; no TLS interception or autonomous widening.

    No new needs label is invented for this epic: its scoped deterministic implementation/measurement work can prepare now. Actual child prerequisites remain on their own tasks; an epic itself never becomes agent-ready.

    This is a logical child epic of #1636 with its native task hierarchy already established. Type: feat describes the new behavior; preserve its recorded priority, areas, parent and assignments. Never agent-ready, and no epic-level blocked label is inferred solely from a child's dependency. Complete Definition of done also requires the corresponding documented outcome and integrated proofs, not just closed child states. New arrivals outside the finite snapshot wait for another triage pass.

    2026-10-11 identity integration at main 8da5c4213e55afbfe47039d13a33d6943a026c16: native #1677 owns the optional host identity helper and real inside-worker negative/positive controls; public hosting-template#18 supplies packaging and depends on that kit output. #1638’s confirmed warning/docs scope does not implement the helper or solve same-uid server-state reads. rootProcCover :114-116 now protects writes, but launcher :142-151 still exposes ordinary read-only host root and shares network. Preserve the identity/no-helper disclosure and exact mask/provider/relay proofs; no delivered egress or uid-separation claim is inferred.

    Delivered record and settled default/identity handoff — 2026-10-12

    The decision record docs/decisions/governed-writable-workers.md is delivered by #1676 (squash b21428aa), an ancestor of inspected main acec591c83a730e5d68f36bae2b807f95bb5d9c9; its named supersession notes are present in policy-write-boundary.md and async-collaboration.md. This is a delivered design/architecture record, not a shipped governed runtime. Consume the record and the later maintainer ruling: governed is the 0.42.0 default despite interim maintenance-worker credentials, with truthful host-status disclosure; it remains available without the separate-uid helper using mask-only protection and explicit status, while the hosting template always supplies its helper. The record’s delivered “Settled release defaults” section already folds in both questions; no pending record amendment remains for them. No new ruling is required for them.

    Existing interaction design prerequisites and native child ownership remain. All proposed runtime guards need their actual integrated tests; record delivery and policy approval do not prove profile activation, journaling, isolation, budgets or egress. This epic remains open without agent-ready.

    2026-10-12 record read-back at main 6f74aaa19d6707db95401649113e65c47787b27a: docs/decisions/governed-writable-workers.md:1409-1416 now records the final release defaults explicitly. Removed the superseded request for a later implementation PR to add them; runtime/design prerequisites remain unchanged.

    Updated 2026-10-12: applied the approved epic scope/ownership clarification; preserved detailed outcomes, criteria, exclusions, decision links and recorded rulings.

    2026-10-15 record reconciliation at main d9ac37b82700d7b45406ba47c0850ae46251fa9b: #1894 is delivered by #1992 / 090c8a5463effe6811742259bc27af2b5ff6e66c. The governed-writable-workers, policy-write-boundary and native-brain-storage records now explicitly specify the external separate-uid broker/supervisor, narrow-helper authority and option E best-effort recovery/external-reference limits. This supersedes the old direct-procfs and absolute reclamation implications, while preserving budgets, optional no-helper disclosure and actual runtime qualification. #1677 still owns implementation and integrated second-uid/lifecycle/authorization/recovery proof; public hosting-template #18 owns downstream packaging. Record delivery is not runtime delivery, and the epic remains open without agent-ready.

    2026-10-16 triage at main 7d1a31d09b96739a85bff5151cc2e1300c9ac4d0: folded verified identity delivery into the current specification after reading #1677's closure, merged #2069 and the landed implementation/operator record. The closure reports integrated offline second-UID/Btrfs and lifecycle/negative/mutation proof under the maintainer's local-qualification waiver; hosted CI was queued. Preserve every remaining child outcome and epic-not-ready status; no independent full hosted green, production helper installation or universal confinement is claimed.

    Correction 2026-10-17: reconciled the closed-but-undelivered #1665 prerequisite, current P1 child ownership and active native maintenance PR; preserved the original outcome, exclusions and historical evidence.

    Correction 2026-10-17: aligned all required open children with this epic's P1 priority under the blocker-priority ruling; the former P2 exclusions are superseded.

    2026-10-22 triage at main fbcfddf33b8b4bc93bbd898e121909ccb4bbaa0f: reconciled #2364’s completion through merged #2616 and the current governed-worker decision amendment. Native #2633’s P0 host-socket policy is now settled by the October 22 maintainer ruling: option A, mask all of /var for governed, strict and maintenance workers, including /var/tmp, preserving required explicit read-only runtime inputs and meaningful compatibility/isolation controls. #2633 delivered implementation, fixture relocation and the durable decision-record amendment through merged #2657 (5b34b6f2460bda675ea0302e0bb90119c1f4ba81); the ruling does not establish #1665’s no-reachable-host-socket gate. Preserve #1665’s implementation ownership and #2284’s separately delivered refusal boundary and pre-policy-writer limitation. No new native/hosted proof or complete programme outcome is claimed.

    2026-10-22 ruling reconciliation: #2633’s option A is selected and its decision prerequisite is resolved. That child is now closed through merged #2657; its source delivery and attributed socket/compatibility receipts are separate from the remaining #1665 activation proof; this epic’s outcome and readiness are unchanged.

    Activation scope and non-managed follow-up — 2026-10-22

    The later #1665 maintainer ruling authorizes default egress only on managed-native-storage hosts. Other supported governed/strict hosts keep their current no-proxy behavior, visibly reported inactive and documented. That approved subscription-Claude managed-storage activation is now merged through #2645; the complete #1665 outcome remains unfinished as specified in the current dependency handoff above.

    Native #2654 owns the separate non-managed-host Claude relay expansion and startup-input proof, with its #2645 prerequisite now merged. Its complete scope advances this epic’s egress outcome, so it is attached here. It is an unscheduled p2 follow-up, not a newly inferred blocker of the narrowed P0 #1665 activation. Preserve Pi’s separate work, #2633’s selected all-/var mask rule and #2284’s separately delivered refusal boundary and pre-policy-writer limitation. Native/checkpoint authority and credential/input guards remain mandatory.

    Scoped host-fallback delivery — triage 2026-10-22

    #2284 is closed by merged #2558 (6c5a4f402), present on inspected main 30c1d50aec53d2e58da4fca3184582869b5895a6. The selected boundary refuses legacy never-governed host fallback before any process starts when provider folders are active, retained by an active writer, or unknown; it covers gated/ungated complete, streaming and synchronous paths. Existing peer refusals keep their ordering, and valid no-folder policy keeps fallback available. The decision amendment in docs/decisions/governed-writable-workers.md preserves the limit: a descendant from legacy work admitted before any folder policy existed is not retroactively tracked or terminated by this correction.

    The PR attributes actual owner-crash/detached-descendant failing-first controls, restored mutations and local preflight to its recorded source. This triage verified source, merge and closed state; it ran no new native or hosted proof. #1668 and the full security/programme outcome remain open; neither this scoped refusal nor the earlier stopped investigation proves complete all-writer lifetime safety. Preserve other ownership, P0 requirements and release attribution.

    2026-10-22 delivery reconciliation at main aeaaf7794b6be41fde4e01bef78ce3f1a5828ac6: #2633 is closed through merged #2657 (5b34b6f2460bda675ea0302e0bb90119c1f4ba81). HOST_MASKS (packages/ui-sdk/src/server/worker-launcher.ts:136) now masks all of /var, including tmp/spool and future layouts, for governed, strict and credential-free maintenance workers. Explicit required runtime files remain read-only binds; relocated fixtures preserve independent socket/database/token controls. The merged PR records complete filesystem socket-walk and mutation receipts; these are attributed worker results, not new triage runtime proof. This delivers the selected option A, without establishing #1665’s remaining relay/activation qualification or completing this epic. Existing #2654 follow-up scope and #2284’s refusal boundary/pre-policy-writer limitation remain unchanged.

    2026-10-23 triage at main f3c6fdc9f9c6321fda5a384cf8cfd8bf2e4846da: folded merged managed-storage subscription-Claude egress and #1667 taint delivery into the active dependency handoff. Preserved #1665’s Pi/API-key/mail/native-record remainder, its owner and settled October 23 Pi rulings, #1666→#1673, #1668 and native #2673’s unapproved design. #2654’s prerequisite is delivered. Attributed PR/native/mutation receipts are not a fresh triage run or complete security outcome; this epic stays open without agent-ready.

  11. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    2026-10-24 triage at main dc5d3c73282c29a3f0098306d398743ee18ec791: Refreshed HOST_MASKS to its declaration; all managed-storage egress, residual-disclosure, provider-routing and user-marked-input prerequisites remain. Existing child needs and deferred non-managed work stay scoped; no new worker or provider proof.

  12. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    2026-10-24 triage at main af6300478a07379178bd30221a31c0b917df2283: Refreshed moved current-source pointers by inspecting their named anchors. Historical receipts retain their source identities; scope, rulings, priorities and outstanding prerequisites are preserved. No runtime result or readiness is inferred from this navigation repair.

  13. schlessera commented on Oct 24, 2026

    @schlessera
    OwnerAuthor

    2026-10-24 triage at main e1ab485669565554ca6cb61ce5d130303647230f: Updated the active #2673 handoff to the new approved interaction while preserving all G6 policy/disclosure rulings. The child is implementation-ready; no taint-mark delivery or epic completion is claimed.

  14. modified the milestones: 0.44.0, 0.45.0 on Oct 25, 2026
  15. schlessera commented on Oct 25, 2026

    @schlessera
    OwnerAuthor

    2026-10-25 triage at main c670449d3bf1b0639e50ce554d728961f4313add: Reconciled the recorded #1668 completion ruling with the delivered #2725 cache relocation and verified squash ancestry. Removed that closed child from remaining work while preserving standalone follow-ups, the native child history and the other open G6/socket/egress obligations. This does not close the parent or claim a new integrated test run.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: backendsAgentBackend implementations and the seam they share.area: ui-sdkWire protocol, runtime schemas, the server and client SDK surfaces.area: ui-serverHono app factory: turn coordinator, auth, session catalog, routes, cron.epicA tracking issue. The work lives in its sub-issues; this one is never coded directly.priority: p0Drop everything: a security hole, data loss, or a broken release.securityAuth, isolation, egress, secrets, or anything in the threat model.type: featA new capability or a change in user-visible behaviour.

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions