Security Model for Executing Commands from .no-mistakes.yaml: Supply-Chain Protection

The no-mistakes daemon executes commands only from a trusted copy of .no-mistakes.yaml pinned to the default branch SHA, ignoring pull request versions unless the maintainer explicitly enables allow_repo_commands on the default branch.

The open-source kunchenguid/no-mistakes repository implements a defense-in-depth security model for executing commands from .no-mistakes.yaml that treats configuration files as supply-chain boundaries. When the daemon runs automated workflows, it strictly validates the file's origin before invoking any shell commands via shellenv.ConfigureShellCommand, ensuring only maintainer-approved code executes.

How the Security Model Works

Trusted Config Loading via loadTrustedRepoConfig

The loadTrustedRepoConfig function in internal/daemon/manager.go reads .no-mistakes.yaml from a pinned SHA that points to the current default-branch tip, not from the mutable origin/<default> ref. If the fetch fails or the SHA cannot be resolved, the function returns nil, which forces an empty command set and prevents execution.

EffectiveRepoConfig and Field Merging

The EffectiveRepoConfig function (implemented in internal/config/config.go) merges the trusted configuration with non-executing fields from the pushed branch. When allow_repo_commands is false (the default), the commands.* and agent sections from the trusted config are used while values from the pushed branch are ignored.

The allow_repo_commands Flag

This per-repository boolean defaults to false. When a maintainer explicitly sets it to true in the default-branch config, the daemon may honor commands.* and agent from the pushed branch. Contributors cannot enable this themselves—the flag must reside in the trusted default-branch version, preventing attackers from activating command execution via pull requests.

Fail-Closed Execution Behavior

The daemon ultimately runs commands with sh -c using shellenv.ConfigureShellCommand. Because only the trusted config can supply the command string, attackers cannot inject arbitrary code through PRs. Any inability to locate a trusted SHA or read the trusted file makes EffectiveRepoConfig drop the command fields, guaranteeing that no unverified commands execute. This protects against stale refs left by previous runs.

Configuration Examples

Default Secure Configuration

When allow_repo_commands is false (or omitted), the daemon ignores any commands or agent values in the PR's version of the file:


# .no-mistakes.yaml stored on the default branch

commands:
  lint: go vet ./...
  test: go test -race ./...
agent: claude
allow_repo_commands: false   # default – only trusted commands run

Opt-In to PR-Provided Commands

Maintainers can explicitly trust PR-provided commands by setting the flag on the default branch:


# .no-mistakes.yaml on the default branch

allow_repo_commands: true   # maintainer explicitly trusts the PR

Now the daemon will read commands: and agent: from the PR's .no-mistakes.yaml, but only after confirming the file's presence on the default branch.

Implementation Details

Command Execution Flow

The startRun function in internal/daemon/manager.go orchestrates the security checks:

func startRun(ctx context.Context, wtDir string) {
    // 1. Resolve default‑branch tip to a SHA.
    tipSHA, err := git.ResolveRef(ctx, wtDir, "origin/main")
    // 2. Load the trusted config from that exact SHA.
    trustedCfg := loadTrustedRepoConfig(ctx, wtDir, tipSHA, runID)

    // 3. Build the effective config (trusted + non‑executing fields from PR).
    effective := config.EffectiveRepoConfig(trustedCfg, pushedCfg)

    // 4. Run commands from the effective config (commands come from trustedCfg
    //    unless allow_repo_commands is true).
    execCommands(effective.Commands)
}

Key Source Files

Summary

  • The daemon treats .no-mistakes.yaml as a supply-chain security boundary, executing commands only from a trusted copy pinned to the default branch SHA.
  • loadTrustedRepoConfig enforces the trust boundary by reading from a specific SHA, returning nil if the file cannot be verified.
  • allow_repo_commands defaults to false and must be explicitly enabled by maintainers on the default branch; contributors cannot activate it via PRs.
  • Fail-closed behavior ensures that any verification failure results in empty command sets, preventing RCE attacks.
  • Command execution uses sh -c via shellenv.ConfigureShellCommand, but only receives strings from the verified trusted configuration.

Frequently Asked Questions

Can a contributor enable command execution via a pull request?

No. The allow_repo_commands flag must be set to true in the .no-mistakes.yaml file on the default branch. Because the daemon reads this flag from the trusted configuration via EffectiveRepoConfig, contributors cannot enable PR-provided commands themselves.

What happens if the default branch SHA cannot be resolved?

The loadTrustedRepoConfig function returns nil, causing EffectiveRepoConfig to drop all command fields. This fail-closed behavior guarantees that no unverified commands execute when the trusted file cannot be located.

How does no-mistakes prevent RCE attacks from malicious PRs?

By treating the .no-mistakes.yaml file as a supply-chain security boundary, the daemon only runs commands from the trusted default-branch version. Even if a PR contains malicious commands or agent directives, these are ignored unless allow_repo_commands: true is explicitly set on the default branch.

Where is the trusted configuration logic implemented?

The core logic resides in internal/daemon/manager.go (orchestration and loadTrustedRepoConfig) and internal/config/config.go (EffectiveRepoConfig and flag enforcement). Test coverage exists in internal/daemon/manager_trust_test.go and internal/e2e/repo_config_security_test.go.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →