Skip to content

Security: ruvnet/dream-machine

Security

SECURITY.md

Security Policy

Reporting a vulnerability

Please report security issues privately via GitHub Security Advisories (Security → Report a vulnerability) on this repository, or email ruv@ruv.net. Do not open a public issue for a suspected vulnerability.

We aim to acknowledge within 72 hours.

Threat model & design guarantees

The Dream Machine runs an autonomous nightly loop against a repository. Its safety rests on a small set of invariants, enforced in code and CI:

  • Evaluation is not promotion. The nightly session never merges and never self-promotes candidate state. It only opens draft PRs.
  • Human merge authority. The legacy automerge.yml workflow is now a read-only policy guard. It cannot merge, enable deferred auto-merge, assign labels, or promote artifacts. autoMerge: false in the base revision's dream.config.json disables eligibility. Missing or malformed configuration also denies eligibility. Setting the flag to true would only permit an eligibility assessment, never a merge. Human review and GitHub's configured branch protections remain separate requirements.
  • Constitutional path protection. The guard evaluates the complete, paginated file list and both names of renames or copies. It denies protected documentation (including ADRs, contracts, benchmarks, research plans and threat models), policy tooling, manifests, lockfiles, configuration, tests, provenance packages and named safety/authority boundaries. Missing files, duplicates, more than 3,000 files, malformed metadata, forks, drafts, missing labels and changes to the observed head or base revision deny eligibility. This conservative path classifier is not a semantic safety proof; an eligible result still requires human review of the exact diff.
  • Least-privilege CI. Each workflow declares the minimum permissions: it needs; contents: read is the default.
  • Optional dependencies are optional. The ruvector/RVF wasm backends are peer-optional; a missing module is a graceful no-op (verified by the no-optional-deps CI job).
  • Witnessed provenance. Every nightly report is bound to its commit by a reproducible double-sha256 witness that any third party can re-derive.

Supply chain

  • npm publishes use OIDC provenance (--provenance).
  • Dependabot watches npm and GitHub Actions.
  • CodeQL (security-extended) runs on every push, PR, and weekly.

Merge policy deployment and verification

pull_request_target executes only the trusted base revision, never PR code. The guard installs no dependencies, retains no checkout credentials and uses only contents: read and pull-requests: read. API results are data; file names are not interpolated into shell commands or workflow output.

This change takes effect only after a human merges it into the base branch. While it is a draft PR, the previous base workflow is still authoritative. Maintainers must separately inspect and cancel any previously enabled pending auto-merges, then verify branch protection requires the intended tests and human approvals. This read-only workflow cannot revoke existing merge requests or enforce repository administrator settings.

Run node --test scripts/automerge-guard.test.mjs to reproduce the policy regressions. Tests use synthetic GitHub responses, including a protected file on page two and stale PR metadata. They do not exercise a live merge or prove that remote branch protections are configured. A blocked eligibility result is informational and does not prevent a separately authorized human merge.

Explicitly authorized software factory coordinator

On 2026-10-11 the repository owner authorized end-to-end automatic merging and publication for the software factory. This is a narrow exception to the default human-only routine above. Candidate workers still have no merge or publication credentials and their reports never grant authority. A separately acting factory coordinator may merge an exact reviewed head after independent review and passing required checks, without bypassing branch protection. It may publish only the verified dream-machine prerelease to next and its sanitized public gist. The default guard remains informational and does not itself grant merge rights.

The ruOS publisher loads only NPM_TOKEN from its protected local binding, validates the exact package name, prerelease version, tarball allowlist and digest, disables lifecycle scripts, and verifies the registry integrity. It never moves the key to ChatGPT or GitHub. This token route does not provide OIDC provenance. Existing versions with different bytes fail closed. Stable releases and other package names remain outside the automatic publisher.

There aren't any published security advisories