SentnelOpsSentnelOpsbeta
LAYER 4 · RUNTIME ENFORCEMENT

Enforcement guides

Four tasks: flip an environment to enforce without breaking real traffic, put a human in front of dangerous tools, decide approvals from the dashboard, and wire alerts to Slack or email.

Flip an environment from observe to enforce, safely

Never enforce a rule that hasn't run in observe first. Observe mode uses the identical decision function, so its would-block rows are a zero-risk preview of exactly what enforce will block. The runbook:

StepYou are done when
1. Run in observe. Watch the live feed's red would-block rows.Would-block counts are stable and every row is a call you genuinely want blocked.
2. Fix the policy, not the traffic. A legitimate call showing as would-block means the rule is wrong — edit the YAML on the Policy page (validated on save, live within seconds).Zero surprising would-block rows for several days of normal traffic.
3. Flip staging: staging: enforce. One line, revertable in seconds.A week of staging traffic with no false blocks.
4. Flip production: production: enforce — and set fail_mode: {production: closed} in the same change if security outranks availability there.Production enforces with no first-day surprises — observe already found them all.
policies/example.yaml — the one-line flips
enforcement:
  staging: enforce            # step 3 — block here first
  # production: enforce       # step 4 — after a clean week in staging
  dev: observe                # advisory in dev for developer speed

Put a human in the loop for dangerous tools

Two ways to hold a call for approval — use both:

explicit rule + blast-radius safety net
enforcement:
  production: enforce
  rules:
    drop_database: require_approval   # always held, in every environment
  approval:
    defaults: {window_seconds: 60, blast_radius_threshold: 0.7}
    # any enforced call whose declared blast_radius >= 0.7 is also held

The explicit rule is for tools you can name in advance; the threshold catches high-blast-radius tools you scored in policy but forgot to list. What the agent experiences: its request simply takes longer — held up to the window (default 60 s) — then either completes normally (approved) or returns 403 blocked_by_sentnelops with the decision in the reason (denied or timed out). Agents need no SDK, only a timeout longer than the approval window.

Timeout is deny. An unstaffed approval queue blocks legitimate high-risk calls — that is by design, but it is your queue to staff. Don't put approval rules on calls nobody will be around to approve.

Decide approvals from the dashboard

The approvals queue with pending approval cards, live countdowns, Approve and Deny buttons, and recent decisions below
Each pending card shows the agent, tool, params, blast radius, and a live countdown — Approve or Deny with an optional note.

Deciding requires the security role or higher (see layer 5); viewers and developers can watch the queue but not decide. Dashboard users always decide as themselves — the approver recorded is your account, and it cannot be spoofed. Automation using an org API key must name its approver explicitly. From the command line:

decide via API (minimum role: security)
curl -s https://<your-api-host>/approvals/<approval-id>/approve \
  -H "Authorization: Bearer <session-or-api-key>" \
  -H "content-type: application/json" \
  -d '{"note": "release window — verified with the on-call"}'

# deny is the same shape at /approvals/<approval-id>/deny
# a second decision on the same approval returns 409 already decided

Wire alerts to Slack and email

Out of the box, alert events are logged locally and nothing leaves your infrastructure — zero egress until you configure a channel. Set either or both:

environment variables (either channel, or both)
# Slack — one incoming-webhook URL
SNOPS_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/<your-webhook-path>

# Email — SMTP with STARTTLS
SNOPS_SMTP_HOST=<smtp-host>          SNOPS_SMTP_PORT=587
SNOPS_SMTP_USER=<user>               SNOPS_SMTP_PASSWORD=<password>
SNOPS_ALERT_EMAIL_TO=<security-team@your-domain>
SNOPS_ALERT_EMAIL_FROM=<sentnelops-alerts@your-domain>

Approval alerts can route to a per-environment Slack channel — set channel in the environment's approval override (for example production: {window_seconds: 30, channel: "#prod-approvals"}) so production holds page the right room.