Getting started

Installation

What a Sentinel install runs, how to deploy it with Docker or from source, and how to configure and operate it.

You run Sentinel on your own servers (on-prem) or in your own cloud account, and the software is the same either way. Each running copy is called an install.

What's in an install

An install is one binary, one PostgreSQL database and, optionally, Redis.

ComponentWhat it does
sentinel-apiServes the API under /v1, /healthz, and the dashboard at /. Applies database migrations when it starts. Scores events with versioned CEL rules.
sentinel-adminCommand-line tool for operator tasks: creating keys, verifying the audit chain, seeding rules and loading screening lists
PostgreSQLThe system of record: events, decisions, alerts, rules, screenings, keys and the audit log. The local setup uses PostgreSQL 17.
Redis (optional)Serves the velocity counters rules read. Without it the counts come from PostgreSQL, which is slower. Redis holds nothing that can't be rebuilt.

The binary makes no outbound connections except to your database and Redis. Nothing goes to Somu Labs.

Multi-tenancy. Every row carries an org_id, and every API key belongs to exactly one organisation. One install can serve several brands or legal entities with complete separation, including separate audit chains. Screening lists are the exception: they're shared by the whole install.

Docker

The Dockerfile in the repository builds one image with the API, the dashboard and sentinel-admin. It runs as a non-root user, listens on port 8080, and has a health check on /healthz.

Terminal
docker build -t sentinel --build-arg VERSION=v0.1.0 .

docker run -d --name sentinel -p 8080:8080 \
  -e SENTINEL_DATABASE_URL="postgres://sentinel:change-me@db.internal:5432/sentinel" \
  -e SENTINEL_BOOTSTRAP_API_KEY="snt_live_..." \
  sentinel

Migrations run on startup, so a new image upgrades the schema when it starts. Run the admin tool inside the container:

Terminal
docker exec sentinel /app/sentinel-admin audit verify -org default

From source

You need Go (the version in go.mod) and Node 22 for the dashboard.

Terminal
make bundle          # builds the dashboard and compiles it into bin/sentinel-api
./bin/sentinel-api   # serves the dashboard at / and the API under /v1

make build builds the API without the dashboard. / then shows a page explaining the dashboard isn't included. make reads a .env file in the repository root if there is one. .env.example has local defaults.

For a local database, make up starts PostgreSQL on port 5433 and Redis on 6379 with Docker Compose. It also starts Redpanda, which nothing uses yet.

Configuration

All settings are environment variables. Only the database URL is required.

VariableDefaultMeaning
SENTINEL_DATABASE_URLnone, requiredPostgreSQL connection string
SENTINEL_HTTP_ADDR:8080Address the API listens on
SENTINEL_REDIS_ADDRunsetRedis for velocity counters. Unset means counts come from PostgreSQL.
SENTINEL_REDIS_DB0Redis database number, for installs that share a Redis
SENTINEL_AUTO_MIGRATEtrueApply pending migrations on startup. false skips them.
SENTINEL_BOOTSTRAP_API_KEYunsetBecomes the organisation's first API key, only while it has none. See the first key.
SENTINEL_BOOTSTRAP_ORGdefaultThe organisation the bootstrap key belongs to
SENTINEL_SCREENING_SAMPLEfalseLoad the synthetic screening list when no list is loaded. Keep it off in production.
SENTINEL_SLA_HIGH4hHow long a high priority alert has to be decided. Any Go duration, like 90m.
SENTINEL_SLA_MEDIUM24hThe same for medium priority alerts.
SENTINEL_NEAR_THRESHOLD_LOW4500Lower end of the "just under the reporting threshold" band the structuring counter uses. Set both ends or neither.
SENTINEL_NEAR_THRESHOLD_HIGH5000Upper end of the band, not included. Set it to your reporting threshold.
SENTINEL_RATE_LIMIT1000Requests a second each API key may make, on average. 0 turns the limit off. Each replica counts its own traffic.
SENTINEL_RATE_BURSTtwice the limitHow many requests a key may make at once before the average applies.

The server fails to start, with a message naming the variable, if a required value is missing or a value can't be parsed.

First run

Start it

Point SENTINEL_DATABASE_URL at an empty database and start the binary or container. It applies every migration and logs which ones it ran.

Get a key

Set SENTINEL_BOOTSTRAP_API_KEY before the first start, or run sentinel-admin key create -name admin once. See Authentication.

Make your own keys

Sign in to the dashboard with that key, open Developers → API keys, and create a key for each person and service. Four-eyes approvals need at least two. Then revoke the bootstrap key and remove the variable.

Seed the rules

Run sentinel-admin rules seed -org default if you want the built-in rules installed as editable rules. See Rules.

Load a screening list

Run sentinel-admin screening load -file <list.json> with a list you've licensed. See Screening.

Admin commands

sentinel-admin reads SENTINEL_DATABASE_URL. Run it with go run ./cmd/sentinel-admin ... from source, or /app/sentinel-admin ... in the container. -org defaults to default.

CommandWhat it does
key create -org <org> -name <name>Makes an API key and prints it once
audit verify -org <org>Checks the organisation's audit chain and reports the first broken entry
rules seed -org <org>Installs the built-in rules as active, editable rules. Refuses if the organisation already has rule versions.
screening load -file <list.json>Loads a sanctions or PEP list, or replaces the loaded list with the same code

Network

ConnectionDirectionPurpose
Your services → APIInboundEvents, entities, decisions and the rest of /v1. Internal network only; no public exposure needed.
Browsers → dashboardInboundYour compliance team. Same port as the API.
API → PostgreSQLOutbound, internalRequired
API → RedisOutbound, internalOptional

The binary speaks plain HTTP. Put TLS in front of it with your load balancer or reverse proxy.

Operations

  • Health. GET /healthz returns status and version, for your load balancer and monitoring. See Health.
  • Logs. Structured JSON on standard output.
  • Several instances. You can run more than one behind a load balancer. Instances starting together take turns applying migrations. A rule activation takes effect at once on the instance that handled it and within 30 seconds on the others. New screening lists show up within 30 seconds too.
  • Backups. Standard PostgreSQL backups cover everything that matters. Redis holds nothing that can't be rebuilt.

Not built yet

The product design includes more than the binary does today. None of these exist yet:

  • Async processing on an event stream, and the workers that would deliver webhooks and file reports.
  • Connectors that pull events from rails.
  • A licence agent, usage metering, and signed updates for releases, lists and rule packs.
  • Air-gapped update bundles.
  • Sign-in through your SSO. The dashboard signs in with an API key.
  • A Helm chart or a documented high-availability layout.
Sentinel is a Somu Labs product. © 2026 Somu Labs Ltd.