Connection lost
Trying to reconnect…
Server didn't respond
Recovering…
Docs / Security
Security model
The precise mechanics behind every control — exactly what each layer checks, and what it deliberately doesn't. For the pitch and the trust-boundary picture, start with the security overview; this page is the reference your security team reads next.
The short version: 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
-
Pre-approved actions only.
The runner loads action YAMLs
at boot and refuses anything not in the catalog. A model that asks for
rm -rf /can't issue it — the request never reaches a shell. - Outbound-only network. Runners dial the control plane over TLS. No inbound ports, no SSH bastion to compromise.
-
Bootstrap key + per-runner token. The enrollment key
(
emkey-auth-…) is a one-time secret. The runner exchanges it for a long-lived per-runner token (rnrtok-…) on first connect. Single-use keys are atomically consumed: two concurrent registrations can never both succeed. - Argument validation on the runner. The runner is the authority on arguments: it validates every arg against the action's declared schema — rejecting anything undeclared, coercing types, and enforcing each arg's min/max — before it executes. The control plane gates the dispatch (policy, scope, pack trust); a misbehaving cloud cannot smuggle an undeclared argument past the runner.
-
Policy.
Two-layer per-account model: a default
decision per risk tier (
low/medium/high/critical), plus ordered per-action overrides that glob-match on action ID. First matching override wins; otherwise the tier default applies. Decisions:allow/require_approval/deny. Higher-risk tiers are forced to be at least as restrictive as lower-risk ones — you can't allowcassandra.nodetool_drainwhile requiring approval forcassandra.nodetool_status. Shipped defaults: low and mediumallow, highrequire_approval, criticaldeny. The runner sees the decision only; it doesn't reason about policy. - Approvals. When policy demands approval, the run is held until an authorised teammate decides. Approvers are emailed; clicking the link lands them on the request page.
-
Output redaction.
20+ built-in patterns — bearer/basic auth, JWTs, AWS keys, Google API keys,
GitHub tokens, private-key blocks, and common
password=/secret=/token=assignments — are masked before the chunk leaves the runner. Per-action rules layer on top, and per-rule hit counts are recorded so you can see what was masked. The control plane never receives the raw bytes. - 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.
-
Searchable cloud audit + hash-chained runner journal.
Cloud-side, every mutation — dispatch, approval, runner state change,
policy edit, sign-in — appends an account-scoped audit event. Those events
ship as NDJSON over
GET /api/audit— forward-only with keyset cursor pagination and RFC 5988Linkheaders — gated on anaudit:read-scoped API key minted from the audit page. Point any SIEM that speaks HTTP at it; that token reads events but never executes an action. Runner-side, every action attempt writes a JSONL line to/var/log/emisar/events.jsonlwith a previous-line hash — that's the host-side forensics copy.emisar audit verifydetects tampering in the local journal. -
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. -
Local action admission (defense-in-depth).
The
runner config supports an
admission.allow/admission.denylist of glob patterns over action ids (e.g.cassandra.*,*.repair). Blocked actions are hidden from the catalog this runner advertises to cloud 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 asaction_blocked_by_admissionevents for SIEM alerting.
What emisar is not
- Not a VM, container, or kernel sandbox. Process isolation is the host's job (use systemd hardening, namespaces, SELinux, gVisor — we recommend all of those).
- Not an EDR. emisar doesn't detect malicious binaries, lateral movement, or host compromise. It detects tampering in the local runner journal and rejects a pack whose on-disk 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.