Install OpenSourceOM on Kubernetes
The chart in deploy/helm/opensourceom installs the API Deployment and, by
default, a Postgres StatefulSet. Chart version and appVersion are
0.3.0. When bundled Postgres is enabled, an init container named
wait-db runs pg_isready against
{{release}}-opensourceom-postgres. A second init container runs
om migrate. The main container runs om serve. Readiness and
liveness probe GET /v1/health. With an external database,
wait-db is omitted and migrate still runs, so that host must
accept connections before the pod can become Ready.
Install
api.secret and postgres.password are required. The image repository
defaults to ghcr.io/opensourceom/core. An empty image.tag falls
back to the chart appVersion (0.3.0). Set the tag when you are not
running that release.
docker build -t ghcr.io/opensourceom/core:0.3.0 .
helm install om deploy/helm/opensourceom \
--set api.secret='change-me' \
--set postgres.password='change-me' \
--set image.tag=0.3.0
Load that image into the cluster if you are not pushing to GHCR. Published images live at
ghcr.io/opensourceom/core.
The Service is ClusterIP on port 8080. The release name om yields a
Service named om-opensourceom:
kubectl port-forward svc/om-opensourceom 8080:8080 Values
| Value | Default | Role |
|---|---|---|
replicaCount | 1 | API replicas. They share one database. |
image.repository | ghcr.io/opensourceom/core | API image. |
image.tag | empty, then chart appVersion (0.3.0) | Image tag. Set it when the cluster should not run 0.3.0. |
service.type / service.port | ClusterIP / 8080 | How the API is reached inside the cluster. |
api.env | production | Written to OM_ENV. |
api.secret | empty, required | OM_API_SECRET. |
postgres.enabled | true | When false, set postgres.host to your own server. |
postgres.persistence.size | 10Gi | PVC for the bundled database. storageClass is optional. |
resources | 100m / 128Mi request, 1 CPU / 512Mi limit | API container. Scan CronJobs use the same limits unless scan.resources is set. |
scan.schedule | 0 */6 * * * | Schedule for every enabled collector. Overlapping runs of one collector are skipped. |
Scheduled scans
Collectors stay off until you enable one and supply credentials. The chart then runs
om scan as a CronJob against the same Postgres the API reads. For a release
named om, that Service is om-opensourceom-postgres.
om scan demo is not scheduled. A scan does not run CSPM rules.
helm upgrade om deploy/helm/opensourceom \
--reuse-values \
--set scan.aws.enabled=true \
--set scan.aws.existingSecret=aws-creds aws-creds must contain AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY. Azure needs scan.azure.subscriptionId and a
Secret with AZURE_TENANT_ID, AZURE_CLIENT_ID, and
AZURE_CLIENT_SECRET. GCP needs scan.gcp.projectId and a Secret key
named credentials.json. Inline key fields on scan.aws,
scan.azure, and scan.gcp work the same way and are copied into a
chart Secret. serviceAccountAuth: true skips the static key and uses the chart
ServiceAccount; set scan.serviceAccount.annotations for IRSA or workload identity.
Enabling a cloud collector without one of those credentials does not create a CronJob.
scan.kubernetes.enabled=true schedules om scan k8s. With no
kubeconfig Secret, the chart creates a read-only ServiceAccount for this cluster.
scan.kubernetes.namespace empty is a ClusterRole; a namespace is a Role in that
namespace. scan.kubernetes.cluster is the graph account id. Set
scan.kubernetes.existingSecret to mount a kubeconfig instead (key
kubeconfig, unless kubeconfigKey says otherwise). See
the Kubernetes collector.
Set postgres.enabled=false and postgres.host to use a database you
already run. postgres.host is required in that mode. The chart still creates
the API Secret. It does not create a database user on the external server.
Keep the Service off the public internet, or put your own gateway in front of it. See
Security for how OM_API_SECRET applies.
Copyright © 2026 OpenSourceOM. Licensed under Apache-2.0.