Skip to main content

PostgreSQL Database Discovery

Tripl-i automatically discovers PostgreSQL instances and databases on Linux servers during SSH scans, providing complete visibility into your PostgreSQL infrastructure alongside other discovered assets.

Overview

When PostgreSQL is detected on a scanned Linux server, the scanner automatically gathers instance configuration, database inventory, active connections, replication status, and installed extensions. This data creates DatabaseInstance and Database CIs with full dependency mapping.

Key Benefits

  • Complete Database Inventory - Discover all PostgreSQL instances and databases across your infrastructure
  • Dependency Mapping - Identify which applications and servers connect to your databases
  • Replication Visibility - Detect primary/standby configurations and streaming replication status
  • Extension Tracking - Know which extensions (PostGIS, pg_stat_statements, etc.) are installed per database
  • Vulnerability Management - CPE generation enables CVE tracking for PostgreSQL versions
  • Capacity Planning - Track database sizes and connection counts

How It Works

Discovery Flow

StepAction
1Linux server is scanned via SSH
2PostgreSQL detected via running processes (postgres), listening port (5432), or installed binary (psql)
3Scanner authenticates to PostgreSQL (OS auth or provided credentials)
4Instance configuration, database inventory, connections, replication, and extensions collected
5DatabaseInstance and Database CIs created
6Relationships mapped between instances, databases, and connected servers/workloads

Automatic Triggering

Database discovery is automatically triggered when:

  • A Linux server is scanned via SSH
  • A running postgres process is detected, or port 5432 is listening, or psql binary is found
  • No additional configuration is required for servers where the SSH account has sudo access

Authentication

Default: OS Authentication (No Extra Credentials)

The scanner uses peer authentication via the postgres OS user:

sudo -u postgres psql

This works on most Linux installations where:

  • The SSH scanning account has sudo access
  • PostgreSQL is configured with default peer authentication in pg_hba.conf

No separate database credentials are required in this case.

Optional: Password Authentication

If sudo access is not available, you can configure PostgreSQL credentials in the Scanner GUI:

  1. Go to Credentials tab
  2. Select protocol: PostgreSQL
  3. Enter Username and Password
  4. Set Port (default: 5432)
  5. Set IP Range to target the database server(s)

The scanner uses the PGPASSWORD environment variable for authentication, keeping passwords out of process listings.

Authentication Priority

PriorityMethodWhen Used
1Provided credentials (PGPASSWORD)When PostgreSQL credentials are configured
2sudo -u postgres psql (peer auth)When SSH user has sudo access
3psql (current user)Fallback if peer auth is configured for SSH user

Required PostgreSQL Permissions

For full discovery, the database user needs:

PermissionPurpose
CONNECT on databasesAccess each database for extension discovery
pg_read_all_settings roleRead all configuration parameters
pg_read_all_stats roleRead activity and replication statistics

The default postgres superuser (via peer auth) has all these permissions automatically.

Data Collected

Instance Information

Data PointDescription
VersionPostgreSQL version (e.g., 16.1)
PortListening port (default 5432)
Data DirectoryLocation of database cluster files
Max ConnectionsMaximum allowed connections
Shared BuffersShared memory buffer size
Work MemoryPer-operation memory allocation
WAL LevelWrite-ahead log level (replica, logical, minimal)
Archive ModeWhether WAL archiving is enabled
Listen AddressesNetwork interfaces accepting connections
SSLWhether SSL is enabled
Is ReplicaWhether this instance is a streaming replica
CPECommon Platform Enumeration for vulnerability matching

Database Information

Data PointDescription
Database NameName of the database
OwnerDatabase owner role
EncodingCharacter encoding (e.g., UTF8)
CollationDefault collation
SizeTotal database size in MB
TablespaceDefault tablespace
Connection LimitMax connections for this database (-1 = unlimited)
Is TemplateWhether this is a template database
Frozen XID AgeTransaction ID age (vacuum health indicator)
ExtensionsInstalled extensions with versions

Connection Information

Data PointDescription
Client AddressIP address of connecting client
Client HostnameResolved hostname of client
Application NameApplication identifier (e.g., "pgAdmin", "Django")
UsernamePostgreSQL role used for connection
DatabaseTarget database
StateConnection state (active, idle, idle in transaction)
Connection CountNumber of connections from this client

Replication Information

Data PointDescription
Is ReplicaWhether this instance is a standby server
Primary HostHostname/IP of the primary server (for replicas)

CI Types Created

DatabaseInstance

Represents a PostgreSQL instance (cluster) running on a server.

  • Naming Convention: ServerName:Port (e.g., db-server-01:5432)
  • Database Engine: postgresql

Database

Represents an individual database within a PostgreSQL instance.

  • Naming Convention: ServerName:Port/DatabaseName (e.g., db-server-01:5432/production)

Relationships Created

RelationshipSourceTargetDescription
Runs OnDatabaseInstanceServerInstance runs on server
Part OfDatabaseDatabaseInstanceDatabase belongs to instance
Uses DatabaseServer/WorkloadDatabaseInstanceClient connects to database
Linked ToDatabaseInstanceDatabaseInstanceReplication partner

Cross-Boundary Dependencies

When a Kubernetes workload connects to a PostgreSQL server, the connection is resolved to the Workload CI:

K8s Workload (api-service) ──Uses Database──> DatabaseInstance (db-server-01:5432)

Vulnerability Management

CPE Generation

Format: cpe:2.3:a:postgresql:postgresql:{version}:*:*:*:*:*:*:*

Examples:

  • PostgreSQL 16.1: cpe:2.3:a:postgresql:postgresql:16.1:*:*:*:*:*:*:*
  • PostgreSQL 15.4: cpe:2.3:a:postgresql:postgresql:15.4:*:*:*:*:*:*:*

Best Practices

Security

  • Use peer authentication when possible (no password storage needed)
  • If using password auth, configure credentials per IP range (not wildcard)
  • Monitor databases with archive_mode = off for disaster recovery gaps
  • Review pg_hba.conf rules discovered in the scan for overly permissive access

Monitoring Indicators

Use discovered data to identify issues:

  • High Frozen XID Age (>200 million) - autovacuum may be struggling
  • Replicas with lag - streaming replication health issues
  • Databases at connection limit - capacity constraints
  • Missing extensions (e.g., pg_stat_statements not installed) - observability gaps

Troubleshooting

IssueCauseSolution
PostgreSQL not discoveredProcess not running or different portCheck pg_isready on the target
Cannot connectPeer auth not configured for scanner userConfigure PostgreSQL credentials in Scanner GUI
Missing databasesInsufficient permissionsUse postgres superuser or grant pg_read_all_stats
No connection datapg_stat_activity access deniedGrant pg_read_all_stats role
No extension dataCannot connect to individual databasesGrant CONNECT on all databases