SentnelOpsSentnelOpsbeta

Core concepts

The five ideas behind SentnelOps, in the order you'll meet them. Everything else in these docs is detail on one of these.

Orgs and credentials

Your org is a hard tenancy boundary — every agent, policy, call log, and user belongs to exactly one org, and nothing crosses it (another tenant's resources 404 as if they don't exist). Two kinds of credentials act inside an org:

CredentialWho uses itActs as
snops_key_…Machines: CI, scripts, the SDKadmin (full access)
Session JWT (12 h)Humans, via logintheir assigned role
Agent JWTAgents, only at the proxythe agent's identity — never a user

The three are deliberately not interchangeable: an agent token is rejected everywhere except the proxy, and a user session is rejected at the proxy.

Agents are first-class identities

An agent record answers the questions security teams ask after an incident: who is this, who owns it, what may it touch, when does it expire, who approved it? Fields: name, owner, environment (dev | staging | production), risk level, allowed/denied MCP servers, lifecycle status, expiry, and review dates. Its JWT is self-contained — the proxy knows the caller without a callback.

Lifecycle, not a boolean

draft → approved → active ⇄ suspended → decommissioned (terminal)

Production agents cannot activate without approval, and the approver must be a different person than the creator (403 segregation_of_duties). Suspension freezes the agent's scope and requires a reason. Every transition is written to an append-only audit log.

Policy: two levels, one evaluator

Level one lives on the agent: allowed_mcp / denied_mcp — which servers it may reach at all. Level two lives in policy YAML — your org's own document, edited on the dashboard's Policy page and overlaying the platform default: per-server allow/deny tool lists with declared blast radius scores (0.0 read-only → 1.0 destructive). One pure function evaluates both levels everywhere it matters:

SurfaceWhat the same decision does
POST /policy/checkAdvisory — returns the decision, blocks nothing
Proxy in observe modeRecords it as would_block — still blocks nothing
Proxy in enforce modeActs on it — denied calls never reach the upstream

Because it's literally the same code path, the would_block counts you accumulate in observe mode are an exact preview of enforcement — not an estimate.

The observe → enforce journey

This is the intended adoption path, one deliberate step at a time:

StageWhat happensRisk
1. Observe (default)Everything forwards; every call logged with would_blockZero — the proxy fails open
2. ReviewDashboards show which calls your policy would stopZero — you're reading a report
3. Enforce stagingOne YAML line: staging: enforceContained
4. Enforce productionSame line for production; high-blast calls can require human approvalKnown in advance from stage 2

Everything is evidence

The call log, audit trail, and registry all export as CSV (/mcp-calls/export.csv, /agents/export.csv, /reports/governance) — designed to be handed to auditors or streamed to a SIEM. The audit log is append-only at the database layer: there is no API, role, or SQL grant that rewrites history.