Skip to main content

How emisar works

How do you give an AI agent access to production without worrying that it might hallucinate its way into dropping a database or taking the site down?

July 2026 · 9 min read

emisar is built to scratch our own itch. We like shipping fast with an AI agent, and we know what that approach can do when it goes wrong.

Sandboxing the model did not solve this. Sandboxing constrains where a model runs; it does not constrain a remote SSH session. Once you hand an agent a shell on a production host, it has whatever that shell has.

The approach we trust is to whitelist what the agent can do. The toolset is defined before the agent asks for anything. Models are most useful in yolo mode, and we wanted to keep the experience of stepping away and coming back to a finished job without handing over a shell.

The design separates a control plane that governs policy and serves as the cloud portal, a runner that executes with minimal trust in the portal, and an MCP interface agents can use from wherever they run. The control-plane and runner split was inspired by Firezone.

What the agent can do

An agent acting through emisar can invoke actions. An action is declared in a pack. Here is a trimmed excerpt of a real one:

linux-core/actions/systemctl_restart.yaml (trimmed)
id: linux.systemctl_restart
kind: exec
risk: high

args:
  - name: unit
    type: string
    required: true
    validation:
      pattern: "^[A-Za-z0-9@._:][A-Za-z0-9@._:-]{0,127}$"
      max_length: 128

execution:
  command:
    binary: systemctl
    argv: ["restart", "{{ args.unit }}"]
  timeout: 60s

output:
  max_stdout_bytes: 4096
  max_stderr_bytes: 8192

Actions are grouped into packs. A pack contains its manifest, action definitions, and any scripts those actions use. The version gives people a release name; the content hash identifies the exact bytes installed on the runner and approved by an operator. If an action, validation rule, or script changes, the hash changes and the new pack must be trusted separately.

Anything not described by an installed and trusted action is not expressible through emisar. If an operator deliberately installs an action capable of dropping a database, however, the agent can request that action. emisar does not make a permitted destructive operation harmless.

Following one request

This is an intentionally simplified example. A real incident usually takes tens of tool calls to inspect the service, read logs, check related systems, try a fix, and verify the result. Here we reduce the investigation to three calls so the request path is easy to follow. Identifiers are shortened throughout; real requests use the exact pack and runner references returned by discovery.

The first call reads recent warnings from checkout.service:

1. read logs — run_action input
{
  "action_id": "linux.journalctl",
  "pack_ref": "linux-core@0.3.19/sha256:8d0ba17c…701c70ba",
  "runner_refs": [
    "api-iad-02~18a65e2f…6d2fc9"
  ],
  "args": {
    "unit": "checkout.service",
    "since": "30m",
    "priority": "warning"
  },
  "reason": "Read recent checkout warnings before changing the service.",
  "expected": "Find why checkout stopped making progress."
}

The log text below is hypothetical; the response shape is the real one. In this example the read succeeds and returns two warnings:

1. read logs — selected result
{
  "operation_id": "op_01K09E3N8Y4J6T2D5Q7R1V9WBE",
  "runs": [{
    "run_id": "019f61cf-59b4-71d9-a78c-4ece74d1e162",
    "runner_ref": "api-iad-02~18a65e2f…6d2fc9",
    "status": "success",
    "exit_code": 0,
    "stdout": "Jul 22 14:31:08 worker pool stalled for 120s\nJul 22 14:31:09 readiness check failed"
  }]
}

The next call requests the restart. Its evidence points to the log run and records what the agent found:

2. restart service — run_action input
{
  "action_id": "linux.systemctl_restart",
  "pack_ref": "linux-core@0.3.19/sha256:8d0ba17c…701c70ba",
  "runner_refs": [
    "api-iad-02~18a65e2f…6d2fc9"
  ],
  "args": {"unit": "checkout.service"},
  "reason": "Restart checkout to reset its stuck worker pool.",
  "evidence": "Run 019f61cf-…-e162 returned repeated worker pool stalled warnings.",
  "expected": "Unit returns to active; checkout health check passes."
}

The pack_ref identifies the pack by a content hash over the pack tree. The runner_refs identify the targets. The reason, evidence, and expected result travel with the request into the audit record.

The control plane checks identity, scope, pack trust, and policy. It records the decision in the cloud audit, dispatches allowed requests, and holds requests that need approval. An approved request is checked again before dispatch.

The runner opens an outbound TLS WebSocket to the control plane and listens on no inbound port. An eligible dispatch arrives over that connection.

The runner does not rely on the control plane's validation. It looks up the action locally, hashes its copy of the pack, and compares the result with the requested pack_ref. It applies local admission rules, rejects arguments it does not recognize, validates the supplied values, and clamps requested limits to the action's declared envelope.

It then renders the argument vector from the template stored in the pack. For this action, it executes systemctl restart checkout.service directly. There is no shell between the runner and the binary.

The child process receives a minimal environment and runs with the OS permissions of the runner service user. Standard output and standard error are bounded and pattern-redacted before anything leaves the runner. If the timeout expires or the operation is cancelled, the runner terminates the process group.

A selected view of the completed result looks like this:

2. restart service — selected result
{
  "operation_id": "op_01K09E3N8Y4J6T2D5Q7R1V9WCF",
  "runs": [{
    "run_id": "019f61cf-59b4-71d9-a78c-4ece74d1e163",
    "runner_ref": "api-iad-02~18a65e2f…6d2fc9",
    "status": "success",
    "exit_code": 0,
    "duration_ms": 380
  }]
}

Empty output streams are omitted rather than returned as empty strings.

Exit code 0 says that systemctl restart completed. The final call checks the service state instead of assuming the restart fixed the incident:

3. verify service — run_action input
{
  "action_id": "linux.systemctl_status",
  "pack_ref": "linux-core@0.3.19/sha256:8d0ba17c…701c70ba",
  "runner_refs": [
    "api-iad-02~18a65e2f…6d2fc9"
  ],
  "args": {"unit": "checkout.service"},
  "reason": "Verify checkout recovered after the restart.",
  "evidence": "Restart run 019f61cf-…-e163 completed with exit code 0.",
  "expected": "systemctl reports checkout.service active."
}

For this example, the status action returns:

3. verify service — selected result
{
  "operation_id": "op_01K09E3N8Y4J6T2D5Q7R1V9WCH",
  "runs": [{
    "run_id": "019f61cf-59b4-71d9-a78c-4ece74d1e164",
    "runner_ref": "api-iad-02~18a65e2f…6d2fc9",
    "status": "success",
    "exit_code": 0,
    "stdout": "● checkout.service — Checkout API\n   Active: active (running)"
  }]
}

A nonterminal response includes a continuation object describing the next call. The operation_id allows a client to recover an operation after losing a response. Separately, the runner keeps a replay record so the same accepted dispatch cannot start another process during its retention window.

Audit, redaction, and privileges

The control plane keeps the fleet-wide audit. A runner that receives a dispatch also writes to a local hash-chained JSONL journal before starting the process and again when it reaches a terminal outcome. The chain makes edits, deletions, and reordering detectable. An attacker with enough privilege on the host can replace the whole file.

Redaction removes values that match configured patterns. A secret in an unexpected format can still appear in output.

The runner's OS privileges limit what a permitted action can affect. A permitted destructive action remains destructive when it runs. emisar is not a VM, container, or kernel sandbox.

A compromised host already controls that host. emisar also does not run the agent loop: the agent decides what to request, while emisar decides whether that request is available and allowed.

Local admission can make a runner stricter than the control plane through action allow and deny patterns and a maximum accepted risk.

The MCP surface

emisar exposes twelve fixed MCP tools.

Discovery uses list_packs, find_actions, and get_action. Execution uses run_action. Other tools handle waiting, operation recovery, recent runs, and runbooks.

Packs add actions to the catalog. They do not add more MCP tool definitions.

Signed dispatch

In normal mode, the runner trusts the hosted control plane to authenticate callers, evaluate policy, and send eligible work.

Signed dispatch is optional. The operator's MCP bridge signs the exact action, pack, arguments, targets, reason, operation, nonce, and time with a key the cloud does not hold. An enforcing runner verifies that signature before execution.

The cloud can still delay or drop a dispatch. It cannot forge a new request, change its arguments, widen its targets, or successfully replay it. The terminal result is not a CA-signed receipt.

Private packs

Packs can also wrap internal workflows.

Our private emisar-admin pack is not published in the public catalog. It runs only on dedicated administration runners beside the portal and calls named operations through a fixed release-RPC script.

For example, emisar.admin.access.diagnose is a low-risk, read-only action. Given an account and member, it returns the account and membership details, confirmation and MFA state, active session count, and active API-key count.

Give your AI agent production access — without the risks.

Start free on the Free plan, or book a walkthrough on your own infrastructure.

Three runners. Seven-day audit. No credit card.