Watch
1
0
Fork
You've already forked RedFlag
0
RedFlag/SECURITY.md

5.6 KiB

Security Model

The software that patches your fleet runs as root on every box. XZ Utils came through a build pipeline. SolarWinds came through an update. The update manager is part of your attack surface — most homelab tooling ignores that. RedFlag treats it as the attack surface it is.

This document is the operator-facing trust model. The architecture behind it — why the design landed where it did, and the pitfalls we think are still out there — is published in the RedFlag Architecture Framework (RAF).


Command Signing

Every command the server issues is Ed25519-signed. Agents verify the signature, check the nonce, validate the timestamp, and reject anything they've seen before. The signing key never leaves your server. You can read the security model in the code, not in marketing copy.

Every command includes a signed nonce with a 10-minute validity window. The agent tracks executed nonces and rejects replays, including from an attacker who intercepted a valid command.

Agent-server communication runs over HTTPS. The Ed25519 signing model is a defense-in-depth layer on top of that — commands can't be forged or replayed even if traffic is somehow intercepted or TLS is terminated at a proxy. The signing model doesn't assume the transport is trustworthy. Cert pinning and enforced TLS verification are on the roadmap.

Signing has no off switch. Signing-required and forward-only (no downgrade) are doctrine, not configuration. There is no "skip verification" path to misconfigure.


Machine Binding

Agents register with a one-time token plus a hardware fingerprint. The server stores the fingerprint; future check-ins that don't match the registered machine are rejected. A stolen config.json doesn't work on a different machine.

Machine-bound renewal. The token-renewal endpoint checks X-Machine-ID against the registered host, exactly as command endpoints do. A stolen config cannot mint access tokens from an unregistered machine — a mismatch returns 403 with a logged machine_id_mismatch security event. The agent surfaces this as a critical event, not a quiet backoff.


Key Management

On first connect, the agent fetches and caches the server's Ed25519 public key (TOFU). Every subsequent command is verified against it. The signing_keys table supports multiple concurrent active keys for zero-downtime rotation: a new key is promoted to primary while the previous key remains active (still verifies commands) until the operator deprecates it through the dashboard. Agents cache keys by key_id fingerprint and re-fetch when they see an unknown signer — no coordinated agent restart required. The roster and deprecation controls live at Settings → Security → Key Management.

Setup accepts an operator-supplied signing keypair — bring-your-own-key deployments are first-class.


Refresh-Token Rotation

90-day TTL. Each renewal mints a new refresh token and marks the old one consumed. Replaying a consumed token whose successor was also consumed means theft — the server revokes the entire token family and logs a security event. Agent crash-before-save is covered by accept-previous-once grace: a consumed token whose successor is still unconsumed gets a fresh one, not a revocation.

The failure mode is detection, not silent coexistence: a leaked token is only useful until the legitimate agent next renews, and using a stale one burns the whole family loudly.


The Supply-Chain Gate

When an update is approved, the server resolves the full dependency closure, checks every transitive artifact against OSV.dev, and mints a signed capability token binding the exact artifact hashes. A network-less privileged executor verifies the signature and every hash before anything installs — it can't reach out and can't be redirected.

A known vulnerability anywhere in the closure is a full stop: the operator must override with a documented reason, or the token is never minted. The override waives the vulnerability judgment only — the signing and hash verification have no skip path.

Before any package install: the agent fetches the expected SHA-256 from the server, downloads the artifact, verifies the hash. Mismatch blocks the install. OSV.dev is queried at discovery time (async, deduped) for npm, PyPI, apt, and dnf packages — results are visible in the dashboard before approval, and the resolved closure is checked again before the token is minted, not just the package you named.

Current boundary, honestly: the capability-token gate covers dnf and apt today. Docker, winget, and Windows Update still execute through the signed-command path without the helper — gating them is designed but not yet built. The gaps are documented in the RAF, not hidden.


Visibility

Security Health is surfaced as a dashboard panel on each agent — signing status, nonce protection, machine binding violations, command validation — so the posture is visible without digging through logs. All operations are logged with full context, sanitized against log injection (ANSI stripping, control character replacement, field truncation) with the content preserved.


Reporting a Vulnerability

Found something? I want to know, and you won't get lawyered at for looking.

  • Email: casey@samaritansolutions.net — use "RedFlag Security" in the subject
  • Please include reproduction steps and the version (v* tag or commit)
  • No live deployment exists outside the dev environment yet, so there's no embargo theater — but a heads-up before public disclosure is appreciated so a fix can land first

Good-faith research against your own RedFlag deployment is explicitly welcome. That's what self-hosted means.