Repository navigation
Capability security wall (primitive + orchestrator) - #2
Merged
Merged
Conversation
…primitive A dumb-mechanism security wall built by composition of HandleTable (unforgeable, generation-checked naming) + SeqCounter (issue provenance). Immutable-by-construction (rights fixed at mint, no setter), capability-to- construct (authorization = holding a wall-minted CapToken; forged/stale tokens rejected structurally by the generation check), and revocation-is- destruction (revoke bumps the slot generation, invalidating every copy). Zero policy: who holds which authority is the orchestrators decision. 7 unit tests; fmt + clippy -D warnings + bare-metal (x86_64-unknown-none) clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rimitives) Adds src/security/ — the orchestrator side of driver_primitives::AuthorityWall: the kernel owns the single wall, mints the root domains full-authority capability at boot (security::init in kmain), and exposes an authorization facade (authorize/issue/revoke) for the cross-domain seams that currently rely on ambient euid==0 checks. Identity is possession of an immutable, revocable CapToken; no policy lives in the wall. - driver-primitives added as a kernel path dep; kit kept as its own isolated workspace via [workspace] exclude. - make check (cargo check, x86_64-unknown-kernel, build-std) passes; the security module emits zero warnings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The kernel orchestrator now indexes structural domain identity -> the capability it issued (BTreeMap behind the wall lock): grant_domain (issue, revoking any prior cap for that domain), authorize_domain (structural-identity check), revoke_domain (destruction). Boot grants the root domain ALL via the registry. DomainId gains Ord so domains can be map-indexed. No production gate flipped yet (that needs spawn-time distribution + boot verification). Kit: clippy -D + 7 tests green. Kernel: make check green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Specifies the path from the landed capability foundation to actual enforcement at scheme/mod.rs:323: DomainId mapping, capability distribution on spawn, gate-flip behind an off-by-default feature, policy tightening, revocation on teardown, and removal of the ambient uid==0 check. Each step is boot-test gated (make check proves compile only, not boot). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…erified) SchemeList::kdup now authorizes via security::authorize_scheme_create instead of a bare uid==0 check: a uid-0 caller is granted CREATE_SCHEME on first use (behaviour-preserving), but the authority is a recorded, REVOCABLE capability — a revoked domain is refused even at uid 0, which the old check could never do. Identity is structural (caller pid). on_context_exit revokes a dying domains capability so a reused pid starts clean. WALL_CAPACITY=256 (was 4096): the kit HandleTable is a fixed array built on the kernel stack during boot; 4096 overflowed it (double fault in kmain, caught by boot-testing). 256 is ample for concurrently-privileged domains. Boot-verified: injected into a Redox image, QEMU boots to redox login: with the full daemon chain (pcid -> virtio-gpud -> display) up, no panic — every boot-time scheme creation authorized through the wall. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A DELEGATE-holding domain hands a *subset* of its authority to another domain (cannot delegate more than it holds, nor without the delegation right). The delegatee gets a fresh, independent capability bound to its own domain; cascade revocation is left to the orchestrator (e.g. a graph min-cut). This turns the walls flat per-domain grants into a delegation graph — the substrate for graph-based security analysis (min-cut quarantine, reachability proofs). Composes the wall mint+check with a DELEGATE-and-subset guard. 9 authority tests (2 new); clippy -D + make check green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The simulators #1 optimization core (stoer-wagner-mincut), as a dumb, host-tested kit primitive: the cheapest split of a weighted graph into two non-empty parts, over a fixed-capacity NxN matrix (no_std, alloc-free). It is the cross-domain optimization->security bridge in code — composed with the AuthorityWall delegation graph it computes graph-minimal QUARANTINE (the fewest authority edges to cut to isolate a compromised domain). Also serves resource-placement (cut a dataflow where least data crosses) and clustering. Verified: 5 tests incl. the classic Stoer-Wagner (1997) example (min cut = 4) and a partition test; clippy -D + bare-metal + kernel make check green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…variants Realizes v5s verify-core (bounded model checking / partial-order-style state exploration). Drives the REAL wall through every reachable issue/revoke/ delegate sequence to depth 5 over a small finite universe, asserting at every state that authorizes() exactly matches a ground-truth reference model. This proves the security invariants across interleavings, not just spot tests: no-forge, immutability, domain-binding, revocation-completeness (incl. slot/ generation reuse), and the delegation bound. Result: 662,193 reachable states verified, no invariant violated (0.6s). Adds Clone to HandleTable/Slot/AuthorityWall to enable state backtracking. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bounded model-check proved the PRIMITIVE sound; an adversarial audit then found what it could not reach — two reachable orchestrator-policy bugs and one theoretical primitive ABA. All fixed: - BUG C (primitive, ABA): CapToken now carries the wall non-wrapping u64 epoch; authorizes/inspect/revoke/delegate all compare it, so a slot/generation reuse (incl. a u32 generation wrap) can never revive a stale token. - BUG A (orchestrator, revoke did not stick): the domain map gains a tombstone (None); revoke leaves a tombstone so a withdrawn live domain stays denied, instead of being re-granted on the next syscall. - BUG B (orchestrator, pid-reuse escalation): the scheme-creation gate now re-checks uid==0 on EVERY call, so a pid reused by a non-root process cannot inherit a prior grant. on_context_exit *forgets* a dead pid (clean slate). Verified: 84 kit tests incl. the 662k-state model-check and a new orchestrator regression test (revoke-sticks + uid-recheck); clippy -D + make check green; the kernel boots to redox login: with the full daemon chain, no panic. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.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.
A capability-based security wall built with the primitive + orchestrator
doctrine — now enforcing and boot-verified.
Status: enforcing + boots to login
SchemeList::kdupauthorizes scheme creation through the capability wall(
security::authorize_scheme_create) instead of a bareuid == 0check. Thekernel boots to
redox login:in QEMU with the full daemon chain up(pcid → virtio-gpud → display), no panic — every boot-time scheme creation is
authorized through the wall. Behaviour is preserved for
uid == 0, but theauthority is now a revocable capability: a revoked domain is refused even at
uid 0, which the old check could never do.
on_context_exitdestroys a dyingdomain's capability so a reused pid starts clean.
(Boot-testing caught a real bug: an oversized
WALL_CAPACITYmade the kit'sfixed-array
HandleTableoverflow the kernel boot stack — double fault inkmain. Capacity is now stack-safe.)Pieces (all CI-green)
driver-primitives::authority::AuthorityWall— composed capability table(
HandleTablegeneration-checked handles +SeqCounter): immutable-by-construction, capability-to-construct, revocation-is-destruction. 7 tests;
fmt + clippy
-D warnings+ bare-metal build green.kernel::security— the orchestrator: owns the wall + aBTreeMap<DomainId, CapToken>registry; grants root authority at boot; the livegate
authorize_scheme_create+on_context_exit.make checkgreen.docs/security-wall.md— design + the remaining-seams roadmap.Remaining (incremental, each boot-tested)
Migrate the other
euid-gated seams (fchown, proc ops) to the wall the sameway, and tighten policy beyond behaviour-preserving (least-authority).
🤖 Generated with Claude Code