RFC: content-addressed authority profiles#36
Draft
joshuajbouw wants to merge 5 commits into
Draft
Conversation
This was referenced Jul 14, 2026
This was referenced Jul 14, 2026
joshuajbouw
added a commit
to astrid-runtime/astrid
that referenced
this pull request
Jul 15, 2026
## Linked Issue Closes #1233 Refs #1228 and astrid-runtime/rfcs#36. ## Summary Adds passive content-addressed capability-registry primitives and moves short device key IDs to BLAKE3 before wider adoption. The profile shape remains unchanged and stored device IDs self-heal from their public keys; active device-scoped bearer sessions re-authenticate after upgrade. ## Changes - add exact capability IDs with borrowed and owned storage - add validated 32-byte entry, registry, and signed-extension-package digest newtypes - type the nonzero capability-registry schema revision - add content-bound capability references and exact resolution - add registered definitions and canonical registry manifests - implement deterministic canonical CBOR and domain-separated BLAKE3 identities - derive device key IDs from BLAKE3 with a legacy SHA-256 self-heal regression - freeze the private 51-ID capability-registry revision 1 set - isolate hashing, encoding, checked conversions, and digest validation in a private util module - encode canonical integer widths with one checked conversion per representation - keep the registry as a public Astrid runtime API without exposing it over HTTP, WIT, or the control socket - cover canonical bytes, BLAKE3 digest goldens, tampering, duplicates, invalid lengths, ordering, schema revisions, and fail-closed errors ## Verification - `cargo fmt --all -- --check` - `cargo metadata --locked --offline --no-deps` - `git diff --check` - golden vectors independently recomputed with `b3sum` - device-key BLAKE3 golden independently recomputed with `b3sum` - targeted local compilation reached the existing native BLAKE3 build-script stall; GitHub CI is the execution gate for the new head ## Checklist - [x] Linked to an issue - [x] CHANGELOG.md updated under `[Unreleased]`
3 tasks
joshuajbouw
added a commit
to astrid-runtime/astrid
that referenced
this pull request
Jul 15, 2026
## Linked Issue Closes #1237 Refs #1228 and astrid-runtime/rfcs#36. ## Summary Preserves the authenticating device's attenuation across every kernel authority view touched by capsule inventory, agent/group listing, and pair-device delegation. No product-specific trust path or public wire change is introduced. ## Changes - centralize canonical device-key resolution with malformed, unknown, and revoked IDs denied - pin the authorized principal profile, group config, and resolved device scope at one policy-decision point per request - use that exact authorization snapshot for capsule inventory, agent/group visibility, and pair delegation - derive the dispatch principal from the snapshot so authority and identity cannot diverge internally - preserve existing no-device and `Full` device behavior - validate every explicit pair-scope allow and deny pattern through the canonical typed capability boundary before token persistence - require effective `self:auth:pair:admin` in the common authorization preamble for `Full`, preset-full, and bare-`*` scopes - preflight pair-specific subset and structural no-escalation rules against the pinned authorization snapshot before recording success - record one failure audit row for missing pair-admin, scoped-to-full, and universal subset denials without a preceding success row - classify malformed pair request input as an authorized operation failure rather than a permission denial or security event - retain issuer denies in every scoped child - make profile-cache invalidation generation-aware per principal so an older concurrent disk load cannot republish pre-revocation authority and unrelated principals do not retry - refresh idempotent profile persistence directly from the disk state already loaded under the cache write lock, avoiding an unnecessary generation bump and reload while preserving mutation invalidation - keep unknown-device assertions at the router authorization boundary rather than private handlers that cannot receive them in production - preserve one outward scope-denial reason for malformed, unknown, revoked, and valid scoped denials so authorization responses do not become a device-key existence oracle; structured security logs retain the operator cause - add regressions across capsule inventory, agent/group views, pair delegation, explicit issue-to-redeem scope preservation, malformed allow/deny persistence rejection, broad-scope minting, audit outcomes, stale-load publication, cross-principal cache isolation, and outward denial opacity ## Verification - `cargo fmt --all -- --check` - `git diff --check` - `cargo metadata --locked --offline --no-deps --format-version 1` - deterministic snapshot regressions authorize, revoke and invalidate, prove a later request fails, then prove the in-flight request keeps the authority already audited as allowed - focused regressions cover no-device, `Full`, scoped allow/deny, malformed explicit patterns, unknown, revoked, concurrent stale-profile, cross-principal invalidation, no-escalation audit outcomes, and denial-reason opacity - compilation, tests, Clippy, and platform coverage run in repository CI ## Checklist - [x] Linked to an issue - [x] CHANGELOG.md updated under `[Unreleased]`
joshuajbouw
added a commit
to astrid-runtime/astrid
that referenced
this pull request
Jul 15, 2026
## Linked Issue Closes #1239 Refs #1237 and astrid-runtime/rfcs#36. ## Summary Carries the authenticated device into capsule dispatch so execution and inventory use the same live authority already enforced at the kernel boundary. The change is generic to Astrid and introduces no product-specific role or trust path. ## Changes - resolve one principal/profile/group/device snapshot per stamped event - reject disabled, malformed, unknown, and revoked identities before matching or grant signalling - use device-effective `capsule:list` only for global describe visibility - activate exact device-effective `capsule:access:any` for unrestricted execution and candidate expansion - preserve exact per-principal capsule grants, no-device/`Full` behavior, and principal-less lifecycle dispatch - emit one `GrantRequired` only for a valid in-view denied match - preserve legacy dispatch when no access resolver is installed - preserve merged authority-cache refresh, pairing preflight, audit classification, and caller-boundary audit behavior - require base `self:auth:pair` authority for pair issuance while retaining the additional `self:auth:pair:admin` gate and elevated audit classification for Full, preset-Full, and explicit-universal scopes - add a dedicated device-scope dispatch regression suite ## Verification - restacked onto `main` after #1196, #1238, and #1257 merged - signed head: `57ec31340db1a1749d5f137a25f4352bb6cb401f` - `cargo fmt --all -- --check` - `git diff --check origin/main...HEAD` - `cargo test --locked -p astrid-capsule` — 563 passed - `cargo test --locked -p astrid-kernel admin_cap_without_base_pair_capability_cannot_issue_full_token -- --nocapture` - `cargo clippy --locked -p astrid-capsule -p astrid-kernel --all-features --tests -- -D warnings` - replacement GitHub CI is the complete integration and execution gate ## Checklist - [x] Linked to an issue - [x] CHANGELOG.md updated under `[Unreleased]` No release is created or published by this change.
joshuajbouw
added a commit
to astrid-runtime/astrid
that referenced
this pull request
Jul 15, 2026
## Linked Issue Closes #1235 Refs #1228, #1233, #1234, and astrid-runtime/rfcs#36. ## Summary Populates the passive 51-entry capability-registry revision 1 on top of the primitives merged in #1234. Existing authorization, wildcard evaluation, persisted state, socket behavior, and wire contracts remain unchanged. ## Changes - bind all 51 kernel entries to fixed scope, ordered target kinds, delegability, privileged status, source, and display danger - expose the typed revision 1 manifest while keeping the raw ID set private - freeze all 51 BLAKE3 entry digests and the aggregate manifest digest - freeze revision 1 danger metadata independently from the mutable live capability catalog - preserve current catalog scope and danger metadata - require kernel and admin request mappings to resolve to a registered entry - complete kernel and admin request-variant inventories - share one complete admin-request test inventory across the mapping and registry suites - append new public error variants without changing existing implicit discriminants - classify every revision 1 ID as primary, secondary, token-authenticated, dormant, or mapping-only - classify `capsule:access:any` as enforced secondary authority now that capsule dispatch enforces it - use immutable registry-revision terminology throughout the public API and errors Revision 1 never silently expands. A capability added to the catalog, an inventoried request mapping, or the capsule-side enforcement constants covered here fails its registry check until a new revision is introduced. An entirely new enforcement site must add its owning-crate registry assertion. ## Verification - exact signed head: `aaf8952f08c2441b217fec60d90de4a40c922754` - restacked directly on merged `main` at `bed06ad476f6e58a5ee56331118da497d121705e` - all 15 commits have good GPG signatures from Joshua J. Bouw - `cargo fmt --all -- --check` - `git diff --check origin/main...HEAD` - `cargo test --locked -p astrid-core capability_registry` (20 passed) - `cargo test --locked -p astrid-kernel capability_catalog_tests` (4 passed) - `cargo test --locked -p astrid-kernel empty_agent_modify_keeps_existing_wire_and_authority_mapping` (1 passed) - `cargo test --locked -p astrid-capsule unrestricted_capsule_access_enforcement_id_is_registered` - `cargo test --locked -p astrid-capsule secondary_enforcement_ids_are_registered` - `cargo test --locked -p astrid-core -p astrid-capsule -p astrid-kernel` (274 core, 564 capsule, and 258 kernel tests passed; the macOS socket group was rerun outside the sandbox) - `cargo clippy --locked -p astrid-core -p astrid-capsule -p astrid-kernel --all-features -- -D warnings` - range-diff confirms the registry commits are preserved while the previously stacked authority fixes are now supplied by merged `main` - the skipped historical integration-merge correction is retained: `capsule:access:any` is live secondary authority, not dormant metadata - the production capsule constants for unrestricted access, audit firehose, and resource exemptions are pinned to their intended exact IDs and checked directly against revision 1; kernel request inventory is shared between mapping and registry suites ## Compatibility The registry remains passive. This PR does not activate a registry evaluator, change authorization behavior, migrate persisted state, or alter the existing wire shape. Revision 1 is an immutable description of the enforcement surface that already exists. ## Checklist - [x] Linked to an issue - [x] CHANGELOG.md updated under `[Unreleased]` - [x] No evaluator activation or persisted-state migration --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
joshuajbouw
added a commit
to astrid-runtime/astrid
that referenced
this pull request
Jul 15, 2026
## Linked Issue Closes #1241 Refs #1237 and astrid-runtime/rfcs#36. ## Summary Replaces gateway-side audit authority inference with the kernel's live principal/device capability evaluator. Historical and streaming audit views now narrow through the same runtime policy, with no AOS-specific role, key exposure or caller-selected identity. ## Changes - add an additive borrowed `CapabilityCheck` constructor while preserving the existing constructor and owned errors - expose one doc-hidden boolean kernel evaluator for a principal, optional device and capability - inject the in-process evaluator through the gateway runner and an additive embedded-router builder; the default router remains self-only - evaluate historical audit authority after the asynchronous log read and at every pagination record boundary - re-evaluate `audit:read_all` for every live SSE event - preserve self visibility after malformed, unknown, revoked, disabled, group-revoked or scope-denied authority - keep raw audit cursor positions stable while live principal narrowing filters same-second batches - bind new cursors to immutable audit-entry identity and effective visibility scope so same-second appends cannot shift the page boundary and widening or a principal change requires a restart - reject unsafe scope changes before visible, hidden and cursor-skipped rows instead of returning a partial page or false end-of-results - accept legacy timestamp/raw-offset cursors only for the unambiguous default self view - suppress continuation cursors at true physical EOF while retaining a scope-bound cursor when hidden rows make a later widening unsafe - pin the gateway's live `audit:read_all` enforcement constant and require it to resolve through capability-registry revision 1 - retain the pair-device terminal audit distinctions already present on `main` - add a race-free pre-bound listener entrypoint for the real HTTP SSE regression - expose the same live evaluator boundary to trusted in-process router embeddings without exposing the internal probe type - document the connect-info make-service requirement for both public router builders so unauthenticated redeem throttling keeps the real peer address, and make the default builder's self-only audit policy explicit - document the additive runner/router migration path for co-located callers that need audit firehose visibility - accept hyphen-leading opaque invite tokens in both CLI redeem and revoke paths so every base64url token the runtime issues remains usable ## Verification - exact signed head: `bf3eb251164f1c20e47fb9f3e841677d9efecc02` - all 20 commits above `d85fb10663c21d08fc43d39d939cfbb5a023cafd` have good Joshua committer signatures - `cargo fmt --all -- --check` - `git diff --check` - `cargo doc -p astrid-gateway --no-deps` - `cargo test -p astrid-gateway` — 160 unit, 7 CORS, 10 models and 18 router tests pass - `cargo test -p astrid-kernel runtime_policy_tests` — 8 tests pass - focused audit pagination suite — 17 tests pass, including same-second insertion, missing-anchor and pre-anchor authority-widening regressions - focused registry enforcement assertion — 1 test passes - `cargo clippy -p astrid-gateway -p astrid-kernel --all-targets -- -D warnings` - all 12 production-root CLI parser tests pass, including redeem and revoke with a generated-token shape beginning in `-` - `cargo clippy -p astrid --all-targets -- -D warnings` - the replacement GitHub matrix is the execution gate for the combined workspace ## Compatibility The public HTTP shape, WIT contracts, persisted authority, gateway state and existing runner entrypoints remain unchanged. The new kernel evaluator is boolean and doc-hidden. The internal typed gateway probe remains private; trusted in-process embedders receive an additive generic callback builder with the same fail-closed policy boundary. When #1244 is refreshed after this PR, its workspace-aware gateway runner must retain this live capability probe across normal, TLS and pre-bound listener paths. ## Checklist - [x] Linked to an issue - [x] `CHANGELOG.md` updated under `[Unreleased]` --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
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.
Summary
Why
The current wildcard authority can inherit capabilities added in the future and can activate bypasses that are not represented in the capability catalog. Astrid needs explicit, inspectable administrative authority without giving up complete sysadmin control.
Status
Draft. This RFC must remain open and unmerged. Generated registry and profile digests, migration fixtures, and implementation artifacts remain acceptance gates.
Tracks astrid-runtime/astrid#1228. Companion design: #37.
Validation
git diff --checkpython3 generate-book.py