renar v0.1.0
security

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.

01

Asset → adversary → answer

the threat model, stated
assetadversary / vectorthe answer
Any served fileMalicious 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 execCSRF from a hostile page the admin is viewing SameSite=Strict cookies · mutating verbs only · step-up re-proof on the dangerous rungs
The engine processKernel / memory exploits Landlock filesystem confinement enforced by the kernel · seccomp · a hardened systemd unit composed per install
PluginsMalicious or buggy package Out-of-process, crash-isolated · default-deny scopes, budgets · Ed25519-signed packages verified before the manifest parses
Terminal sessionsA browser-triggered shell Separate grant, off by default at the high tiers · recording (Enterprise) · session TTLs
CredentialsBrute force, replay, phishing Passkeys first (phishing-resistant) · password + TOTP · argon2id at rest · constant-time compare
The audit trailInsider tampering Hash-chained JSONL ledger — each record hashes the previous; scope mode is stamped into the chain itself
Supply chainDependency compromise Locked builds · cargo-deny and cargo-audit gates in CI · signed releases · no CDN, no telemetry, offline-first
TraversalSymlinks, path escapes, fancy filenames Blocked and tested · roots never followed out of root · bidi-isolated listing output, control bytes refused
Path confusionNames 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
argv-only exec

No shell construction anywhere in engine plumbing. Children spawn env-cleared, in their own process group, killed — descendants included — at the deadline.

secrets hashed, never cleartext

Passwords and API-token secrets: argon2id / SHA-256 at rest. Token secrets print exactly once, at mint.

sessions that re-prove

HMAC-signed sliding cookies — 12 h idle, 7 day absolute. Exec, shell and delete demand fresh proof, not an old cookie.

revocation that works offline

Every edition verifies an installed revocation list signed by the license issuer; break-glass accounts arm the emergency door.

redacted support bundles

The diagnostics bundle reports paths and facts, redacts every secret to a marker, and self-declares edition, posture and live degradations.

policy files are data

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.

02

The tier is a posture, not a checkbox

t0–t4 · every default published

An 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.

tierenvironmentshape
T0Loopback onlyLocal accounts, step-up re-proof off — the dev loop · full surface
T1Tailnet / meshLocal accounts with step-up re-proof · full surface, mutations ledger
T2Shared team serverPAM / OIDC verifiers · full-scope ledger
T3Internet-exposedOIDC/SAML SSO + WebAuthn MFA · TLS · short sessions, exec and tokens off
T4High-security / air-gappedPasskey-only credentials, SAML/Kerberos SSO, break-glass accounts · signed everything, full ledger, session recording, kernel sandboxing
03

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.
No certification claims. We state what the pipeline re-proves on every push and nothing else. The crypto tree is in-house and reviewed through repeated internal adversarial code-review rounds; if we ever hold a formal certification, this section will say so the day it is true.
banned from the dependency tree
  • ✕ 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.

04

How this gets reviewed

said plainly, or not said

The 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.