tutorial

Monitoring Cerbos Authorization Service with Vigilmon: Health API, gRPC Port, Policy Engine & SSL Certificate Alerts

How to monitor Cerbos authorization service deployments with Vigilmon — health endpoint checks, gRPC port monitoring, policy decision API availability, and SSL certificate alerts.

How to Monitor Cerbos Authorization Service Deployments with Vigilmon

Cerbos is an open-source, cloud-native authorization service that externalizes access control from your application code — evaluating policy decisions in milliseconds using a combination of RBAC, ABAC, and custom policy logic. Applications call Cerbos's gRPC or HTTP API at authorization time, and Cerbos returns allow/deny decisions based on your policy bundle. When Cerbos is down, every permission check in your application fails.

That makes Cerbos availability directly tied to your application's ability to function at all. External monitoring with Vigilmon ensures you know immediately when Cerbos is unreachable — before your application's 403 errors start cascading to users.


Why Cerbos needs external monitoring

Cerbos's internal health endpoints report process-level health, but miss the authorization path failure modes that affect applications:

  • Policy store becomes unreachable during a deploy — Cerbos process is alive but policy hot-reload fails; the engine serves stale or no policies while health checks pass
  • gRPC port is bound but HTTP REST API fails to start — applications using REST get connection refused while gRPC clients appear healthy
  • TLS certificate expires on the Cerbos endpoint — all policy decision requests fail immediately while the process health check (which often uses plain HTTP internally) stays green
  • Policy bundle compilation fails silently — a bad policy commit causes the policy engine to reject all decisions with errors while the liveness endpoint returns 200
  • Cerbos PDP (Policy Decision Point) crashes under load — high-throughput decision requests exhaust goroutines; the health endpoint responds but decision requests queue and time out
  • Sidecar injection fails in Kubernetes — the application container starts without Cerbos sidecar; all authorization checks fail because the sidecar address is unreachable

External monitoring from a neutral vantage point catches authorization service failures that internal probes miss.


What you'll need

  • A running Cerbos instance (standalone server, Docker, Kubernetes sidecar, or hub deployment)
  • HTTP or gRPC endpoint accessible from outside the server
  • A free Vigilmon account (sign up takes 30 seconds)

Step 1: Understand Cerbos's health endpoints

Cerbos exposes health endpoints on its HTTP port (default 3592) and gRPC port (default 3593):

# Liveness check — is Cerbos running?
curl -s -o /dev/null -w "%{http_code}" http://localhost:3592/_cerbos/health

# Readiness check — is Cerbos ready to evaluate policies?
curl -s http://localhost:3592/_cerbos/health | python3 -m json.tool

# Policy decision test — does the policy engine actually respond?
curl -s -X POST http://localhost:3592/api/check/resources \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "monitor-test",
    "principal": {"id": "monitor", "roles": ["admin"]},
    "resources": [{"kind": "document", "id": "test", "actions": ["read"]}]
  }' | python3 -m json.tool

The health response includes:

{
  "status": "SERVING",
  "version": "0.36.0",
  "policies": {
    "count": 42,
    "lastReloadTime": "2026-03-10T14:00:00Z"
  }
}

Watch for "status": "NOT_SERVING" — this means Cerbos is alive but the policy engine isn't ready.

Starting Cerbos with Docker

docker run -d \
  --name cerbos \
  -p 3592:3592 \
  -p 3593:3593 \
  -v /path/to/policies:/policies \
  ghcr.io/cerbos/cerbos:latest \
  server \
    --config=/config/cerbos.yaml

Ports:

  • 3592 — HTTP REST API and health endpoints
  • 3593 — gRPC API

Step 2: Create an HTTP monitor for the Cerbos health endpoint

Log in to Vigilmon and create your primary monitor:

  1. Click Monitors → New Monitor
  2. Set the Type to HTTP
  3. Enter your endpoint: https://cerbos.yourdomain.com/_cerbos/health
  4. Set Check interval to 1 minute
  5. Set Expected status to 200
  6. Set Keyword to find: SERVING
  7. Set Alert after to 1 failure — authorization service outages affect every protected API call
  8. Click Save

The keyword check ensures you catch the NOT_SERVING state where Cerbos responds with HTTP 200 but the policy engine isn't operational.

What this monitor catches

| Failure | Vigilmon response | |---------|-----------------| | Cerbos process crashed | Connection refused → alert | | Policy engine not ready | NOT_SERVING keyword → alert | | Policy store unreachable | HTTP 503 or NOT_SERVING → alert | | Reverse proxy misconfigured | HTTP 502/504 → alert | | OOM kill | Connection refused → alert | | DNS resolution failed | DNS error → alert | | TLS certificate expired | SSL error → alert |


Step 3: Add a TCP monitor for the gRPC port

Most production Cerbos integrations use gRPC (port 3593) for lower latency. Monitor it separately:

  1. Click Monitors → New Monitor
  2. Set the Type to TCP
  3. Enter: cerbos.yourdomain.com:3593
  4. Set Check interval: 1 minute
  5. Click Save

This lets you distinguish "HTTP layer down" from "gRPC port not listening" — different root causes with different recovery procedures. Most application SDKs use gRPC by default, so a gRPC port failure silently breaks authorization for all SDK users.


Step 4: Monitor the policy decision API

Going beyond health checks, verify that the policy engine actually processes authorization requests:

  1. Click Monitors → New Monitor
  2. Set the Type to HTTP
  3. Enter: https://cerbos.yourdomain.com/api/check/resources
  4. Set Method: POST
  5. Set Request headers: Content-Type: application/json
  6. Set Request body:
    {
      "requestId": "vigilmon-health-check",
      "principal": {"id": "monitor-principal", "roles": ["admin"]},
      "resources": [{"kind": "health_check", "id": "vigilmon", "actions": ["read"]}]
    }
    
  7. Set Expected status: 200
  8. Set Check interval: 5 minutes
  9. Click Save

This end-to-end check verifies the policy evaluation path is operational, not just that the HTTP server accepts connections.


Step 5: Configure alert channels

Navigate to Alerts → New Alert Channel:

Slack integration:

# In Slack, create an incoming webhook for #security or #authorization-alerts
# In Vigilmon, paste the webhook URL under Alerts → Slack

PagerDuty / Opsgenie:

POST https://events.pagerduty.com/v2/enqueue
{
  "routing_key": "YOUR_INTEGRATION_KEY",
  "event_action": "trigger",
  "payload": {
    "summary": "Cerbos authorization service is DOWN — all permission checks failing",
    "severity": "critical",
    "source": "vigilmon"
  }
}

Email: Configure direct email alerts to your security and platform engineering teams.

Example Vigilmon webhook payload:

{
  "monitor_name": "Cerbos /_cerbos/health",
  "status": "down",
  "url": "https://cerbos.yourdomain.com/_cerbos/health",
  "started_at": "2026-03-10T14:52:00Z",
  "duration_seconds": 60
}

Step 6: Correlate Vigilmon alerts with Cerbos diagnostics

When an alert fires, run this triage sequence:

# 1. Is the Cerbos process running?
docker ps | grep cerbos
# or for systemd:
systemctl status cerbos

# 2. Check Cerbos logs for policy errors or panics
docker logs cerbos --tail 100 | grep -E "ERROR|FAIL|panic|policy" -i

# 3. Test health directly (bypass proxy)
curl -v http://localhost:3592/_cerbos/health

# 4. Test gRPC port (requires grpc_health_probe or grpcurl)
grpc_health_probe -addr=localhost:3593

# 5. Test a policy decision directly
curl -s -X POST http://localhost:3592/api/check/resources \
  -H "Content-Type: application/json" \
  -d '{"requestId":"test","principal":{"id":"test","roles":["admin"]},"resources":[{"kind":"test","id":"1","actions":["read"]}]}'

# 6. Check policy store connectivity
curl -v http://localhost:3592/_cerbos/admin/policies | head -c 500

# 7. Verify policy bundle status
curl -s http://localhost:3592/_cerbos/health | python3 -c "import sys,json; h=json.load(sys.stdin); print(h.get('policies', {}))"

Triage decision tree:

  • Process not running → check host OOM (dmesg | grep killed), restart Cerbos, verify policy directory is mounted correctly
  • /health returns NOT_SERVING → policy store is unreachable or policy compilation failed; check logs for specific policy errors
  • Health returns SERVING, but decision API returns errors → specific resource kind may have missing policies; check policy files for the affected resource kind
  • Process running locally but Vigilmon shows down → reverse proxy or network path issue; check nginx/Traefik configuration and TLS termination
  • gRPC port down, HTTP up → check Cerbos config for gRPC bind address; may have failed to bind to 0.0.0.0

Step 7: Kubernetes sidecar deployment monitoring

Cerbos is commonly deployed as a sidecar in Kubernetes, running next to each application pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-application
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-application
  template:
    metadata:
      labels:
        app: my-application
    spec:
      containers:
        - name: app
          image: myapp:latest
          env:
            - name: CERBOS_HOST
              value: "localhost:3593"

        - name: cerbos
          image: ghcr.io/cerbos/cerbos:latest
          args:
            - server
            - --config=/config/cerbos.yaml
          ports:
            - containerPort: 3592  # HTTP
              name: http
            - containerPort: 3593  # gRPC
              name: grpc
          volumeMounts:
            - name: cerbos-config
              mountPath: /config
            - name: policies
              mountPath: /policies
          livenessProbe:
            httpGet:
              path: /_cerbos/health
              port: 3592
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /_cerbos/health
              port: 3592
            initialDelaySeconds: 5
            periodSeconds: 10
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"

      volumes:
        - name: cerbos-config
          configMap:
            name: cerbos-config
        - name: policies
          configMap:
            name: cerbos-policies

For standalone Cerbos deployments (non-sidecar), expose an ingress and monitor it with Vigilmon. Kubernetes liveness probes tell you what the pod scheduler sees; Vigilmon tells you what your application clients and external tools actually reach.


Step 8: Create a status page for authorization infrastructure

  1. Go to Status Pages → New Status Page
  2. Name it: "Authorization Service"
  3. Add your monitors grouped by component:
    • Cerbos PDP: health check, gRPC port
    • Policy API: decision API endpoint
  4. Publish and share with:
    • Application teams who depend on Cerbos for every authenticated request
    • Security teams tracking authorization infrastructure uptime
    • On-call engineers who need to know when auth failures are infrastructure vs. application

Putting it all together

| Monitor | Type | What it catches | |---------|------|----------------| | https://cerbos.yourdomain.com/_cerbos/health | HTTP keyword | Process health, policy engine status, NOT_SERVING state | | cerbos.yourdomain.com:3593 | TCP | gRPC port availability for SDK clients | | https://cerbos.yourdomain.com/api/check/resources | HTTP | End-to-end policy evaluation path |


What's next

  • Policy metrics — Cerbos exposes Prometheus metrics at /_cerbos/metrics; scrape with Prometheus for decision latency and policy hit rates; use Vigilmon for the external availability signal
  • SSL certificate monitoring — Vigilmon tracks TLS cert expiry for your Cerbos endpoints automatically
  • Multi-region monitoring — if you run Cerbos in multiple regions for latency, add a Vigilmon monitor for each regional endpoint

Get started free at vigilmon.online — no credit card, monitors start running in under a minute.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →