Watch
1
0
Fork
You've already forked RedFlag
0
Fail-closed signed update system for Linux fleets
  • Go 66.6%
  • TypeScript 26.3%
  • Rust 2.6%
  • Go Template 1.9%
  • Shell 1.2%
  • Other 1.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Fimeg d74498a19d publish supply-chain gate plan, honest status section in README
RAF/SUPPLY_CHAIN_GATE_PLAN.md unblocked — the architectural thesis for the
capability-token model. Updated to reflect agent-self upgrade path, OSV
expansion, and current verification state.

README Status section rewritten: "implemented and locally exercised, not
production-proven" replaces the misleading "working in production" header.
Honest gaps listed (GATE-002, CRITICAL-004).
2026-05-30 13:25:12 -04:00
agent feat: zero-sudo agent, helper self-upgrade, OSV expansion, docker handler rewrite, staging UI 2026-05-30 12:56:40 -04:00
config fix: BUG-012, BUG-014, BUG-015 - platform detection, strict signing, key paths 2026-04-10 10:16:48 -04:00
helper feat: zero-sudo agent, helper self-upgrade, OSV expansion, docker handler rewrite, staging UI 2026-05-30 12:56:40 -04:00
RAF publish supply-chain gate plan, honest status section in README 2026-05-30 13:25:12 -04:00
Screenshots feat(security): A-1 Ed25519 key rotation + A-2 replay attack fixes 2026-03-28 21:25:47 -04:00
scripts refactor: rename aggregator-agent to agent for public release 2026-05-21 13:19:18 -04:00
server security: hash registration tokens at rest, idempotency guard, README trust model 2026-05-30 13:12:58 -04:00
web security: hash registration tokens at rest, idempotency guard, README trust model 2026-05-30 13:12:58 -04:00
.gitignore publish supply-chain gate plan, honest status section in README 2026-05-30 13:25:12 -04:00
CHANGELOG.md bump v0.2.1.0 -> v0.2.1.1, add CHANGELOG.md 2026-05-30 12:56:49 -04:00
docker-compose.yml docs: bump v0.2.0.7 → v0.2.1.0, update CLAUDE.md and changelog 2026-05-29 17:50:49 -04:00
LICENSE feat(security): A-1 Ed25519 key rotation + A-2 replay attack fixes 2026-03-28 21:25:47 -04:00
Makefile feat: package-centric updates, version timeline, and registry-gap closure (v0.2.0.7) 2026-05-28 20:25:59 -04:00
OPERATIONS.md add 90-day TTL to trust model, unblock OPERATIONS.md for public 2026-05-30 13:20:47 -04:00
README.md publish supply-chain gate plan, honest status section in README 2026-05-30 13:25:12 -04:00
THIRD_PARTY_LICENSES.md chore: add windowsupdate COM interface stubs and update third-party licenses 2026-05-21 13:48:42 -04:00

RedFlag

Self-hosted update management for operators who own their stack.

v0.2.1.1 — May 2026 · MIT License

NOT YET ANNOUNCED — Tags do not imply stability. Massive flux. Use at your own risk.


The update manager is part of your attack surface. Most homelab tooling ignores this. RedFlag doesn't.

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. Hardware binding means a stolen agent config doesn't work on a different machine. You can read the security model in the code, not in marketing copy.

It also just manages your updates — across Linux and Windows, including Docker containers running on those hosts — from a single dashboard, with a human approval step before anything gets installed.

Next up is the supply-chain gate: the server mints a signed capability token over the exact resolved package closure, and a network-less privileged executor verifies the signature and artifact hashes before anything installs. Wired up and in live testing now — soon.

ConnectWise charges $50/agent/month. RedFlag doesn't.


Dashboard Agent Health Updates
More screenshots
Live Ops History Docker
Heartbeat Windows Agent Agent List

Quick Start

Server

git clone https://github.com/Fimeg/RedFlag.git
cd RedFlag
cp config/.env.bootstrap.example config/.env
docker-compose build && docker-compose up -d

Open http://localhost:31336, complete the setup wizard, then restart:

docker-compose down && docker-compose up -d

Agent

Get a registration token from Settings → Token Management, then:

Linux / macOS:

curl -sfL https://your-server.com/install | sudo bash -s -- your-registration-token

Windows:

iwr https://your-server.com/install.ps1 | iex your-registration-token

What It Manages

Platform Package Managers / Scanners
Linux APT, DNF, Docker (socket)
Windows Winget, Windows Update (COM), Docker (socket)

Agents run at the OS level and query the Docker socket directly — there's no separate container agent. Agents are pull-based: they check in every 5 minutes and execute what the server has approved. The server never initiates a connection.


Trust Model

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. This prevents config copying between hosts.

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 with a sliding window — a new key is promoted to primary while the old key remains active, so agents that cached the previous key continue verifying successfully until the operator deactivates it. Rotation is zero-downtime; no coordinated restart required.

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.

Before a package is installed: the agent fetches the expected SHA-256 from the server, downloads the artifact, verifies the hash. Mismatch blocks the install. OSV.dev is queried for known vulnerabilities at discovery time (async, deduped) for npm, PyPI, apt, and dnf packages — results are visible in the dashboard before approval.

Refresh-token rotation (90-day TTL). Each renewal mints a new refresh token (90-day expiry) 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.

Machine-bound renewal. The renewal endpoint now checks X-Machine-ID against the registered host, exactly as command endpoints do. A stolen config.json 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.

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.


Architecture

┌─────────────────┐
│  Web Dashboard  │  React + TypeScript
│  Port: 31336    │
└────────┬────────┘
         │ HTTPS + JWT + Machine Binding
┌────────▼────────┐
│  Server (Go)    │  PostgreSQL · Ed25519 Signing Service
│  Port: 31337    │
└────────┬────────┘
         │ Pull-based (agents check in, not the reverse)
         ├──────────────────┐
┌────────▼────────┐  ┌──────▼──────────┐
│   Linux Agent   │  │  Windows Agent  │
│                 │  │                 │
│  APT / DNF      │  │  Winget / WUA   │
│  Docker socket  │  │  Docker socket  │
└─────────────────┘  └─────────────────┘

Features

  • Approval workflow — updates queue for human review before anything runs
  • Maintenance windows — day/time gates on when installs can proceed
  • Upstream tracking — polls GitHub, Gitea, GitLab, Bitbucket for new releases; flags EOL drift
  • Drift detection — knows what should be installed vs. what is, bridges the gap into update packages
  • Agent self-update — SHA-256 → signature → atomic binary swap → service restart, reconciled server-side
  • Dependency dry-run — checks before installing, not after
  • Idempotent installer — re-running won't create duplicate agents
  • Proxy support — HTTP/HTTPS/SOCKS5 for restricted networks
  • Native services — systemd on Linux, Windows Services on Windows
  • Full audit trail — all operations logged with context, sanitized against log injection

Status

Compiles, runs on the maintainer's stack, not yet battle-tested. No live deployment outside the dev environment. The gate (supply-chain verification) has not completed a full end-to-end run against real infrastructure. Treat everything below as "implemented and locally exercised, not production-proven."

Implemented:

  • Linux and Windows agent registration and update management
  • APT, DNF, Winget, Windows Update, Docker image scanning
  • Dry-run dependency checking
  • Real-time heartbeat and rapid polling
  • Ed25519 key rotation and replay protection
  • Supply chain hash verification and OSV.dev checks
  • Maintenance windows
  • Upstream version tracking (GitHub, Gitea, GitLab, Bitbucket, Repology, endoflife.date)
  • Agent self-update via privileged helper (zero agent sudo)

Not yet done:

  • Live end-to-end gate test (GATE-002)
  • Windows installer stubs report fake success (CRITICAL-004)
  • No AUR, Snap, Flatpak, or Homebrew support
  • macOS agent binaries not signed
  • Mobile dashboard usable, not optimized

Updating

git pull && docker-compose down && docker-compose build --no-cache && docker-compose up -d

Agent self-update runs from the dashboard. Requires a real service manager (systemd on Linux, SCM on Windows). Container-only agent deployments can't self-update through this path — redeploy with the new image instead.

If a self-update times out, the previous binary is preserved at <binary>.bak on the agent host. Restore manually and restart the service.

Nuclear option (full reset)
docker-compose down -v --remove-orphans && \
  rm config/.env && \
  docker-compose build --no-cache && \
  cp config/.env.bootstrap.example config/.env && \
  docker-compose up -d

This wipes all data including the database. Re-register agents afterward with new tokens.

Upgrading from pre-v0.1.20

Old installations used different paths. Clean reinstall is the supported migration path.

Remove old artifacts if present:

sudo rm -rf /etc/aggregator/ /usr/local/bin/aggregator-agent /var/lib/aggregator/

Then install fresh with the standard one-liner.


Philosophy

RedFlag follows ETHOS:

  • Honest — what you see is what you get
  • Transparent — errors logged with full context, sanitized against injection
  • Secure — hardware binding, cryptographic verification, local-only logging
  • Open standards — no vendor lock-in, no cloud dependency, no telemetry

The maintainer runs this on their own infrastructure. Releases are versioned, migrations are idempotent. If something breaks, the error shows up in full — not swallowed into a generic failure message. Log output is sanitized against injection (ANSI stripping, control character replacement, field truncation) but the content is preserved.

Built for operators who'd rather own the problem than outsource it.


Changelog

v0.2.1.0 (May 2026)

  • Helper privilege split: redflag-helper now invoked via sudo systemd-run --pipe as its own transient service, escaping the agent's ProtectSystem=strict sandbox. The helper and its dnf/apt children see the real root filesystem.
  • Token-is-the-command: all package-manager operations now routed through one of two paths — discovery (scan, dry-run, hash-resolve) through a unified DiscoveryRunner, mutation (install, upgrade) exclusively through consumer.go → systemd-run --pipe → redflag-helper. The agent no longer has code to run dnf install -y or apt install -y directly.
  • SecureCommandExecutor deleted — replaced by DiscoveryRunner for discovery and the helper for mutation.
  • Sudoers narrowed: agent user can no longer run mutation commands (dnf install *, apt install -y *, etc.) — only discovery + the helper invocation.
  • EcosystemConfig registry: adding a new package ecosystem (AUR, Snap, Flatpak, Homebrew) means one config entry and implementing the discovery interface. Mutation is automatic via the token path.
  • Hash verification fail-closed: empty expected hash now returns an error instead of silently passing.
  • Installer interface shrunk from 7 methods to 4: IsAvailable, GetPackageType, DryRun, VerifyHash.
  • apt-getapt throughout (ecosystem config, sudoers, discovery commands).

v0.2.0.7 (May 2026)

  • Refresh-token rotation with accept-previous-once crash-recovery grace
  • Machine-bound renewal path closes stolen-config.json replay attack
  • Typed sentinel errors for auth failures in agent polling loop
  • Loud terminal-state detection: revoked refresh tokens and machine-ID mismatches surface as critical events, not silent retries
  • No-more-unsigned-binaries: signing-disabled path removed from orchestrator; unsigned fallback removed from download handler

v0.2.0.6 (May 2026)

  • Agent cold-start trust root: signed release manifest verified before first binary execution
  • Supply-chain hash registry (Layer 1): expected SHA-256 stored server-side, verified by agents before install
  • Drift → UpdatePackage bridge: drifted bindings automatically create pending update packages
  • Upstream tracking UI with release-source adapters (GitHub, Gitea, GitLab, Bitbucket)
  • Attention panel: surfaces offline agents, failed updates, EOL drift, upstream movement

v0.2.0.0 (May 2026)

  • Maintenance windows for scheduling/gating installs
  • OSV.dev supply chain checks at approval time (npm/PyPI)
  • Ed25519 key rotation with TTL-based auto-refresh
  • Command signing v3: agent_id binding prevents relay attacks
  • Replay protection via signed nonces (10-minute window)
  • Semver-aware version comparison
  • Binary path traversal protection
  • Machine ID rebind endpoint for hardware migration
  • 170+ tests across 18 packages
  • Command lifecycle v2: received state, disk-persisted dedup, authenticated binary download

v0.1.27 (December 2025)

  • Hardware binding with machine fingerprinting
  • Ed25519 signing for all commands and updates
  • Error transparency system (ETHOS #1)
  • Circuit breakers and retry logic
  • Agent auto-update fully implemented
  • Rate limiting (60 req/min, configurable)
  • Command deduplication and idempotency

License

MIT — see LICENSE.

Third-party: Windows Update integration based on windowsupdate (Apache 2.0).