ExecFence

ExecFence: Guardrails Before Repository Code Executes

This is a technical launch article for ExecFence, a local guardrail for the moment a software project starts executing code on a developer machine, CI runner, or agent workspace.

The short version:

npx --yes execfence scan
npx --yes execfence run -- npm test
npx --yes execfence run --sandbox-mode audit -- npm run build

Before going deeper, it is important to separate two installation surfaces:

In short: npm runs the guardrail; the skill teaches the agent to use the guardrail.

The ExecFence skill is also proposed for the OpenAI Skills catalog in openai/skills#385, which gives the project an external integration path beyond the npm package.

ExecFence exists because malicious code does not need to look like an obvious executable. It can hide in package hooks, build configs, IDE tasks, lockfiles, CI workflows, or agent tool manifests. The dangerous moment is often mundane: a developer runs test/build/dev, opens a folder in an IDE, installs dependencies, or lets an agent run the project.

Quick Start

Run a scan:

npx --yes execfence scan

Expected clean output:

[execfence] OK
[execfence] wrote report to /project/.execfence/reports/my-app_2026-05-01T19-00-00-000Z.json

Run a project command through the runtime gate:

npx --yes execfence run -- npm test

Expected clean runtime behavior:

[execfence] preflight scan: OK
> npm test
...
[execfence] post-run scan: OK
[execfence] runtime report: /project/.execfence/reports/my-app_2026-05-01T19-01-00-000Z.json

If ExecFence detects a known injected loader marker or suspicious execution pattern, the command fails before project code runs:

[execfence] blocked suspicious finding(s)

critical  void-dokkaebi-loader-marker  tailwind.config.js:1
Injected JavaScript loader marker associated with suspicious repository execution.

[execfence] wrote report to /project/.execfence/reports/my-app_2026-05-01T19-02-00-000Z.json

For higher-risk local execution, use sandbox audit mode:

npx --yes execfence sandbox doctor
npx --yes execfence sandbox plan -- npm test
npx --yes execfence run --sandbox-mode audit -- npm test

Hard sandbox enforcement is explicit:

npx --yes execfence run --sandbox -- npm test

If the platform or helper cannot enforce the required filesystem, process-tree, sensitive-read, new-executable, or network policy, ExecFence blocks before execution. It does not silently downgrade --sandbox to audit mode. Metadata-only helpers do not count; enforce mode requires a helper binary with matching SHA-256 and a successful execfence-helper self-test.

If ExecFence Blocks

This is the most important operational path. A block usually happens at the moment a developer or agent is about to run project code, so the right response should be clear and boring:

npx --yes execfence reports latest
npx --yes execfence reports open <report>
npx --yes execfence incident bundle --from-report .execfence/reports/<report>.json

When ExecFence blocks:

  1. Do not rerun the blocked command outside ExecFence.
  2. Preserve the JSON report and suspicious files.
  3. Review the finding id, severity, file, line, snippet, SHA-256, git blame, and recent commits.
  4. Check package scripts, lockfiles, workflows, and agent/MCP configs related to the finding.
  5. If already-executed code may have touched secrets, rotate credentials.

The report is the evidence handoff. It is designed to answer: what blocked, where it was, why it was suspicious, what changed recently, and what to inspect next.

Why ExecFence Was Created

ExecFence started from a practical incident-response question. A project build/test path produced a temporary Go test binary that local security tooling flagged as PasswordStealer.Spyware.Stealer.DDS. The immediate question was whether that specific binary was malicious. The better engineering question was:

What guardrail should exist so a developer does not need to manually notice every injected payload before running build, dev, or test?

That question maps directly to current developer-targeted attacks.

Trend Micro’s research on Void Dokkaebi describes fake job interview lures that push developers toward code repositories and turn repository execution into a malware delivery path: Void Dokkaebi Uses Fake Job Interview Lure to Spread Malware via Code Repositories.

Microsoft’s research on Contagious Interview describes a related trust problem: attackers use recruitment workflows, malicious packages, and Visual Studio Code task execution after repository trust is granted: Contagious Interview: Malware delivered through fake developer job interviews.

Datadog’s analysis of the 2026 axios npm compromise shows the supply-chain form of the same execution problem: malicious releases introduced a dependency with a postinstall script that downloaded and ran a cross-platform RAT during install, then removed traces from disk: Compromised axios npm package delivers cross-platform RAT.

The shared lesson is operational: ordinary developer commands can become the execution trigger.

CLI Install vs Codex Skill Install

ExecFence has two installation paths because there are two different users of the tool: humans/CI running commands, and coding agents deciding which commands to run.

The npm CLI

The npm package provides the actual execfence command.

You can run it without a global install:

npx --yes execfence guard enable
npx --yes execfence guard enable --apply
npx --yes execfence guard status
npx --yes execfence scan
npx --yes execfence run -- npm test
npx --yes execfence ci

Or install it globally if you prefer:

npm install -g execfence
execfence scan

The CLI runs in:

The CLI is the part that performs enforcement and evidence collection:

If you only want terminal/CI protection, the npm CLI is enough.

For repository-local protection, use project guard mode:

npx --yes execfence guard enable
npx --yes execfence guard enable --apply

The first command is a dry-run. The second writes reversible project-local changes. Use npx --yes execfence guard disable to preview removal, then npx --yes execfence guard disable --apply to remove generated wrappers and marked agent rules while preserving evidence and configuration.

For terminal and agent-run package-manager commands, use global guard mode. It installs reversible shims for npm/pnpm/yarn/Bun, Python, Cargo, Go, Maven/Gradle, dotnet/NuGet, Composer, and Bundler so raw commands such as npm test, pnpm add, pip install, cargo test, go get, and composer require pass through ExecFence before the real package manager starts.

The Codex/Agent Skill

The skill is different. It is not the scanner. It is an instruction layer for Codex and compatible agent workflows.

Install it with:

npx --yes execfence install-skill

That command installs:

After that, Codex can use the skill when it is working on a persistent project. The skill should make the agent:

The skill runs in the agent’s reasoning context. The CLI runs in the operating system process. That distinction matters:

Question npm CLI Codex/agent skill
Does it scan files? Yes No, it tells the agent to run the CLI
Does it block commands? Yes, by exit code No, it instructs the agent not to bypass blocks
Does it write reports? Yes, under .execfence/reports/ No, but it tells the agent to preserve/read reports
Does it run in CI? Yes No
Does it change agent behavior? Only if the agent calls it Yes
Is it useful without Codex? Yes No, except as portable guidance
Is it useful without npm CLI? No Limited; it needs a guardrail command to invoke

For best results, use both:

npx --yes execfence install-skill
npx --yes execfence guard enable --apply
npx --yes execfence run -- npm test

This gives the human and CI a real command-line guardrail, and gives Codex/agents the instruction to keep using it.

Project-Local Agent Rules

There is a third, portable option:

npx --yes execfence install-agent-rules --scope project

This writes project-local rules for tools such as Codex, Claude, Gemini, Cursor, Copilot, Continue, Windsurf, Aider, Roo, and Cline.

Use this when the repository itself should carry the instruction:

before running build/dev/test or changing execution surfaces, use ExecFence.

This is useful for teams because the rule travels with the repository instead of living only in one developer’s global Codex setup.

How ExecFence Fits Into A Security Stack

ExecFence is not an antivirus, EDR, SCA platform, secret scanner, or malware sandbox. It does not try to replace those tools.

It sits earlier in the workflow:

clone/open repo -> inspect execution surfaces -> scan -> gate command -> record evidence -> run existing security tools

Use it with:

ExecFence’s role is to stop or document suspicious execution before a normal project command becomes the payload trigger.

Why Dependency-Free Matters

ExecFence’s base CLI intentionally has zero runtime dependencies.

That matters in this threat model because installing a security tool should not create a large new dependency tree with its own install hooks, transitive packages, typosquatting surface, or postinstall behavior. A guardrail for package-execution risk should be small enough to inspect, run through npx, and package with low supply-chain blast radius.

Dependency-free also helps in CI and incident response:

ExecFence v5 introduces a real helper contract for Windows and Linux. The base scanner, runtime gate, reports, CI command, and skill remain usable without mandatory helper installation, but enforce mode only runs through a verified helper binary that passes execfence-helper self-test. Metadata-only helpers do not enable enforcement, and the npm package ships helper source for review/build rather than a prebuilt trusted helper binary.

What The Scanner Inspects

The scanner is designed around execution surfaces, not only source files.

It inspects:

It skips normal generated or dependency directories such as .git, node_modules, dist, build, coverage, target, caches, and test output by default.

How Detection Works

ExecFence combines exact IoC matching, project/team regex signatures, suspicious loader heuristics, lifecycle-script audit, lockfile source review, executable/archive detection, workflow hardening checks, and agent/MCP surface audit. The lifecycle audit covers install-time download/eval chains, pipe-to-shell behavior, hidden PowerShell, and Windows LOLBins or script hosts such as bitsadmin, mshta, rundll32, and regsvr32.

The important design choice is scope: rules are weighted toward files that execute during development, build, test, CI, package, publish, IDE, or agent workflows. ExecFence is not trying to lint every source file; it is trying to catch suspicious code where a normal command can activate it.

For the full technical detection breakdown, including baselines and exceptions, see Detection Model.

Mapping To Real Attack Patterns

Public case Attack pattern ExecFence control
Trend Micro Void Dokkaebi Fake interview repositories and malicious code execution through developer workflows scan, known IoCs, loader heuristics, VS Code task checks, runtime gate
Microsoft Contagious Interview Recruitment workflow abuse, malicious packages, VS Code trust/task execution coverage, .vscode/tasks.json audit, package lifecycle checks, run --sandbox-mode audit
Datadog axios compromise Compromised npm releases added a dependency with postinstall RAT execution and cleanup behavior lifecycle script audit, lockfile diff, deps diff, pack audit, reports, CI gate

ExecFence does not claim campaign attribution. It turns the lessons from those incidents into local controls around execution.

Main Functional Areas

What Version 5 Adds

Version 5 is the release that combines multi-ecosystem supply-chain coverage with the first real platform-helper sandbox contract.

The supply-chain expansion is no longer npm-only. ExecFence now understands package-manager and runtime surfaces across npm/pnpm/Yarn/Bun, Python, Rust/Cargo, Go, JVM, .NET/NuGet, Composer/PHP, and Bundler/Ruby. That means deps diff, deps review, ci, coverage, manifest, wire, global package-manager shims, runtime dependency behavior audit, and reports all consume the same ecosystem adapter layer instead of treating non-npm ecosystems as partial side cases.

The sandbox expansion is helper-backed. Enforce mode does not trust a config flag or metadata declaration. It requires a real Windows/Linux helper binary, hash verification, platform/arch match, provenance metadata, and a successful execfence-helper self-test. Only then can execfence run --sandbox -- <command> delegate execution to execfence-helper run --policy <policy.json> -- <command>.

Version 5 keeps the same non-claim: ExecFence does not prove arbitrary third-party code benign. It blocks and records observable execution surfaces, dependency drift, helper capability proof, and runtime evidence. If a capability cannot be proven on the current host, it is reported as unsupported and strict/enforce blocks.

Essential Commands

These are the commands most projects should start with:

npx --yes execfence init --preset auto
npx --yes execfence scan
npx --yes execfence run -- npm test
npx --yes execfence ci

Use them to initialize policy, scan before execution, wrap local test/build commands, and run the aggregate CI guard.

Static Scan

npx --yes execfence scan
npx --yes execfence scan --mode audit
npx --yes execfence scan --changed-only --ci --format json
npx --yes execfence scan --ci --format sarif

Use this before running project code, during review, and in CI.

Runtime Gate

npx --yes execfence run -- npm test
npx --yes execfence run -- npm run build
npx --yes execfence run -- go test ./...
npx --yes execfence run -- python -m pytest
npx --yes execfence run -- cargo test

run performs:

  1. preflight scan
  2. command execution only if allowed
  3. runtime trace
  4. file snapshot comparison
  5. post-run scan of changed files
  6. JSON report generation

For artifact-sensitive workflows:

npx --yes execfence run --record-artifacts --deny-on-new-executable -- npm test

Sandbox Audit And Enforce Mode

npx --yes execfence sandbox init
npx --yes execfence sandbox doctor
npx --yes execfence sandbox plan -- npm test
npx --yes execfence sandbox install-helper --binary ./path/to/execfence-helper
npx --yes execfence helper audit
npx --yes execfence run --sandbox-mode audit -- npm test

Audit mode records what would be allowed or blocked across filesystem, process, and network policy.

Before enforce mode can run, build or obtain a reviewed Windows/Linux helper binary and register that exact file. The package includes helper source under helper/; it does not silently install or trust a compiled helper during npx or global CLI installation.

Enforce mode is explicit:

npx --yes execfence run --sandbox -- npm test

If enforcement is unavailable, the command blocks before running. Downgrade requires explicit --sandbox-mode audit or --allow-degraded. In enforce mode, ExecFence writes a policy JSON and delegates execution to execfence-helper run --policy <policy.json> -- <command>; the helper emits JSONL events for spawn, deny, filesystem, process, network, new executable, and exit evidence.

The v5 helper contract is deliberately evidence-driven:

The current unprivileged helper proves process supervision, Windows Job Object or Linux process-group child handling, and new executable artifact detection. Filesystem pre-read denial, sensitive-read denial, and outbound network blocking require a real platform broker/elevated capability before ExecFence will claim them.

Execution Manifest And Coverage

npx --yes execfence manifest
npx --yes execfence manifest diff
npx --yes execfence coverage
npx --yes execfence coverage --fix-suggestions

These commands answer:

Wiring

npx --yes execfence wire --dry-run
npx --yes execfence wire --apply
npx --yes execfence guard enable
npx --yes execfence guard enable --apply
npx --yes execfence guard disable
npx --yes execfence guard disable --apply
npx --yes execfence guard status

This helps move project commands from:

npm test

to:

execfence run -- npm test

guard enable is the recommended high-level entrypoint for project adoption. It runs init, checks coverage, applies wrappers, installs project-local agent rules, and reports remaining gaps. Global guard mode installs reversible package-manager shims:

npx --yes execfence guard global-status
npx --yes execfence guard global-enable
npx --yes execfence guard global-disable

It installs skill/defaults, global agent rules, and marked shell-profile PATH blocks for <home>/.execfence/shims/. Terminal and agent-run package-manager commands enter ExecFence before the real package manager starts. guard global-status returns an actionPlan for inactive PATH, missing shims, current-shell reload, Corepack/nvm/Volta/asdf ordering, and CI/container/IDE surfaces that still need explicit wrapping. Install-like commands get a clean preflight scan and guarded dependency metadata/reputation/tarball review. npm-like managers also get lifecycle-script suppression; ecosystems without a universal suppression flag rely on runtime behavior audit, sandbox evidence, and strict-mode blocking when containment is missing.

Supply Chain And Package Audit

npx --yes execfence deps diff
npx --yes execfence deps review
npx --yes execfence pack-audit
npx --yes execfence trust audit

These commands focus on lockfile drift, suspicious package sources, guarded package metadata/reputation, OSV advisory matches, tarball integrity/content, tarball delta against the previous resolved version, dangerous package contents, and changed trusted artifacts. For CI or release workflows, supplyChain.mode: "strict" blocks unavailable signals, cooldown/age windows, missing integrity/provenance, uncovered package-manager surfaces, and changed-dependency runtime audits that lack helper-backed containment.

Agent And MCP Report

npx --yes execfence agent-report

This flags sensitive changes in:

Example output:

{
  "ok": false,
  "sensitiveChanges": ["mcp.json"],
  "mcpFindings": [
    {
      "id": "agent-mcp-shell-access",
      "severity": "high",
      "file": "mcp.json",
      "line": 4,
      "detail": "MCP/tool config exposes broad shell or process execution capability."
    },
    {
      "id": "agent-disable-execfence-instruction",
      "severity": "high",
      "file": "mcp.json",
      "line": 5,
      "detail": "Agent or tool instruction appears to disable, skip, ignore, or bypass ExecFence/security guardrails."
    }
  ]
}

This is one of the more differentiated parts of ExecFence: it treats agent tooling as part of the execution surface, not as a trusted control plane by default.

Advanced Commands

These commands are useful once the basic workflow is in place:

npx --yes execfence scan --changed-only --ci --format json
npx --yes execfence scan --ci --format sarif
npx --yes execfence manifest diff
npx --yes execfence coverage --fix-suggestions
npx --yes execfence wire --dry-run
npx --yes execfence deps diff
npx --yes execfence deps review
npx --yes execfence pack-audit
npx --yes execfence trust audit
npx --yes execfence reports diff <old-report.json> <new-report.json>
npx --yes execfence pr-comment --report .execfence/reports/<report>.json

Use them for CI output, PR review, lockfile investigation, package publishing checks, report comparison, and team adoption.

coverage, manifest, and ci share coverage evidence. directGuarded means the command invokes ExecFence itself; covered also includes package prehooks, workflow gates, inherited guards, and active global shims.

Evidence Reports

Every blocking-capable command writes a new JSON report under:

.execfence/reports/

Reports include:

ExecFence does not delete suspicious payloads automatically. It preserves evidence first.

Project Layout

ExecFence keeps project-owned state under .execfence/:

.execfence/
  config/
    execfence.json
    signatures.json
    baseline.json
    sandbox.json
    policies/
  reports/
  cache/
  trust/
  quarantine/
  helper/
  manifest.json

Important files:

Reports are gitignored by default. A project can opt into versioning reports with reportsGitignore: false.

Validate policy before release:

npx --yes execfence config validate --strict

This checks ExecFence config, baselines, signatures, sandbox policy, and local policy packs. Invalid regexes, expired strict baselines, unpinned executable allowlist entries in strict mode, suspicious registry allowlists, and strict supply-chain mode without complete coverage fail validation.

For scanner internals, rule layers, and exception policy, continue to the Detection Model.

For an existing project:

npx --yes execfence init --preset auto
npx --yes execfence scan
npx --yes execfence coverage
npx --yes execfence wire --dry-run
npx --yes execfence run -- npm test

For a project with existing noise:

npx --yes execfence adopt
npx --yes execfence adopt --write-baseline

For CI:

npx --yes execfence ci

For higher-risk local execution:

npx --yes execfence sandbox doctor
npx --yes execfence sandbox plan -- npm test
npx --yes execfence sandbox install-helper --binary ./path/to/execfence-helper
npx --yes execfence helper audit
npx --yes execfence run --sandbox-mode audit -- npm test
npx --yes execfence run --sandbox -- npm test

Design Principles

References