Knowledge Base › Read-Only IAM Role for RDS PostgreSQL
Operations 6 min read · IAM · AWS RDS Security

Read-Only IAM Role for RDS PostgreSQL

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": "*"
    }
  ]
}
Scope the Resource: Replace "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:

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.

View PGFlare IAM Setup Guide →