Secure the rungs.
Don't amputate them.
A tool that edits files and runs processes is RCE by design. Renar does not pretend otherwise — it makes the dangerous rungs accountable: capability grants, step-up re-proof, signed plugins, recorded sessions, a hash-chained ledger. This page describes what is built and tested in the 0.1.0 artifacts, and what we refuse to claim.
Asset → adversary → answer
the threat model, stated| asset | adversary / vector | the answer |
|---|---|---|
| Any served file | Malicious markdown/HTML/SVG → XSS in the app origin | Everything escaped · strict CSP · raw HTML/SVG served as download or in a sandboxed opaque origin · no remote subresources, ever |
| Write and exec | CSRF from a hostile page the admin is viewing | SameSite=Strict cookies · mutating verbs only · step-up re-proof on the dangerous rungs |
| The engine process | Kernel / memory exploits | Landlock filesystem confinement enforced by the kernel · seccomp · a hardened systemd unit composed per install |
| Plugins | Malicious or buggy package | Out-of-process, crash-isolated · default-deny scopes, budgets · Ed25519-signed packages verified before the manifest parses |
| Terminal sessions | A browser-triggered shell | Separate grant, off by default at the high tiers · recording (Enterprise) · session TTLs |
| Credentials | Brute force, replay, phishing | Passkeys first (phishing-resistant) · password + TOTP · argon2id at rest · constant-time compare |
| The audit trail | Insider tampering | Hash-chained JSONL ledger — each record hashes the previous; scope mode is stamped into the chain itself |
| Supply chain | Dependency compromise | Locked builds · cargo-deny and cargo-audit gates in CI · signed releases · no CDN, no telemetry, offline-first |
| Traversal | Symlinks, path escapes, fancy filenames | Blocked and tested · roots never followed out of root · bidi-isolated listing output, control bytes refused |
| Path confusion | Names that display alike but differ in bytes | Byte-true paths end to end — every write door resolves the raw bytes and the decoded form as a guarded pair; two names that render identically address two different files, never a fold |
No shell construction anywhere in engine plumbing. Children spawn env-cleared, in their own process group, killed — descendants included — at the deadline.
Passwords and API-token secrets: argon2id / SHA-256 at rest. Token secrets print exactly once, at mint.
HMAC-signed sliding cookies — 12 h idle, 7 day absolute. Exec, shell and delete demand fresh proof, not an old cookie.
Every edition verifies an installed revocation list signed by the license issuer; break-glass accounts arm the emergency door.
The diagnostics bundle reports paths and facts, redacts every secret to a marker, and self-declares edition, posture and live degradations.
Per-directory .renar.toml policies — the auditable .htaccess: read-only for a role, no exec, hidden after hours. Reviewable in git; invalid policy is refused before it lands.
The tier is a posture, not a checkbox
t0–t4 · every default publishedAn instance declares its Tier at startup and the surface
shrinks or grows accordingly — every parameter admin-tunable, every default
published beside its bound on the /posture page. OSS and
degraded installs may declare any Tier; only a license can cap one.
| tier | environment | shape |
|---|---|---|
| T0 | Loopback only | Local accounts, step-up re-proof off — the dev loop · full surface |
| T1 | Tailnet / mesh | Local accounts with step-up re-proof · full surface, mutations ledger |
| T2 | Shared team server | PAM / OIDC verifiers · full-scope ledger |
| T3 | Internet-exposed | OIDC/SAML SSO + WebAuthn MFA · TLS · short sessions, exec and tokens off |
| T4 | High-security / air-gapped | Passkey-only credentials, SAML/Kerberos SSO, break-glass accounts · signed everything, full ledger, session recording, kernel sandboxing |
One crypto vendor: ours
pure rust, no c in the path- Transport — an in-binary TLS 1.3 acceptor from
russl-tls, with hybrid ML-KEM post-quantum key exchange. TLS is opt-in per deployment: over a tailnet, WireGuard already is the encryption layer, and duplicating it adds surface, not security. - Signatures — Ed25519 (
russl-ed25519) for release artifacts, plugin packages, license envelopes, fleet status envelopes, and ledger anchoring. - Passwords & sessions — argon2id; HMAC-signed
cookies; TOTP; WebAuthn/passkeys via
russl-webauthn. - Proof, not assertion — every push re-proves in CI that a reference OpenSSL client negotiates the hybrid ML-KEM group, that a SHA-256-suite-first client completes the handshake (the browser-interop gate), and that a real Chromium renders the served page.
- ✕ rustls
- ✕ ring
- ✕ aws-lc-rs
- ✕ openssl
Enforced by
review rule and by cargo-deny in CI. One vendor, one
dependency story, no C crypto in the path — the same discipline the
release signatures carry.
How this gets reviewed
said plainly, or not saidThe confinement layer carries its own review cadence. The virtual-filesystem core — the code that decides which bytes every door may touch — is re-reviewed in repeated adversarial rounds: three independent reviewers, fresh eyes, every prior fix re-verified as code rather than trusted as a claim. Six rounds have run; every finding from them is closed in the tree or declined with a written stance. We call this exactly what it is — internal adversarial review — and not a third-party audit, which we have not had. When we commission one, this page will say so.