Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Security Review Report

Review date: 2026-07-12 Review scope: target refactor release gate (cloudssh.room.v1, SQLite, SSH, HTTP, WebSocket, browser distribution, automation, and operator documentation). Deployment classification: Trusted self-hosted single-node service for one trusted team.

Decision

Decision: ACCEPTED for the documented Trusted self-hosted model only.

The product is not accepted as a hostile-user isolation boundary, a public signup service, or a hosted multi-tenant execution platform. LocalPtyRuntime starts every room with the service Unix account and shares that account’s host filesystem, process permissions, environment, network reachability, and kernel. A separately specified and reviewed isolated runtime is mandatory before any of those deployment claims can change.

Review Checklist

AreaVerification and release evidenceResult
Runtime trustdocs/security.md, configuration guidance, and the operations runbook warn that LocalPtyRuntime is trusted local execution, not sandboxing.Pass
Input confidentialityActor tests verify raw input is absent from durable event values and Debug output. The log gate rejects terminal-input fields. Echoed shell output remains documented as durable data.Pass
Request loggingscripts/security-check.py parses every Rust tracing invocation, rejects secret/query-bearing fields, and verifies middleware records Uri::path() rather than the query string.Pass
Metrics cardinalityThe same gate extracts metric label keys and enforces the fixed allowlist phase, outcome, transport, reason, and kind; identity and room labels are rejected.Pass
Browser artifact secretsmake security-check builds and scans every file in web/dist for private keys, JWTs, bearer values, and enabled Cloud SSH operator secrets.Pass
Sessions and providersOpaque session digests, CSRF/origin validation, bounded provider calls, HTTPS endpoint validation, stable-subject identity, and secret-reference redaction are covered by focused tests.Pass
SSH identityStable operator-owned host keys are required. Public development host-key generation helpers are prohibited by the repository gate.Pass
Persistence failureDisk-full and database-busy tests fail the journal closed. Corrupt/unsupported snapshot acceptance tests reject the snapshot while preserving output segments.Pass
Load and boundsmake load-check has hard process and scenario deadlines and verifies concurrent input ordering, a 32-client output fanout, a 128 KiB-per-client burst, and a 1 MiB SQLite flush to zero durable lag.Pass
Schema and residueThe gate requires one squashed SQLite migration, no ignored Rust tests, no POC source files, no compatibility marker, and no public test/development helper.Pass
Backup and recoveryBackup/restore tests preserve terminal generations, output, and snapshots; the operator runbook covers upgrade, restore, retention, disk-full, busy database, and corrupt snapshots.Pass
Dependency advisory gateCI and release workflows run rustsec/audit-check against the committed lockfile, and pull requests run GitHub dependency review. Known vulnerabilities block validation; exceptions require an explicit reviewed report change.Pass

Automated Evidence

Run from a clean checkout with the locked dependency graphs:

make security-check
make load-check
cargo audit --deny warnings
make production-check

make security-check is not a declaration-only checklist. It inspects tracing macro fields, request-path logging, metrics labels, the generated frontend artifacts, migration count, ignored tests, source residue, and this signed-off review evidence. make load-check executes the production actor and SQLite journal paths with deterministic fixtures and explicit failure thresholds.

Residual Risks And Operating Conditions

  • Terminal output and snapshots are plaintext in SQLite and may contain secrets echoed by a shell. Disk and backup encryption are operator responsibilities.
  • One compromised room process has the Unix permissions of the Cloud SSH service account. Run it as a dedicated unprivileged account/container and do not mix hostile users.
  • SQLite is a single-node durability boundary. Operators must alert on journal failure and durable lag and must rehearse restore procedures.
  • Provider availability and identity correctness depend on operator-controlled provider configuration. Redirects are disabled and response/time limits are enforced, but provider compromise remains outside Cloud SSH’s boundary.
  • Advisory databases evolve after a release. Re-run the dependency advisory gate for every lockfile change and before deploying an old revision.

Any expansion beyond these conditions invalidates this acceptance decision and requires a new architecture and security review.