Back to changelog
New
2 minute read

Security Scan: Report Vulnerabilities in Running Databases

A new atlas security scan command connects to running databases and reports the security issues it finds in them, starting with the installed extensions affected by a published CVE, resolved against the Atlas Security Graph.

Linting catches a vulnerable extension before it is installed, but new CVEs are published for versions that are already running, and no amount of CI will surface those.

atlas security scan reads the live database instead: it resolves the installed extensions against the Security Graph to identify and rank CVEs in your databases.

atlas security scan brings that to the CLI on demand. Atlas connects to your database and reports the security issues found, with the cve check included by default. It reads the live database, so it needs neither a dev database nor access to your codebase, which is what makes it useful on a schedule: new CVEs are published for versions that are already installed, and no amount of CI will surface those.

Scanning a Database

Point the command at a database with --url. Each finding carries the CVE identifier, the level it is graded at, and the version to upgrade to. Credentials are redacted, so the report is safe to keep in CI logs or forward to a webhook:

atlas security scan --url "postgres://postgres:pass@localhost:5432/app?sslmode=disable"
Scanning 1 database for security issues:
-- postgres://postgres:xxxxx@localhost:5432/app?sslmode=disable (postgres 13.23):
-- Extension "pg_trgm" version "1.5" is vulnerable to CVE-2026-14678 (ELEVATED):
PostgreSQL pg_trgm picksplit reads past end of buffer. Upgrade the database engine to
version 14.24 or later to resolve CVE-2026-14678: the fix for extension "pg_trgm" ships in
engine releases
-- Extension "pgcrypto" version "1.3" is vulnerable to CVE-2026-14663 (ELEVATED):
PostgreSQL pgcrypto, for OpenSSL-disabled ciphers, silently encrypts to and decrypts
from cleartext. Upgrade the database engine to version 14.24 or later to resolve
CVE-2026-14663: the fix for extension "pgcrypto" ships in engine releases
-- Extension "pgcrypto" version "1.3" is vulnerable to CVE-2026-2005 (HIGH): PostgreSQL
pgcrypto heap buffer overflow executes arbitrary code. Upgrade the database engine to
version 14.21 or later to resolve CVE-2026-2005: the fix for extension "pgcrypto" ships in
engine releases
-------------------------
-- 864.441209ms
-- 3 issues found: 1 high, 2 elevated

Findings are matched against the installed extension version and the engine version of the scanned database, which is why the three above name an engine upgrade rather than an extension upgrade. The fix for a built-in extension ships in an engine release.

Configuring the Scan

A security block in atlas.hcl configures it. Each check has its own block and runs when that block is present, and the cve check is included by default, so a bare security {} still runs it:

env "prod" {
url = "postgres://postgres:pass@localhost:5432/app?sslmode=disable"
security {
fail_on = HIGH
cve {
ignore = ["CVE-2026-14678"]
}
notify {
http "slack" {
url = var.slack_webhook
headers = { "Content-Type" = "application/json" }
body = jsonencode({
text = "${scan.count} vulnerable extensions (${scan.high} high, ${scan.elevated} elevated)"
})
}
}
}
}
Block or attributeDescription
min_severityThe lowest level every check reports: NORMAL, ELEVATED, HIGH, or CRITICAL, as the Security Graph grades them. A check raises it for itself, and never lowers it.
fail_onFail the command when an issue of this level or higher was reported. Issues are reported without failing the command when unset.
cveThe check reporting installed extensions with known vulnerabilities. Takes min_severity, ignore, and timeout.
notifySends the result to HTTP endpoints, such as a Slack webhook. The url, headers, and body may interpolate the scan.

Gating and Reporting Are Separate

A database that could not be scanned always fails the command, since that leaves its state unknown. The issues it reports do not, until fail_on names a severity. This keeps a scheduled scan honest: it reports everything it finds while only the severity you chose breaks the build.

Both failures exit non-zero without printing a message of their own, because the report already names the target and the reason. For an unattended run, pair the gate with a notify block, which sends on findings and on failures by default. Anything the CVSS rated below HIGH is graded ELEVATED, so a job gated at HIGH stays green on the most common finding there is.

Machine-Readable Output

--format takes a Go template, so the result can feed a dashboard or a policy gate instead of a terminal:

atlas security scan --url "postgres://postgres:pass@localhost:5432/app?sslmode=disable" \
--min-severity HIGH --format '{{ json . " " }}'
{
"Targets": [
{
"URL": "postgres://postgres:xxxxx@localhost:5432/app?sslmode=disable",
"Driver": "postgres",
"Version": "13.23",
"Extensions": [
"hstore",
"pg_trgm",
"pgcrypto"
],
"Vulnerabilities": [
{
"Name": "pgcrypto",
"Version": "1.3",
"ID": "CVE-2026-2005",
"Level": "HIGH",
"Severity": "HIGH",
"Title": "PostgreSQL pgcrypto heap buffer overflow executes arbitrary code",
"Suggestion": "Upgrade the database engine to version 14.21 or later to resolve CVE-2026-2005: the fix for extension \"pgcrypto\" ships in engine releases"
}
]
}
],
"Start": "2026-08-26T17:52:37.960585+07:00",
"End": "2026-08-26T17:52:38.356392+07:00"
}
atlas security scan and the security block are available to Atlas Pro users with the Security Graph enabled in their plan. Get started by running atlas login, or read more about Atlas Pro.

See the Security Scanning documentation for the full reference, and Vulnerable Extensions for the analyzer that catches the same problem in CI, before the extension is installed.

featuresecuritycvesecurity graphpostgresatlas pro