OpenSourceOM security model
Core assumes it runs in a network you control. The database holds a copy of your inventory, IAM relationships, and findings. Protect Postgres and the API the way you protect that data.
Personal API tokens
Each admin has a personal API token. The console shows the raw value once, after the account
is created or after a rotation. Graph and ingest routes require
Authorization: Bearer <token>, X-API-Key: <token>, or
a console session cookie. That includes graph reads, findings, the rules list, blast radius,
ingest, rules run, and Slack export. A missing or wrong credential is 401. There is no shared
secret and no open mode.
GET /v1/health, GET /v1/auth/session,
POST /v1/auth/logout, POST /v1/auth/setup,
POST /v1/auth/login, POST /v1/auth/totp,
POST /v1/auth/forgot, and POST /v1/auth/reset do not require a session.
GET /v1/admins, POST /v1/admins,
POST /v1/admins/token, and
DELETE /v1/admins/{id} require a console session. A personal token cannot
add or remove admins. The console HTML at / and /login loads
without a session so the sign-in page can render. See Console.
Keep the API port private until the first admin exists. Whoever can open it first can become
that admin. Create the account with om admin create before you publish the
port when you can. The CLI never sends this header. Anyone who can open a local shell as a
user with database credentials can scan and export without a token.
People use an email and password. Scripts use a personal token. Do not publish the Service to the internet. Put it on a private network or behind a gateway you operate.
Console admins
People sign in with an email and password. Every account is an admin. The first account is
created from the setup form, or with om admin create before the port is
reachable. OM_ADMIN_EMAIL pins that first address when you set it. Later admins
receive a temporary password and choose their own at the next sign-in. When SMTP is
configured, an admin can request a one-hour reset link. The response does not reveal
whether the address exists. The link works once, sets a new password, and ends that
admin's sessions. Personal API tokens stay valid. Passwords are stored
as Argon2id hashes. Optional authenticator-app two-factor authentication is per admin.
Sessions are httpOnly cookies. The cookie is marked Secure when
OM_PUBLIC_URL uses https.
Google and GitHub are optional. A verified provider email must match an existing admin. OAuth client secrets and the SMTP password are deployment secrets. Password login works without them, including on an air-gapped console.
Collectors
Built-in collectors call read APIs. Give them a role that cannot change infrastructure. Plugins run with your user privileges and are not sandboxed. Review plugin binaries the way you review any other code that holds cloud credentials.
POST /v1/export/slack reads the webhook from the JSON body
({"webhook":"..."}) and rejects a webhook query parameter so
the URL is less likely to land in access logs. The body is still a credential. Prefer
om export findings run --format slack with SLACK_WEBHOOK_URL in
the environment.
Console script
The graph view loads vis-network from /ui/vis-network.min.js on the API. It is
not loaded from a CDN. The session cookie is httpOnly, so page script cannot read it.
Reporting a vulnerability
Email security@opensourceom.org. Do not open a public GitHub issue for a security bug. The core repository’s SECURITY.md is the project policy.
Copyright © 2026 OpenSourceOM. Licensed under Apache-2.0.