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.

00

There is no unauthenticated mode

the spine always starts

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

https://box.tailnet.ts.net/login
The renar sign-in page in its dark theme: a centred card asking for account, password and an authenticator code, with a Sign in button.
the only door, before any grant is evaluated
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.