From 9c492d739aaf98009bd841514b4ec01a8a1ab34edd47ce22271ef2510deaf72b Mon Sep 17 00:00:00 2001 From: Tyler J King Date: Wed, 15 Apr 2026 15:37:27 -0400 Subject: [PATCH] docs: add ARCHITECTURE.md, CHANGELOG, fix Cargo metadata ARCHITECTURE.md explains the governed shell stack, Keylime integration model, ShellClass derivation, and implementation status for reviewer orientation. CHANGELOG documents v0.1.0-rc.1 deliverables. Cargo.toml metadata (license, repository) added to bascule-core, bascule-agent, bascule-gateway. Signed-off-by: Tyler King Signed-off-by: Tyler J King --- ARCHITECTURE.md | 92 ++++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 40 +++++++++++++++++ bascule-agent/Cargo.toml | 3 ++ bascule-core/Cargo.toml | 2 + bascule-gateway/Cargo.toml | 2 + 5 files changed, 139 insertions(+) create mode 100644 ARCHITECTURE.md create mode 100644 CHANGELOG.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..a1181d4 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,92 @@ +# Bascule — Governed Shell Access Control + +Bascule is an SSH-over-HTTPS proxy with identity-aware sessions and +ceremony-gated access control. It terminates operator identity (SSH certs, +OIDC tokens, Entra), evaluates Accord policy, classifies sessions by the +host's hardware attestation posture, and emits Chronicle audit events for +every governed operation. + +## Component Map + +``` +Operator + │ + ▼ +bascule-gateway (cluster-side gRPC) + ├─ OIDC auth → OperatorIdentity + ├─ Ceremony engine (self-grant / single-approval / break-glass) + ├─ Posture-current ConfigMap → ShellClass derivation + ├─ OPA policy evaluation (via accord-opa) + ├─ 8-stage filter chain (auth→session→classify→policy→budget→execute→response→audit) + ├─ Breach evaluator (30s posture poll, BreachResponse enforcement) + └─ Audit pipeline → Quartermaster merkle anchoring + │ + ▼ +bascule-agent (application sidecar) + ├─ Shellstream protocol (msgpack over Unix socket) + ├─ 8 namespace handlers (Crypto, Identity, Secrets, Governance, + │ Attestation, Audit, Network, Intelligence) + ├─ PostureReader → posture-current ConfigMap (cached, 30s TTL) + └─ Optional SSH server on port 2222 + +bascule-core (shared types) + ├─ SessionScope, ShellClass, DelegationScope + ├─ CeremonyGrant, CeremonyType, Evidence + ├─ derive_shell_class(PostureLevel) → ShellClass + └─ BreachAction evaluation +``` + +## Keylime Integration Model + +Bascule **consumes** Keylime attestation — it does not reimplement or +compete with it. The integration boundary is the `posture-current` +ConfigMap written by the substrate-operator's posture evaluator: + +``` +Keylime verifier (CNCF) + → substrate-operator / TpmAttestationValid checker + → posture-current ConfigMap (level: 1-5) + → bascule-agent PostureReader + → bascule-gateway ceremony grant (ShellClass derivation) + → bascule-gateway breach evaluator (session downgrade) +``` + +The `keylime-client` crate (in the substrate workspace) is the single +Keylime consumer. Neither bascule-agent nor bascule-gateway imports it +directly. They read the ConfigMap output. + +## ShellClass Model + +Sessions are classified at ceremony grant time based on the host's +operational posture level: + +| PostureLevel | ShellClass | Operations Permitted | +|---|---|---| +| Normal (5) | System | Kernel modules, firmware, network config, storage | +| Elevated (4) | Application | Deploy, query APIs, run playbooks | +| Restricted (3) | Application | Deploy, query APIs, run playbooks | +| Critical (2) | Application | Deploy, query APIs, run playbooks | +| Lockdown (1) | Application | Deploy, query APIs, run playbooks | + +- No mid-session upgrade. Downgrade only (on posture breach). +- Upgrade requires a new ceremony. +- DelegationScope enables "Infrastructure shells" — Application sessions + that orchestrate System operations on remote hosts (Ansible pattern). + +## What's Implemented vs Planned + +| Component | Status | +|---|---| +| Ceremony engine (3 types) | Implemented | +| 8-stage filter chain | Implemented | +| PostureReader (ConfigMap) | Implemented | +| ShellClass derivation | Implemented | +| DelegationScope + pre-flight | Implemented (target posture query stubbed) | +| Breach evaluator + downgrade | Implemented | +| Accord hot-reload | Not implemented (static at startup) | +| Helm chart | Exists, not updated for posture fields | +| LabelSelector delegation | Type defined, async resolution deferred | + +## License + +Apache-2.0. All source files carry SPDX headers. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..65c840e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +## [0.1.0-rc.1] - 2026-04-15 + +### Added + +- **ShellClass** (Application | System) derived from PostureLevel at ceremony grant + - Immutable for session lifetime — no mid-session upgrade, downgrade only + - `derive_shell_class()` pure function with configurable threshold + - `satisfies()` hierarchical check (System satisfies Application) + +- **PostureReader** in bascule-agent replacing soft-mode attestation + - Reads `posture-current` ConfigMap written by substrate-operator + - TTL-cached (30s default) with stale-serve-on-error semantics + - Fail-closed to `PostureLevel::Lockdown` on ConfigMap unavailability + - `posture_source="static"` preserved for dev/test without a cluster + +- **DelegationScope** for Infrastructure shell pattern + - Application sessions with delegation authority for orchestrators (Ansible/Terraform) + - `TargetSelector`: Hosts, LabelSelector (deferred), TrustDomain + - Orthogonal to ShellClass — independent axes on SessionScope + +- **Session downgrade on posture breach** + - Breach evaluator maps all 5 `BreachResponse` variants (LogOnly, AlertDelegates, + ReducePosture, SuspendTrust, RevokeAccord) + - 30s posture polling loop on `posture-current` ConfigMap + - System sessions downgraded to Application on posture degradation + - SuspendTrust/RevokeAccord terminate sessions immediately + +- **Worker pre-flight enforcement** in org-ops + - `required_shell_class()` on OrgCommands trait (default: Application) + - `target_host()` on OrgCommands trait for remote dispatch + - Three-step pre-flight: delegation authority + target scope + target posture + - Fail-closed on unknown delegation or posture + +- **SessionScope enrichment** + - `shell_class: ShellClass` with `#[serde(default)]` + - `posture_level_at_establishment: Option` with `#[serde(default)]` + - `delegation: DelegationScope` with `#[serde(default)]` + - All backward-compatible with existing persisted sessions diff --git a/bascule-agent/Cargo.toml b/bascule-agent/Cargo.toml index 1cc9c00..a640562 100644 --- a/bascule-agent/Cargo.toml +++ b/bascule-agent/Cargo.toml @@ -2,6 +2,9 @@ name = "bascule-agent" version = "0.1.0" edition = "2021" +description = "Governed application sidecar — Shellstream namespace router with attestation" +license = "Apache-2.0" +repository = "https://git.guildhouse.dev/guildhouse/bascule" [[bin]] name = "bascule-agent" diff --git a/bascule-core/Cargo.toml b/bascule-core/Cargo.toml index 5627ead..c299670 100644 --- a/bascule-core/Cargo.toml +++ b/bascule-core/Cargo.toml @@ -3,6 +3,8 @@ name = "bascule-core" version = "0.1.0" edition = "2021" description = "Shared types for the Bascule governance-mediated access control system" +license = "Apache-2.0" +repository = "https://git.guildhouse.dev/guildhouse/bascule" [dependencies] serde = { workspace = true } diff --git a/bascule-gateway/Cargo.toml b/bascule-gateway/Cargo.toml index 852d2e6..9106444 100644 --- a/bascule-gateway/Cargo.toml +++ b/bascule-gateway/Cargo.toml @@ -3,6 +3,8 @@ name = "bascule-gateway" version = "0.1.0" edition = "2021" description = "Bascule governance gateway — cluster-side API gateway for governed access" +license = "Apache-2.0" +repository = "https://git.guildhouse.dev/guildhouse/bascule" [[bin]] name = "bascule-gateway"