Why Vigo

Simplicity, security, reliability, scalability, and price — where Vigo is different from every other distributed state enforcement system and configuration management tool.

Puppet vs Vigo — side by side

Create a user with passwordless sudo and an SSH key — a task every team does. Puppet needs 4 resources across 2 files. Vigo needs one.

Puppet — 2 files, 4 resources
manifests/profile/admin_user.pp
class profile::admin_user (
  String $username,
  String $ssh_pubkey,
  String $comment     = '',
  Array  $groups      = ['sudo'],
) {
  user { $username:
    ensure     => present,
    managehome => true,
    shell      => '/bin/bash',
    comment    => $comment,
    groups     => $groups,
  }

  file { "/home/${username}/.ssh":
    ensure  => directory,
    owner   => $username,
    group   => $username,
    mode    => '0700',
    require => User[$username],
  }

  ssh_authorized_key { "${username}_key":
    ensure  => present,
    user    => $username,
    type    => 'ssh-ed25519',
    key     => $ssh_pubkey,
    require => File["/home/${username}/.ssh"],
  }

  file { "/etc/sudoers.d/${username}":
    ensure  => file,
    owner   => 'root',
    group   => 'root',
    mode    => '0440',
    content => "${username} ALL=(ALL) NOPASSWD: ALL\n",
  }
}
hieradata/nodes/web01.yaml
classes:
  - profile::admin_user

profile::admin_user::username: 'alice'
profile::admin_user::comment: 'Alice Nguyen'
profile::admin_user::groups:
  - sudo
  - adm
profile::admin_user::ssh_pubkey: 'AAAAC3NzaC1lZDI1NTE5AAAAIJqR...'
Vigo — 1 file, 1 resource
modules/os-users.vgo
name: os-users

resources:
  - name: alice
    type: user
    username: alice
    comment: Alice Nguyen
    shell: /bin/bash
    groups: sudo, adm
    state: present
    password: secret:vigo/os-users/alice
    sudo_nopasswd: true
    authorized_keys: |
      ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJqR... alice@laptop

📄 Simplicity

One server at any scale

No compile masters, no worker pools, no database clusters, no load balancers. One process, one SQLite file, one config directory. The architecture does not change whether you manage 10 nodes or 100,000.

~5 MB static agent binary

No Ruby, no Python, no JVM, no package manager ecosystem on managed nodes. Copy the binary, run it. Zero runtime dependencies.

One config format, one config path

There is exactly one way to configure Vigo: edit YAML files and publish. No API writes, no database config, no UI mutations. One source of truth, one format, one tool.

No DSL

The configuration language is YAML. Go templates appear only inside content: attributes. No custom language to learn, no compiler, no parser quirks.

Bootstrap is one command

curl | sudo sh downloads the binary, generates TLS certificates, registers with the server, installs the service, and verifies connectivity. Under management in 30 seconds.

Seven OS families from one codebase

Linux, macOS, FreeBSD, OpenBSD, NetBSD, illumos, and Windows. Write type: service and it dispatches to systemd, launchctl, rc.d, rcctl, SMF, or sc.exe.

Conditional resources without an if DSL

when: "os_family('debian')" on any resource or module. Boolean logic, builtins like has_command, arch, version_ge. Server evaluates what it can, passes the rest to the agent. No DSL, no plugins.

Visibility — trace any decision back to its source

One command — vigocli config trace danlap — shows the complete resolution chain for any node. Every module, variable, dependency, compliance tag, waiver, and conditional traced to the exact file that defined it.

Vigo config trace showing directory inheritance tree with path and module resolution for danlap
Path inheritance — the directory tree that contributes to this node's config, from fleet root down to the leaf entry file.
Vigo module inheritance showing per-level module lists and role expansion for danlap
Module inheritance — which modules and roles came from which file, with role expansion showing the modules each role contributes.
Vigo variable inheritance chain showing per-level vars with override markers and final resolution sources
Variable inheritance — vars defined at each directory level, override markers where a child shadows a parent, and the final resolution showing where each var's value came from.
Vigo dependency inheritance showing depends_on, notify, and subscribes edges between resources
Dependency inheritance — the full DAG of depends_on, notify, and subscribes edges. Resources execute in topological order; notify triggers re-application when a dependency changes.
Vigo conditional inheritance showing server-side and agent-side when expressions with template variable resolution
Conditional inheritance — every when: expression with its evaluation side. Server-side conditions (like changed) are resolved before dispatch; agent-side conditions (like os_family and hour_range) run on the managed node. Template variables are resolved and shown beneath the original expression.
Vigo compliance inheritance mapping modules to framework controls across CIS, HIPAA, NIST, PCI DSS, SOC 2, ISO 27001, and DISA STIG
Compliance inheritance — every module's compliance tags mapped to framework controls. Seven frameworks, from CIS benchmarks to HIPAA and PCI DSS, traced to the module that enforces them.
Vigo waiver inheritance showing approved compliance control exemptions with approver and source file
Waivers inheritance — approved exemptions for specific compliance controls. Each waiver records who approved it, why, and which file defined it. Waivers inherit through the directory chain.

🔒 Security

Per-request ED25519 signatures

Every agent request is individually signed and verified against stored public keys. Not just TLS — actual cryptographic proof of identity on every API call. Replay and impersonation require the private key, not just a valid certificate.

Secrets are never materialized

The secret: prefix resolves at config load through a pluggable provider and is stripped before transmission. Secrets never appear in YAML files, environment variables, logs, database rows, gRPC payloads, or run result reports.

No plaintext mode

mTLS is the only transport. There is no --no-ssl flag, no plaintext fallback, no "development mode" that skips encryption. The insecure path does not exist in the codebase.

One-time enrollment tokens

Tokens are bcrypt-hashed at rest and bound to hostname glob patterns. A token that matches *.web.prod cannot enroll a machine named db01.staging. Used once, then permanently invalidated.

Self-protection guardrails

The validation pipeline blocks any resource that targets the agent binary, server binary, config directory, or service unit. Even --dangerous mode cannot bypass these checks. The system cannot be used to break itself.

Verified agent binary

The agent binary is distributed with ED25519 signatures and SHA-256 checksums, verified at bootstrap. Binary hardening includes PIE, full RELRO, stack protectors, stripped symbols, and LTO.

⚡ Reliability

Signed policy bundles with offline convergence

The server signs bundles with ED25519. The agent verifies, caches in LMDB, and continues converging indefinitely if the server disappears. Pending results queue and drain on reconnect.

Adaptive stream promotion

Agents default to lightweight stateless polling. Persistent streams are promoted only when the server has work to dispatch, then released. Idle agents consume zero stream resources.

Evaluation resilience

A template render error or a when: parse error in one resource skips that resource and continues with the rest of the convergence run. A single bad resource does not abort the entire policy.

Zero database operations on the hot path

The FleetIndex is a fully in-memory index with async dirty-set flushing. An agent check-in — lookup, policy compilation, and response — touches zero database queries.

The agent never exits on transient failures

Server unreachable, TLS handshake failure, malformed response, policy evaluation crash — all handled with backoff and retry. The agent binary, once started, runs until explicitly stopped.

Reload with graceful fallback

Config publish validates, syncs, and reloads. If the new config fails validation, the server keeps the previous working config. No downtime, no partial state.

Browser-based remote access (Scrier)

SSH terminals, RDP desktops, and live session shadowing from the web UI. No VPN, no bastion, no port forwarding. Tunnels through the agent's existing mTLS connection. Ephemeral keys per session. Shadow/assist mode lets help desk see and control a user's live desktop with consent.

Observe mode for safe migration

Run Vigo alongside existing CM. Agents report what they would change without applying anything. Cut over when confident. Per-node or fleet-wide.

📈 Scalability

50,000–200,000 nodes per server

On a single 4-core, 8 GB machine. No compile masters, no worker pools, no database clusters. See the analysis →

~300 µs check-in latency

Cache-hit check-ins complete in microseconds, not milliseconds. No catalog compilation, no Ruby interpretation, no database round-trips. 3,300 check-ins per second on a single core.

~50 MB RAM at 10,000 nodes

The in-memory FleetIndex stores only what it needs. Puppet Server requires 8–16 GB for the same fleet. Chef requires 4–8 GB. Vigo runs on a Raspberry Pi.

No external database

SQLite in WAL mode. No PostgreSQL cluster to provision, tune, backup, upgrade, or keep alive at 3 AM. The database is a single file you can copy with cp.

Delta streaming protocol

After the initial check-in, agents send only what changed — traits deltas, run completions, heartbeats. No redundant full-state transfers on every cycle.

Hub-spoke spanner for multi-region

When one server is not enough, spanner fans out enrollment, queries, and tasks across spoke servers. Each spoke manages its own fleet. The hub aggregates results. No shared database.

💰 Price

Free for 25 nodes. No time limit.*

No credit card, no feature gates. Every capability — orchestration, workflows, queries, native integrations, compliance export, AI assistant — is included at every tier.

No enterprise-only features

There is no "Enterprise Edition" with critical features held back. RBAC, OIDC, API tokens, compliance export, spanner — all included. The free tier is the full product.

Infrastructure cost: near zero

One process, one SQLite file, ~50 MB RAM at 10,000 nodes. No PostgreSQL cluster, no Redis, no message queue, no compile master fleet. The server that runs your monitoring can run Vigo too.

No per-node agent licensing

The agent binary is freely distributable. You pay for the server-side node count, not per agent install. Decommission and re-enroll without license churn.

Simple per-node pricing

$144/node/year at 26 nodes, dropping to $84/node/year at scale. Volume discounts are automatic. No sales calls required until 5,000+ nodes.

Lowest total cost of ownership

License is the only meaningful cost. No compile masters, no PostgreSQL DBA, no dedicated CM engineers. At 1,000 nodes, Vigo's total TCO is ~$172K. Puppet's is ~$284K. See the full TCO breakdown →

See how it compares

Detailed head-to-head analysis against Puppet, Ansible, Chef, Salt, and CFEngine.

* Free tier is for evaluation purposes only and is provided AS IS with no support obligation. See Commercial Terms.