Skip to content

feat(net): expose authenticated connection principals - #70

Merged
joshuajbouw merged 2 commits into
mainfrom
feat/request-context-principal
Sep 15, 2026
Merged

joshuajbouw merged 2 commits into
mainfrom
feat/request-context-principal

Conversation

@joshuajbouw

Copy link
Copy Markdown
Member

Summary

  • expose the host-authenticated principal attached to accepted local streams
  • keep payload identity separate from transport identity
  • sync the canonical request-context WIT contract

Verification

  • cargo check --workspace
  • cargo test --workspace

Related to astrid-runtime/astrid#1940.

Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Update the canonical WIT source, regenerate staging, and correct the package documentation.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds host-authenticated connection principal access while keeping transport identity separate from payload identity.

Changes:

  • Extends the request-context WIT interface.
  • Adds ConnectionPrincipal and TcpStream::connection_principal().
File summaries
File Summary
astrid-sys/wit-staging/deps/astrid-request-context@1.0.0/request-context@1.0.0.wit Adds the principal accessor; canonical contract synchronization and documentation updates are required.
astrid-sdk/src/net.rs Exposes the authenticated connection principal through the Rust SDK.
Review details

Suppressed comments (1)

astrid-sys/wit-staging/deps/astrid-request-context@1.0.0/request-context@1.0.0.wit:25

  • This adds a function to the shape of astrid:request-context@1.0.0, but the repository freezes host WIT packages at their declared version and requires shape changes to ship under a new version path (for example, astrid-net and astrid-identity). Editing the 1.0.0 contract in place can make components compiled against the existing ABI incompatible; add a new request-context version and update the generated-world import instead.
}
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The canonical WIT contract is not updated, and the frozen 1.0.0 interface is modified.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

astrid-sys/wit-staging/deps/astrid-request-context@1.0.0/request-context@1.0.0.wit:24

  • This is a staged mirror, not the canonical source: astrid-sys/build.rs removes wit-staging and recopies every host WIT from contracts/host when the submodule is present, and CI checks out submodules. Since this PR only changes the staged copy, a workspace build will overwrite this addition from the unchanged canonical file and the new Rust binding will not be generated. Update the canonical host WIT/submodule and regenerate the mirror.
    connection-principal: func(connection: borrow<tcp-stream>) -> result<option<string>, error-code>;
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread astrid-sdk/src/net.rs
@joshuajbouw
joshuajbouw merged commit 238b979 into main Sep 15, 2026
9 checks passed
joshuajbouw added a commit to astrid-runtime/astrid that referenced this pull request Sep 17, 2026
## Linked Issues

Closes #1936
Closes #1940

## Summary

Bind every interactive approval to the authenticated request that caused
it, expose the authenticated local connection principal to host
capsules, and retry grant-gated CLI commands only after the kernel
confirms the grant is durably installed.

## Changes

- mint an opaque owner for each authenticated native-uplink connection
- mint a signed random owner in each new HTTP bearer while preserving
legacy bearer verification
- carry ownership through host-stamped IPC metadata and capsule fan-out
- expose local connection ownership and the host-authenticated principal
through the additive request-context WIT host API
- require exact principal and owner matches for approval, local-egress
consent, and grant-on-use responses
- derive HTTP approval ownership from the verified bearer rather than
accepting an owner from the request body
- reject wrong-owner approval traffic before route queue admission, so
peer sessions cannot consume the intended owner's queue budget
- handle capsule approval prompts in the owning CLI: non-interactive
callers deny immediately, while TTY callers can approve once or deny
without preventing daemon-exit and capsule-unload cancellation
- handle owner-routed grant prompts in the CLI, register
request/response correlation through one ordered bounded kernel
observer, wait for an exact kernel-sourced `GrantResult` acknowledgement
after durable grant persistence, then retry the dropped command exactly
once
- keep elicitation principal-scoped while making approval and grant
control request-scoped
- fail closed for forged, unattributed, ownerless, or internally
inconsistent approval prompts and responses
- make the runtime E2E shutdown helper wait for the daemon's real
signal/finalization path instead of truncating volume packing with a
generic five-second reaper
- add cross-owner, same-principal peer, missing-owner, legacy-bearer,
propagation, queue-budget, CLI, HTTP, native, cancellation, crash,
restart, authenticated-principal, and durable-grant regressions

The WIT contract landed in astrid-runtime/wit#25 and
astrid-runtime/wit#26. SDK ownership support landed in
astrid-runtime/sdk-rust#68; authenticated-principal support is in
astrid-runtime/sdk-rust#70. AOS consumption is tracked by
unicity-aos/aos-ce#175 and unicity-aos/aos-ce#176.

## Verification

- `cargo test -p astrid-events -p astrid-gateway -p astrid-uplink -p
astrid --lib --bins` (767 CLI, 82 event-bus, 175 gateway, and 47 uplink
tests passed before the final focused successor)
- `cargo test -p astrid-types --features clock grant_result` (2 passed)
- `cargo test -p astrid-kernel grant_on_use::tests` (15 passed,
including an immediate response with no settling delay)
- `cargo test -p astrid-capsule request_context` (1 passed)
- `cargo test -p astrid-uplink native::` (34 passed, including owner
metadata on the native wire and malformed approval rejection)
- `cargo test -p astrid --bin astrid commands::capsule_verb` (14 passed)
- `cargo clippy -p astrid-types -p astrid-kernel -p astrid-capsule -p
astrid-uplink -p astrid --all-targets --all-features -- -D warnings`
- `cargo check -p astrid -p astrid-kernel -p astrid-capsule -p
astrid-uplink`
- `TMPDIR=/tmp ASTRID_E2E_SKIP_BUILD=1
ASTRID_E2E_CAPSULES_DIR=/tmp/astrid-aos-stage.Dbn3hy/capsules
scripts/e2e/runtime-harness.sh` (full runtime E2E passed through
approvals, isolation, restart, crash recovery, capsule
cancellation/lifecycle, and audit collection before the final focused
successor)
- `cargo fmt --all -- --check`
- `git diff --check`

## AI / Tool Assistance

Assisted-by: Codex:gpt-6-astra

Codex helped trace the ownership path across native sockets, signed HTTP
bearers, the event bus, approval waiters, durable grant installation,
control streams, and regression tests. I reviewed the exact diff and
validated it with the compile, focused tests, strict clippy, formatting,
and runtime journey listed above.

## Checklist

- [x] Linked to issues
- [x] Changelog fragment added under `changes/1936.fixed.md`
- [x] I understand every change in this PR and can explain its design,
risks, and validation.
- [x] I reviewed and tested any meaningful tool-generated output
included in this PR.
- [x] Every non-bot, non-merge commit has a matching `Signed-off-by`
trailer.

---------

Signed-off-by: Joshua J. Bouw <jjb@unicity-labs.com>
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.

2 participants