Skip to main content
Docs navigation

Security model

The precise mechanics behind every control — what each layer checks, and what it deliberately does not. Start with the security overview for the picture; this is the reference your security team reads next.

In short, emisar is a curated allowlist with an audit envelope, not a sandbox. Restarting Cassandra still restarts Cassandra. The value is the narrow attack surface and the audit trail, not process isolation.

The trust boundary#

  1. Pre-approved actions only. The runner loads action YAMLs at boot and refuses anything not in the catalog. A model cannot choose a binary or command program. Some reviewed actions use a fixed shell program; open-ended values reach it as environment or positional-argv data, and only finite choices and two-sided bounded numbers can render into its text. Arbitrary shell is isolated in the staging-only, critical-risk, default-denied shell pack.
  2. Configured catalog publisher trust. A valid catalog can authorize a matching pack already installed on a runner. The publisher also chooses the risk, kind, and retirement floor that the control plane reads. The catalog cannot install bytes or bypass descriptor checks, argument validation, or local admission. The catalog file itself is not signed — HTTPS and control of publication access are its protection today.
  3. Outbound-only network. Runners dial the control plane over TLS. No inbound ports, no SSH bastion to compromise.
  4. Bootstrap key + per-runner token. The enrollment key (emkey-enroll-…) is a bootstrap secret. It is single-use by default. A reusable key can have a use cap for fleet templates. The runner exchanges it for a per-runner token (rnrtok-…) on first connect; expiry and the refresh schedule are in Runner credentials. A single-use key is consumed atomically, so two concurrent registrations can never both succeed.
  5. Argument validation on the runner. The runner is the authority on arguments: it validates each one against the action schema — rejecting undeclared arguments, coercing types, and enforcing every minimum and maximum — before execution. The control plane gates the dispatch through policy, scope, and pack trust. A misbehaving cloud cannot smuggle an undeclared argument past the runner.
  6. Policy. Every dispatch gets one decision — allow / require_approval / deny — evaluated in the control plane from per-action overrides and risk-tier defaults (low / medium / high / critical). A dispatch the policy cannot answer is denied, and a higher tier can never be more permissive than a lower one. The runner sees only the decision — it does not reason about policy. Evaluation order, the shipped defaults, and overrides are in Policies & approvals.
  7. Approvals. When policy demands approval, the run is held until someone who can approve decides, and an undecided request expires. Approver counts, self-approval, four-eyes, and standing grants are in Policies & approvals.
  8. Output redaction. The runner masks 20 built-in patterns before output leaves the host. These include bearer and basic auth, JWTs, Google API keys, GitHub tokens, private-key blocks, and common password= / secret= / token= assignments. AWS access-key IDs remain usable in follow-up actions; secret access-key fields are masked. Per-action rules layer on top, but an unknown shape can pass through — treat redaction as a backstop, not a guarantee.
  9. Limits. Every action has a timeout and stdout/stderr byte ceiling. Cloud opts can lower these but not raise them above the action's declared maximum.
  10. Searchable cloud audit + hash-chained runner journal. Cloud audit records terminal action outcomes, denials, approval gates and decisions, and selected product changes. Product changes include runner state, policy, credential, team, and sign-in events. Pending, sent, and running action states remain in run history. A read-only audit-export token reads events through GET /api/audit and cannot execute an action; the export pipeline is in Audit & SIEM. Runner-side, every action attempt writes a JSONL line to /var/log/emisar/events.jsonl with a previous-line hash. That is the host-side forensics copy. emisar audit verify verifies continuity within the retained journal or retained suffix. It cannot prove that a privileged host operator did not replace or truncate the entire local journal. The off-host cloud audit cannot be changed from the host. Cross-reference the two.
  11. Setuid drop on Linux. Actions with user: set drop the child process to that local user's uid and primary gid before exec. A runner shipping under a privileged service account still runs the declared action as the lower-privilege user.
  12. Local action admission (defense-in-depth). The runner config supports admission.allow and admission.deny glob lists over action IDs. For example, use cassandra.* or *.repair. It also supports a risk ceiling. On a read-only host, admission.max_risk: medium drops every high-risk and critical action, regardless of cloud policy. Blocked actions are hidden from the catalog this runner advertises and refused at execution time, so even a compromised portal cannot push something the host operator did not sanction. Refusals land in the JSONL audit log as action_blocked_by_admission events for SIEM alerting.
  13. Bridge-attested dispatch (the strongest cloud-compromise defense). With signing.enforce_signatures on, the runner requires a valid v5 signature from an Ed25519 or ECDSA P-256 leaf key. The signature binds the origin, action, immutable pack, exact arguments, exact runner set, reason, operation, nonce, and time. It also binds digests of the evidence and expected result shown to an approver. A certificate from the trusted offline CA must vouch for the leaf key.
  14. The control plane cannot forge signed work. The leaf private key stays in the customer-authorized MCP bridge, and the CA private key stays offline. The control plane can relay a signed action, but it cannot create or change one, since it does not hold a private key. It can still withhold a signed action — signed dispatch protects integrity, not availability.
  15. The runner rejects stale or replayed work. The certificate and dispatch must be current. The runner stores used nonces on disk. A restart does not clear replay protection. A request outside max_attestation_age or the certificate window is stale.
  16. The target set and certificate scope are separate limits. Each call signs its exact identity-bound runner references. The certificate adds a coarser group or label ceiling. Display names remain portal-owned metadata. Verify runner suffixes out of band for the highest-trust workflows. See signed dispatch for setup, fleet key distribution, rotation, and revocation.

What emisar is not#

  • Not a VM, container, or kernel sandbox. Process isolation is the host's job. Use systemd hardening, namespaces, SELinux, or gVisor.
  • Not an EDR. emisar does not detect malicious binaries, lateral movement, or host compromise. The retained-journal continuity check described above does not change that boundary. The runner rejects a pack whose contents no longer match the cloud-pinned trusted hash before execution.
  • Not a replacement for OS-level access control. The user: drop only works because the OS already permits it.
  • Redaction is pattern-based, not a guarantee. A secret in a shape none of the rules match reaches the control plane in the run output. Keep provider credentials in the runner environment rather than in arguments, and treat masking as the second line, not the first.
  • There is no per-certificate revocation for signed dispatch. A leaked leaf key stays usable until its certificate expires. Short lifetimes bound the routine case. The immediate lever is removing the trusted CA from every runner. This is a fleet operation, not a switch in the console.
  • Audit is evidence, not prevention. The trail proves what happened. Policy, scope, and trust are what stop it. The export is a pull API. A stalled collector leaves your SIEM blind while the control plane keeps recording.

When one of these limits becomes an event, follow security incidents. Examples include a leaked key, unexplained pack hash, or untrusted host.

Where your data lives#

The runner, its packs, and its local journal live on your hosts. The hosted control plane runs on Google Cloud in the United States. It includes the console, audit log, run history, and MCP API. Data is encrypted at rest with provider-managed keys and in transit with TLS. The runner opens an outbound TLS WebSocket, never an inbound listener, and commands return through that established connection. Architecture and failure behavior explains which component owns each decision and what happens when one drops out. The table below lists what is kept, where, and for how long.

What Where it lives How long
Audit events Control plane, United States Your plan's window, stamped on each event when it is written — 7 days on Free, 90 on Team, 365 on Enterprise. A plan change applies to new events only.
Run history and runner-returned output Control plane, United States The same account window as audit. Configured host redaction is best effort. Unknown shapes can still contain secrets.
Exact action arguments Control plane, United States The same account window as run history. The portal stores them for authorization, approval, dispatch, and hashing. Sensitive descriptors mask views, not storage.
Account, members, policies, trusted pack hashes, runbooks Control plane, United States Until you change or delete them.
Bearer credentials we issue Control plane, as a hash only Until revoked or deleted. A stolen database copy cannot be replayed.
OIDC provider client secrets Control plane, reversible application data Until you change or delete the connection. The portal must present the secret to the identity provider. Infrastructure encryption protects it at rest.
Packs and the local event journal Your host You control rotation and retention. The --purge option deletes them with the runner.
Signing keys Leaf in the customer-authorized MCP bridge, CA offline We never hold either. There is no per-certificate revocation list.
Pack and provider credentials Your host's protected runner environment Keep them out of call arguments. If an action prints an unknown secret, redaction can miss it and send it to the control plane.

Retention is a ceiling, not a promise to keep evidence for you. If you need it longer, ingest it before the window closes — Audit & SIEM owns that. For subprocessors, backups, and release verification, see the security overview and the trust page.

Last reviewed August 23, 2026