DEV Community

Cover image for Give Your Coding Agent a Governed CLI Workflow with apexe
tercel
tercel

Posted on Originally published at blog.aiperceivable.com

Give Your Coding Agent a Governed CLI Workflow with apexe

An agent task starts simply: list a directory, read a file, inspect a tool. As the task grows, those small calls become a workflow with real permissions and side effects.

That is a useful place to introduce apexe: a governed execution layer for CLI tools and HTTP APIs. It gives existing commands typed contracts and applies configured policy before execution, with records of executions and refusals.

Here is how to start with a local CLI workflow, then connect it to the agent or protocol client you use.

1. Prepare apexe and a trusted CLI

Use a prebuilt binary, or build from source with stable Rust and Cargo:

git clone https://github.com/aiperceivable/apexe.git
cd apexe
cargo install --path .
apexe --version
Enter fullscreen mode Exit fullscreen mode

The workflow below targets Unix CLI tools. macOS and Linux are the main starting points; native Windows CLI discovery is not supported. Git is needed to acquire the rules corpus, and the CLI binaries you want to use must already be installed.

Initialize coverage and inspect the result:

apexe init
apexe list --verbose
Enter fullscreen mode Exit fullscreen mode

init obtains the configured rules source, normally cli-permissions, checks matching installed commands and variants, and writes bindings plus a starter ACL.

Review ~/.apexe/acl.yaml. A new policy defaults to deny, with generated allow rules for local readonly operations. Existing manual rules and policy defaults are preserved. Treat generated classifications as material to review.

Read the init report, including skipped tools, warnings, and native_ready module IDs. This is where you learn which entry points your installation can actually use.

2. Preview one native invocation

Native execution accepts familiar argv:

apexe exec --dry-run -- ls -la
Enter fullscreen mode Exit fullscreen mode

For this example, you need a matching reviewed native binding. The current native pilot covers BSD cat, head, and ls. A Linux installation may successfully scan GNU tools while lacking native grammar for this call; scanning coverage and native eligibility are separate.

Inspect the preflight's validity, execution mode, module, ACL decision, approval requirement, and argument/path checks. Confirm that it describes the operation and policy you intended.

Only after reading an admitted preflight, submit a separate execution call:

apexe exec -- ls -la
Enter fullscreen mode Exit fullscreen mode

Native stdout and stderr pass through, and apexe preserves the child's exit status. You do not need to activate a shell environment or run an MCP server.

Keep preview and execution separate in an agent workflow: the point is to inspect the result before starting the child. Execution checks the request again; a preview does not reserve permission or grant human approval.

3. Use module JSON when the binding has no native grammar

Module JSON is another local interface. Start by inspecting the installed schema:

apexe list --verbose --format json
Enter fullscreen mode Exit fullscreen mode

The output's modules array contains each module's id and input_schema. Use the property names and shapes from your own binding.

For example, if your cli.ls schema advertises a file array, preview:

apexe exec cli.ls --input '{"file":["."]}' --dry-run
Enter fullscreen mode Exit fullscreen mode

After inspecting an admitted result, execute separately:

apexe exec cli.ls --input '{"file":["."]}'
Enter fullscreen mode Exit fullscreen mode

Module mode captures the result as JSON, including stdout, stderr, and exit_code; it supplies null child stdin. Native mode preserves streams, with stdin inheritance only where reviewed capabilities permit it.

Both routes apply their normal governance checks. A missing native grammar can justify selecting module JSON for the same operation. An ACL or path refusal calls for resolving the denied request with the operator.

4. Give your terminal agent the same workflow

apexe includes one shared routing Skill for Claude Code, Codex, pi, and OpenCode. From the source checkout:

python3 scripts/install_agent_skill.py --project-dir /path/to/your-project
Enter fullscreen mode Exit fullscreen mode

Replace that destination with the project where the agent works. Follow the Agent Skill guide to declare the execution route and selected policy in the host's project instructions.

The Skill guides the agent to resolve configuration before its first task command, route external CLI calls through explicit exec, preview new or changed calls, and stop on governance refusals. Explicit exec works without shims or MCP.

For a pipeline, the shell still owns the pipe. Each external stage needs its own governed invocation, and the Skill calls for preflighting stages sequentially before execution. Shell redirection happens outside apexe's typed-path checks.

Installing the Skill alone does not enroll every project or intercept an unrestricted terminal. Compulsory routing requires host enforcement.

5. Add an interface when you need it

For existing shell workflows, optional env integration installs eligible external-command shims:

apexe env --enable
source ~/.apexe/bin/apexe-activate.sh
apexe env --check
Enter fullscreen mode Exit fullscreen mode

Use this after bindings and policy are ready. Shims preserve familiar command names for covered tools. Builtins, aliases, absolute paths, and uncovered commands remain outside that route.

For an MCP client:

apexe serve --acl ~/.apexe/acl.yaml
Enter fullscreen mode Exit fullscreen mode

For A2A:

apexe a2a --acl ~/.apexe/acl.yaml
Enter fullscreen mode Exit fullscreen mode

Servers need the explicit ACL flag for access control. Local exec uses caller local and loads the default ACL when present; if none is loaded, access control is inactive. MCP interactive approval is opt-in with --enable-approval and a compatible client. Local execution has no interactive approval client, so calls that actually need that decision fail closed. A2A has no interactive approval transport; approval-store support requires library integration.

Have an HTTP API too? serve and a2a can import supported operations from OpenAPI 3.0/3.1 documents alongside CLI modules. See the OpenAPI guide for the supported JSON proxy surface and credential setup. HTTP import is a server feature.

Keep the contract current

After a CLI changes, check its source contract:

apexe verify --report ./drift-report.json
Enter fullscreen mode Exit fullscreen mode

Optional explicit behavioral cases add evidence for the invocations tested. Recorded evidence is bound to binding, executable, and case digests, so changes can invalidate it. It does not certify every possible use of a CLI.

Know the execution boundary

Governed CLI calls use structured inputs, configured ACLs, schema-typed path checks, environment scrubbing, timeouts, and auditing. apexe passes argv to the subprocess without evaluating a shell command string.

An allowed process still has the host process's privileges. apexe is not an OS sandbox. Pair it with the account and isolation boundary your workload needs, and read the threat model.

The project is Rust-based and Apache-2.0 licensed. Start with one trusted CLI and one operation you can inspect from preflight through audit.

Explore apexe on GitHub · Read the quick start

Which CLI would you like your agent to use through a reviewed execution contract?

Top comments (1)

Collapse
 
murali_gour_13cd7a6a6db2c profile image
Murali Gour •

The dry run not reserving permission is the honest part. I’d check that the exec call re-evaluates the policy at run time instead of trusting the preview, otherwise a rule change or a path swap between the two calls slips through. Failing closed when there’s no approval client is the right default too.