Security & compliance

Built so your security team says yes.

emisar exists because giving an LLM raw shell access is reckless. Every layer here is designed so the LLM is the least-privileged participant in the system — and every action is auditable.

No inbound port on hosts Secrets redacted before egress Hash-chained audit journal MFA + per-user runner scopes No raw shell, ever

Trust boundary

Who can do what, by design.

The LLM is never trusted with privileged execution. It can only request actions from a catalog your team has reviewed.

LLM (untrusted)
 │  asks for a catalog action over MCP — with a required reason
 ▼
Control plane
 │  evaluates policy · checks scope & pack trust · routes · records audit
 │  on require_approval, waits for a human ──▶ Operator approves / denies
 ▼  run_action (only after the gate passes)
Runner on host — outbound WSS only; the host dials out, nothing listens
 │  validates args against the action schema · re-verifies the pack hash
 │  drops to least privilege · argv arrays, never a shell · redacts before egress
 ▼
Hash-chained JSONL journal on the host + searchable cloud audit

LLM

Untrusted. Can only call catalog actions with declared args.

Control plane

Evaluates policy, checks scope and pack trust, routes, and audits. Never executes shell itself.

Runner

Non-root service user, and the authority on arguments: validates every arg against the action's declared schema (rejecting anything undeclared), drops to a per-action user/group, clamps options to the action's min/max bounds, and runs argv arrays — never shell strings.

Data handling

Boring, defensible defaults.

TLS-only transport

Runners connect to the control plane over WSS using TLS 1.2+. A bootstrap key is exchanged for a per-runner token that can be revoked from the dashboard.

No inbound connections to runners

Runners are outbound-only. No ports to expose, no firewall holes, no NAT traversal. Your hosts initiate every connection.

Hash-chained audit journal

Every action is recorded to an append-only JSONL audit on the host, with each line carrying the SHA-256 of the previous entry. Any edited line or break in the chain is caught by emisar audit verify; the cloud audit is the durable system of record.

Hash-pinned packs

Action packs are content-addressed. New, custom, or changed hashes block dispatch until an admin trusts the contents. Before execution, the runner recomputes the cloud-pinned hash and rejects a mismatch. This is content integrity, not publisher signing — the runner trusts the exact bytes an admin approved.

Secrets redacted before egress

20+ built-in patterns (AWS keys, GitHub/GitLab/Slack/Stripe/OpenAI/Anthropic tokens, JWTs, bearer/basic auth, private-key blocks, secret assignments) plus your own per-action rules scrub stdout and stderr on the runner before anything is forwarded. The control plane receives only the redacted stream; per-rule hit counts are recorded so you can see what was masked.

SIEM export, least-privilege token

The cloud audit is the searchable system of record. Stream it to your SIEM as NDJSON with keyset cursor pagination and RFC 5988 Link headers, using a dedicated audit:read key — your SIEM never holds a token that can execute an action.

Organizational controls

The knobs your IAM team expects.

RBAC

Roles for owner, admin, operator, and viewer, plus per-user runner and runner-group scopes.

Scoped LLM access

Each MCP key carries its own scopes (actions:read, actions:execute, audit:read), user attribution, and runner filters. Keys are revocable and inherit their creator's runner scope at call time — revoke the user and every key they minted shrinks with them.

MFA

TOTP (RFC 6238) on every plan, with one-time recovery codes and replay protection. Enforce it org-wide with one switch.

Independent standard

Built for “assume breach.”

Anthropic — the lab behind Claude — published Zero Trust for AI Agents, a framework for giving autonomous agents access to real systems: least agency, deny-by-default tools, human approval for high-risk actions, and an immutable audit trail. emisar enforces that control set — and assumes the agent may already be compromised, so a jailbroken or prompt-injected model still can't exceed the declared, gated, audited catalog.

Local admission control

Beyond the cloud policy, an operator can set an allow/deny list on the runner itself. Denied actions are hidden from the catalog and refused at execution — fail-closed, even against a compromised control plane. The host always has the last word.

See emisar mapped to the framework, control by control Not affiliated with or endorsed by Anthropic.

Responsible disclosure

Found a security issue? We want to hear about it. Email security@emisar.dev with a description and reproduction steps. We acknowledge within one business day and credit reporters in our security advisories.

Full policy in SECURITY.md.