Skip to content

Capability security wall (primitive + orchestrator) - #2

Merged
Rekonquest merged 10 commits into
masterfrom
claude/security-authority-wall
Jul 6, 2026
Merged

Rekonquest merged 10 commits into
masterfrom
claude/security-authority-wall

Conversation

@Rekonquest

@Rekonquest Rekonquest commented Jun 23, 2026 •

Copy link
Copy Markdown
Owner

A capability-based security wall built with the primitive + orchestrator
doctrine — now enforcing and boot-verified.

Status: enforcing + boots to login

SchemeList::kdup authorizes scheme creation through the capability wall
(security::authorize_scheme_create) instead of a bare uid == 0 check. The
kernel 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 the
authority is now a revocable capability: a revoked domain is refused even at
uid 0, which the old check could never do. on_context_exit destroys a dying
domain's capability so a reused pid starts clean.

(Boot-testing caught a real bug: an oversized WALL_CAPACITY made the kit's
fixed-array HandleTable overflow the kernel boot stack — double fault in
kmain. Capacity is now stack-safe.)

Pieces (all CI-green)

  • driver-primitives::authority::AuthorityWall — composed capability table
    (HandleTable generation-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 + a
    BTreeMap<DomainId, CapToken> registry; grants root authority at boot; the live
    gate authorize_scheme_create + on_context_exit. make check green.
  • 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 same
way, and tighten policy beyond behaviour-preserving (least-authority).

🤖 Generated with Claude Code

Rekonquest and others added 4 commits June 23, 2026 14:36
…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>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Rekonquest and others added 6 commits June 23, 2026 15:09
…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>
@Rekonquest
Rekonquest merged commit c77085e into master Jul 6, 2026
8 checks passed
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.

1 participant