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.
There is no unauthenticated mode
the spine always startsWith no account yet, the engine serves a bootstrap notice and nothing else. There is no read-only anonymous mode to forget to turn off, and no flag that opens one. The first operator is created from the command line, on the box, on purpose.
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.