Granting diagnostic or monitoring access to an RDS PostgreSQL instance should follow the
principle of least privilege: the account should be able to read system statistics and
metadata — pg_stat_activity, pg_stat_user_tables,
pg_stat_statements — without the ability to read application data or modify
any configuration.
This guide covers two layers: the AWS IAM role (controls what can be done to the RDS resource via the AWS API) and the PostgreSQL database role (controls what the connecting user can do inside the database). Both are required for a properly scoped read-only monitoring setup on RDS PostgreSQL 16, 17, and 18.
Part 1 — AWS IAM policy for read-only RDS access
This IAM policy grants read-only access to RDS describe and metrics APIs — sufficient for monitoring tooling that needs to enumerate instances, read parameter groups, and access Performance Insights. It grants no ability to modify instances, snapshots, or parameters.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RDSReadOnly",
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:DescribeDBClusters",
"rds:DescribeDBParameterGroups",
"rds:DescribeDBParameters",
"rds:DescribeDBLogFiles",
"rds:DownloadDBLogFilePortion",
"cloudwatch:GetMetricData",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics",
"pi:GetResourceMetrics",
"pi:DescribeDimensionKeys",
"pi:ListAvailableResourceDimensions"
],
"Resource": "*"
}
]
}
"Resource": "*" with the specific
RDS instance ARN to restrict access to a single database instance:
arn:aws:rds:eu-west-1:123456789012:db:my-instance-id. This is especially
important if the IAM role will be attached to a third-party monitoring tool or shared
service account.
Part 2 — PostgreSQL database role
Create a dedicated PostgreSQL role with read-only access to system statistics.
On RDS PostgreSQL 16, 17, and 18, the pg_monitor built-in role grants
read access to all monitoring views without superuser:
-- Create the monitoring user: CREATE ROLE pgflare_monitor WITH LOGIN PASSWORD 'use-a-strong-random-password' CONNECTION LIMIT 3 NOSUPERUSER NOCREATEDB NOCREATEROLE; -- Grant pg_monitor (read access to pg_stat_*, pg_stat_activity, etc.): GRANT pg_monitor TO pgflare_monitor; -- Grant access to pg_stat_statements (requires explicit GRANT on PG16+): GRANT EXECUTE ON FUNCTION pg_stat_statements_reset() TO pgflare_monitor; GRANT SELECT ON pg_stat_statements TO pgflare_monitor;
The pg_monitor role is available in PostgreSQL 10+ and is specifically designed
for monitoring use cases. It grants SELECT on all pg_stat_* views
and access to functions like pg_stat_get_activity without the risks of a
superuser account.
Part 3 — Restrict network access
The monitoring role should only be accessible from known IP ranges or VPC security groups. In your RDS security group, restrict inbound PostgreSQL traffic (port 5432) to:
- Your application security group (the SG attached to your app servers / ECS tasks)
- Your monitoring tool's security group or specific IP range
- A bastion host security group for interactive access
Never open port 5432 to 0.0.0.0/0. RDS instances inside a VPC are not
publicly accessible by default — ensure Publicly Accessible is set to
No on the RDS instance settings.
Using IAM database authentication (optional)
RDS PostgreSQL 16, 17, and 18 support IAM database authentication, which replaces static passwords with short-lived tokens generated by the AWS SDK. This is the recommended approach for machine accounts (monitoring agents, Lambda functions) where password rotation is operationally expensive:
-- Create the user with rds_iam attribute (no PASSWORD needed): CREATE ROLE pgflare_monitor WITH LOGIN; GRANT rds_iam TO pgflare_monitor; GRANT pg_monitor TO pgflare_monitor; -- Generate a token (15-minute TTL) in the connecting application: -- aws rds generate-db-auth-token \ -- --hostname your-rds-endpoint \ -- --port 5432 \ -- --username pgflare_monitor
PGFlare uses exactly this role structure for every client engagement.
The read-only monitoring role is created
during onboarding, scoped to pg_monitor + pg_stat_statements, with no access to application
data. A full step-by-step setup guide with Terraform examples is included when you book
a Diagnostic session.