Running Open-SSPM
This guide covers day-to-day operation of Open-SSPM.
For the realtime architecture and provider matrix, see Real-Time Synchronization.
Components
| Command | Purpose | Normally Running? |
|---|---|---|
open-sspm api | Web UI and API | Yes |
open-sspm worker | Background full sync loop | Yes |
open-sspm worker-discovery | Background discovery sync loop | Optional |
open-sspm worker-ingest | Background push ingest queue processing | Optional |
open-sspm worker-tail | Background incremental audit/delta tail loop | Yes for realtime sync |
open-sspm worker-riskpolicy | Background shadow canonical-event riskpolicy loop | Yes for event shadow evaluation |
Starting the Application
Repo-Local Workflow
Start Postgres:
just dev-upRun the app processes in separate terminals:
just runjust workerjust worker-discoveryjust worker-ingestjust worker-tailjust worker-riskpolicyThe discovery worker is only needed when SYNC_DISCOVERY_ENABLED=1 and you want polling-based discovery data. The ingest worker is needed when you enable push ingest such as Okta Event Hooks or EventBridge. The tail worker keeps cursor-based providers caught up, and the riskpolicy worker evaluates canonical events in shadow mode.
Kubernetes
The Helm chart runs the commands as Deployments:
kubectl get deployments -l app.kubernetes.io/name=open-sspm
kubectl get pods -l app.kubernetes.io/name=open-sspmScale a component:
kubectl scale deployment open-sspm-api --replicas=2
kubectl scale deployment open-sspm-worker --replicas=1
kubectl scale deployment open-sspm-worker-discovery --replicas=1
kubectl scale deployment open-sspm-worker-ingest --replicas=1
kubectl scale deployment open-sspm-worker-tail --replicas=1
kubectl scale deployment open-sspm-worker-riskpolicy --replicas=1Stopping the Application
Repo-Local Workflow
- Stop
apiand worker processes withCtrl-Cin each terminal. - Stop the local Postgres dependency with:
just dev-downKubernetes
Scale Deployments to zero:
kubectl scale deployment open-sspm-api --replicas=0
kubectl scale deployment open-sspm-worker --replicas=0
kubectl scale deployment open-sspm-worker-discovery --replicas=0
kubectl scale deployment open-sspm-worker-ingest --replicas=0
kubectl scale deployment open-sspm-worker-tail --replicas=0
kubectl scale deployment open-sspm-worker-riskpolicy --replicas=0Viewing Logs
Repo-Local Workflow
just run, just worker, just worker-discovery, just worker-ingest, just worker-tail, and just worker-riskpolicy log directly to their terminal sessions.
For the local Postgres container:
docker compose logs dbKubernetes
kubectl logs -l app.kubernetes.io/component=api -f
kubectl logs -l app.kubernetes.io/component=worker -f
kubectl logs -l app.kubernetes.io/component=worker-discovery -f
kubectl logs -l app.kubernetes.io/component=worker-ingest -f
kubectl logs -l app.kubernetes.io/component=worker-tail -f
kubectl logs -l app.kubernetes.io/component=worker-riskpolicy -fManual Sync Operations
Trigger a Sync from the UI
- Settings → Resync data → Resync now queues an immediate full sync, and also queues discovery when discovery is enabled globally.
- Settings → Connector health → Trigger sync queues a sync for a specific connector.
Trigger a Sync from the CLI
just syncopen-sspm sync runs the full sync lane and then runs discovery if SYNC_DISCOVERY_ENABLED=1.
To run only the discovery lane:
just sync-discoveryShadow Event Projection
Canonical events can be replayed into the shadow discovery projection and compared against baseline discovery event rows:
just event-projection -- --source-kind okta --source-name your-org.okta.comThis command records parity diff rows and does not cut the UI over to the shadow read model. When --since is omitted, projection resumes from the last stored checkpoint for that source.
Manual Resync Mode
RESYNC_MODE controls how UI-triggered resyncs execute:
| Mode | Behavior | Use Case |
|---|---|---|
signal | Queue durable jobs for background workers | Normal operation |
inline | Run the sync inside the HTTP request | Debugging and single-process setups |
Monitoring Sync Status
Use Settings → Connector health to review:
- Last successful run
- Last attempted run
- Recent success rate
- Average successful run duration
- Latest connector-specific errors
Health Checks
Web Health Endpoint
curl http://localhost:8080/healthzExpected response:
okMetrics Endpoint
Metrics are only exposed when METRICS_ADDR is set to a non-empty value.
Example:
curl http://127.0.0.1:9090/metricsBackup Operations
Database Backup
pg_dump "$DATABASE_URL" > opensspm-backup-$(date +%Y%m%d).sqlIf you are using the repo-local Postgres container:
docker compose exec -T db pg_dump -U postgres opensspm > backup.sqlRestore
psql "$DATABASE_URL" < backup.sqlFor the repo-local Postgres container:
docker compose exec -T db psql -U postgres opensspm < backup.sqlUpdates and Upgrades
Repo-Local Workflow
After updating the checkout:
just migrate
just uiThen restart api and the worker processes.
Kubernetes
helm upgrade open-sspm ./helm/open-sspm -f values.yaml
kubectl rollout status deployment/open-sspm-apiTroubleshooting
Web UI not loading
Check:
just runis running.HTTP_ADDRis correct.- CSS assets were built with
just ui. - The application can reach
DATABASE_URL.
Syncs are not running
Check:
just workeris running.RESYNC_MODE=signalhas a background worker available.- Connector health shows recent runs and errors.
Tail jobs are not running
Check:
just worker-tailis running.SYNC_TAIL_INTERVALis a positive duration.- The connector declares an executable tail capability. Current executable tails include Okta System Log, Google Workspace Reports activities, Datadog Audit Logs, and AWS CloudTrail when the provider client is configured.
Shadow event findings are not updating
Check:
just worker-riskpolicyis running.- Canonical events are being written for the source.
riskpolicy_event_queuerows are not stuck inprocessing; stale rows are requeued by the worker.
Discovery data is missing
Check:
SYNC_DISCOVERY_ENABLED=1just worker-discoveryis running- Discovery is enabled on the relevant IdP connector
Okta push ingest is not processing
Check:
just worker-ingestis running.- The Okta Event Hook or EventBridge endpoint reaches the API process.
- The connector ingest mode and shared secret match the delivery channel.
Event partitions are not advancing
Check:
- At least one worker process is running.
EVENT_PARTITION_MAINTENANCE_INTERVAL,EVENT_PARTITION_FUTURE_DAYS, andEVENT_RETENTION_DAYSare positive.- Worker logs include
event partition maintenance complete.
Database connection errors
Test the connection directly:
psql "$DATABASE_URL" -c "SELECT 1"Getting Help
Review application logs first, then open an issue on GitHub with:
- The command or deployment mode you are using
- Relevant error messages
- Steps to reproduce the problem