Ory Kratos is the cloud-native identity and user management system that handles login, registration, account recovery, settings, and MFA flows as decoupled API endpoints. When Kratos becomes unavailable, users can't log in or create accounts, and every application relying on its session cookies or tokens starts returning authentication errors. When the email courier stalls, password reset and verification emails queue up silently while users wait. Vigilmon gives you external visibility into Kratos's public and admin APIs, its self-service flows, the email courier, and the database backing all identity data so you catch failures before users encounter authentication dead-ends.
What You'll Build
- An HTTP monitor on Kratos's
/health/aliveendpoint to detect process failures - An HTTP monitor on Kratos's
/health/readyendpoint to detect unready dependencies - HTTP monitors on the public self-service flow endpoints (login, registration)
- A monitor for the Kratos email courier delivery health
- Database connectivity monitoring via TCP
- SSL certificate monitoring for all Kratos-facing domains
- An alert runbook mapping Vigilmon findings to Kratos remediation commands
Prerequisites
- Ory Kratos v1.0+ deployed via Helm, Docker Compose, or the Ory Network
- PostgreSQL or another supported database configured as the identity backend
- SMTP or a courier service configured for transactional email delivery
- A Kubernetes cluster with
kubectlaccess or Docker withdocker composeaccess - A free account at vigilmon.online
Step 1: Understand Kratos's Observability Surface
Kratos exposes distinct liveness and readiness endpoints and writes structured JSON logs. Before configuring external monitoring, inspect what is available:
# Kubernetes: check Kratos pod status
kubectl get pods -n ory
# View live Kratos logs
kubectl logs -n ory deployment/kratos --tail=50 -f
# Test the liveness endpoint (is the process alive?)
curl https://kratos.example.com/health/alive
# Expected: {"status":"ok"}
# Test the readiness endpoint (are dependencies connected?)
curl https://kratos.example.com/health/ready
# Expected: {"status":"ok"} — fails if database is unreachable
# Test the public API (are self-service flows reachable?)
curl https://kratos.example.com/self-service/login/browser
# Expected: 302 redirect to login UI (means API is routing)
# Check the admin API (internal only by default)
kubectl port-forward -n ory svc/kratos-admin 4434:4434
curl http://localhost:4434/health/alive
The key signals are:
/health/alive: Returns{"status":"ok"}as long as the Kratos process is running./health/ready: Returns{"status":"ok"}only when the database connection is established and migrations are complete. This is the critical readiness gate.- Self-service endpoints: If
/self-service/login/browserreturns 5xx rather than a redirect, the flow routing layer has failed. - Courier stalling: Undelivered emails accumulate in the database while Kratos logs
level=warning msg="Courier is not running".
Step 2: Expose Kratos Endpoints for External Monitoring
Kratos splits its surface into a public API (port 4433, user-facing) and an admin API (port 4434, internal). The public API is already externally reachable if you have an Ingress. The readiness endpoint is on the public API:
# kratos-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kratos-public
namespace: ory
annotations:
nginx.ingress.kubernetes.io/proxy-buffer-size: "128k"
spec:
rules:
- host: kratos.example.com
http:
paths:
- path: /health
pathType: Prefix
backend:
service:
name: kratos-public
port:
number: 4433
- path: /self-service
pathType: Prefix
backend:
service:
name: kratos-public
port:
number: 4433
tls:
- hosts:
- kratos.example.com
secretName: kratos-tls
kubectl apply -f kratos-ingress.yaml
# Verify both health endpoints are reachable
curl https://kratos.example.com/health/alive
curl https://kratos.example.com/health/ready
Step 3: Create Vigilmon HTTP Monitors for Health Endpoints
Create two monitors — one for liveness, one for readiness:
Liveness monitor (process alive):
- Log in to Vigilmon → Add Monitor → HTTP.
- URL:
https://kratos.example.com/health/alive. - Check interval: 1 minute.
- Response timeout: 10 seconds.
- Expected status:
200. - Keyword:
ok. - Label:
kratos liveness. - Click Save.
Readiness monitor (dependencies connected):
- Add Monitor → HTTP.
- URL:
https://kratos.example.com/health/ready. - Check interval: 2 minutes.
- Response timeout: 15 seconds.
- Expected status:
200. - Keyword:
ok. - Label:
kratos readiness. - Click Save.
The two-monitor pattern is deliberate:
- Liveness down, readiness also down: Kratos process is crashed or restarting.
- Liveness up, readiness down: Kratos is running but its database connection has been lost. This is the most common production failure mode.
This pairing catches:
- Pod crashes and OOM kills that halt all identity operations
- Database connection pool exhaustion during traffic spikes
- Pending migrations after Kratos version upgrades that block readiness
- DSN misconfiguration after secret rotation that makes Kratos unable to connect
Step 4: Monitor Self-Service Flow Availability
Kratos's health endpoints check internal wiring, but the self-service flows — login, registration, recovery — go through additional middleware and browser redirect logic. A routing failure in the flow layer can leave the health endpoints green while users encounter errors:
# Test login flow initiation
curl -o /dev/null -s -w "%{http_code}" \
https://kratos.example.com/self-service/login/browser
# Expected: 302 (redirect to login UI) or 200 if UI is inlined
# Test registration flow initiation
curl -o /dev/null -s -w "%{http_code}" \
https://kratos.example.com/self-service/registration/browser
# Expected: 302 or 200
In Vigilmon:
- Add Monitor → HTTP.
- URL:
https://kratos.example.com/self-service/login/browser. - Check interval: 5 minutes.
- Expected status:
302(if Kratos redirects to a separate UI) or200(if UI is embedded). - Label:
kratos login flow. - Click Save.
Repeat for the registration flow at /self-service/registration/browser.
Step 5: Monitor Email Courier Delivery
Kratos uses an internal courier to send verification and password recovery emails. The courier runs as a background goroutine and can stall silently — particularly after SMTP configuration changes or upstream email provider outages:
# Check courier status via the admin API
kubectl port-forward -n ory svc/kratos-admin 4434:4434
curl http://localhost:4434/admin/courier/messages?status=queued | jq '.[] | .status'
# Check for courier-related errors in logs
kubectl logs -n ory deployment/kratos | grep -i "courier\|smtp\|email" | tail -20
# Count queued messages (stalling courier means this grows)
curl http://localhost:4434/admin/courier/messages?status=queued | jq 'length'
For direct SMTP monitoring in Vigilmon:
- Add Monitor → TCP.
- Host:
smtp.example.com(your SMTP relay host). - Port:
587(submission) or465(SMTPS). - Check interval: 5 minutes.
- Label:
kratos smtp courier host. - Click Save.
If you use a third-party transactional email API (Mailgun, Postmark, SendGrid), add an HTTP monitor on the provider's status page or API ping endpoint.
Step 6: Monitor Database Connectivity
Kratos's readiness endpoint fails when the database is unreachable, but that failure mode gives you no indication of whether it's the database itself or the connection string. Add a direct TCP monitor on the database:
# Find your database service
kubectl get svc -n ory | grep postgres
# Test connectivity
psql "postgresql://kratos:password@postgres.ory.svc.cluster.local:5432/kratos" \
-c "SELECT 1;"
In Vigilmon:
- Add Monitor → TCP.
- Host:
postgres.example.com(or your database endpoint). - Port:
5432. - Check interval: 2 minutes.
- Label:
kratos postgresql backend. - Click Save.
When both the Kratos readiness monitor and the PostgreSQL TCP monitor are down simultaneously, the root cause is the database — not Kratos itself. This triage signal saves significant debugging time.
Step 7: Monitor SSL Certificates
Kratos handles user authentication tokens and session cookies over HTTPS. A certificate expiry breaks every client application that calls the Kratos API:
# Check the Kratos public API certificate
openssl s_client -connect kratos.example.com:443 2>/dev/null | \
openssl x509 -noout -dates
# Check the login UI domain if separate
openssl s_client -connect login.example.com:443 2>/dev/null | \
openssl x509 -noout -dates
In Vigilmon:
- Add Monitor → SSL Certificate.
- Domain:
kratos.example.com. - Alert when expiry is within: 30 days.
- Alert again: 14 days, 7 days, 3 days, 1 day.
- Click Save.
Repeat for your login UI domain, any OAuth2/OIDC callback domains, and your SMTP relay if it uses client certificates.
Step 8: Configure Alerting and Runbook
In Vigilmon under Settings → Notifications, configure your alert channels:
| Monitor | Trigger | Immediate Action |
|---|---|---|
| Liveness | Non-200 | kubectl get pods -n ory → check crash status; kubectl logs -n ory deployment/kratos --tail=30 |
| Readiness | Non-200 | kubectl logs -n ory deployment/kratos \| grep -i "database\|dsn\|migration" → check database connectivity |
| Login flow | Non-302/200 | Check Ingress rules; verify Kratos public API is routing; check SELFSERVICE_FLOWS_LOGIN_UI_URL config |
| SMTP TCP | Connection refused | Check SMTP relay service; verify credentials in Kratos courier config; check email provider status |
| PostgreSQL TCP | Connection refused | Check database pod/service; verify DATABASE_URL in Kratos secret; check storage capacity |
| SSL certificate | < 30 days to expiry | kubectl get certificates -n ory; check cert-manager logs; trigger manual renewal if needed |
Common Ory Kratos Failure Modes and What Vigilmon Catches
| Scenario | Vigilmon monitor | |---|---| | Kratos pod crashes after config change | Liveness endpoint returns 502; alert within 1 min | | Database connection pool exhausted under load | Readiness endpoint fails; liveness stays green | | Kratos migration pending after version upgrade | Readiness endpoint returns error; prevents schema drift being silently ignored | | SMTP credentials rotated without updating Kratos config | SMTP TCP port check stays green (server alive); email delivery fails silently — monitor courier queue separately | | Login UI service crashes independently | Liveness/readiness green; login flow monitor catches 502 on redirect target | | cert-manager fails to renew Kratos TLS | SSL monitor catches 30 days before browsers show certificate errors | | PostgreSQL runs out of disk space | TCP check succeeds; readiness monitor fails when Kratos can't write sessions | | Kratos namespace deleted accidentally | All monitors go down simultaneously; unambiguous full-stack failure |
Ory Kratos separates identity management from application code and makes it possible to evolve authentication flows independently — but that decoupling means a Kratos failure takes down every application that depends on it, often without those applications logging meaningful error messages. Vigilmon closes the blind spot with independent checks on the liveness and readiness separation that Kratos exposes by design, plus direct monitoring of the database and email courier that your application code can't observe. When something breaks, you know within minutes whether the issue is Kratos itself, its database, or its email pipeline.
Start monitoring Ory Kratos in under 5 minutes — register free at vigilmon.online.