The two exposures that keep recurring on Amazon RDS and Aurora are not exotic exploits: they are a master password that never changes and lives in a dozen places, and a snapshot that someone shared with the wrong account or with every AWS account. Both are identity and authorisation problems, and both have native fixes that many teams have not switched on. This guide covers how access works at the AWS control plane and inside the database engine, IAM database authentication, Secrets Manager managed master passwords, encryption and key choices, snapshot sharing, RDS Proxy, logging and a hardening baseline aligned to Security Hub and the CIS AWS Database Services Benchmark. It goes deeper on RDS than the engine-neutral Database Credential and Access Security Guide and is written for cloud, database and security engineers.
Key takeaways
- Let RDS manage the master password. With
ManageMasterUserPassword, RDS generates the password, stores it in Secrets Manager and rotates it every seven days by default; you can deny creation of databases without it. - Use IAM authentication for applications where the engine supports it. MySQL, MariaDB and PostgreSQL accept 15-minute IAM tokens instead of stored passwords, but CloudTrail does not log those authentications.
- Encrypt at creation, because you cannot add it later. An unencrypted instance can only be encrypted by copying a snapshot with encryption and restoring from the copy.
- Encrypted snapshots cannot be made public. Public visibility is only possible for unencrypted snapshots, so encryption with a customer managed key is also your best guard against accidental public sharing.
- Control-plane and database access are separate. IAM decides who can modify, snapshot and share a database; engine users decide who can read the data. Secure both.
How identity and access work in RDS and Aurora
| Layer | Who | Controlled by | Key risk |
|---|---|---|---|
| AWS control plane | Engineers, pipelines, backup tools | IAM policies on rds:* actions | Snapshot sharing, password reset via ModifyDBInstance, deletion |
| Master user | Database administrators, automation | Engine password, ideally RDS-managed in Secrets Manager | Static password shared and never rotated |
| Application users | Services and workloads | Engine password or IAM database authentication | Passwords in config files and environment variables |
| IAM database users | Workloads with an IAM role | rds-db:connect permission for a specific database user | Broad rds-db:connect grants across all users |
| RDS Proxy | Applications connecting through the proxy | Proxy authentication scheme and its IAM role | Proxy role able to read too many secrets |
An important consequence: anyone with permission to call ModifyDBInstance or ModifyDBCluster can reset the master password and then connect as the most privileged database user, regardless of database-level grants. Treat those actions as privileged.
IAM database authentication
- Supported engines: MariaDB, MySQL and PostgreSQL (support varies by version and Region), not RDS on Outposts. Aurora MySQL and Aurora PostgreSQL support it too.
- How it works: the client calls
generate-db-auth-token(a SigV4 signature) using its IAM credentials and presents the token as the password. Tokens last 15 minutes and only authenticate the connection; an established session is unaffected when the token expires. - Authorisation: the IAM policy grants
rds-db:connecton a resource of the formarn:aws:rds-db:region:account:dbuser:DbiResourceId/db-user-name. Grant per database user, neverdbuser:*/*. - Limitations: network condition keys such as
aws:SourceIp,aws:SourceVpcandaws:SourceVpceare not supported, so network restriction must come from security groups. IAM authentication uses an extra 300 to 1,000 MiB of memory on the instance. On PostgreSQL, grantingrds_iamto a user, including the master, forces that user to sign in with IAM, and IAM and Kerberos cannot both be enabled. - Logging gap: CloudTrail and CloudWatch do not log IAM authentication or token generation. Use the engine's own connection logging to see who connected.
Choose IAM authentication for workloads that already have IAM roles (ECS tasks, Lambda, EC2, EKS with pod identity), moderate connection rates and a supported engine. Choose Secrets Manager credentials with rotation for SQL Server, Oracle and Db2, for third-party tools that cannot generate tokens, and for very high connection rates, or put RDS Proxy in front. See the Cloud Workload Identity Guide.
Admin roles and privileged access
Managed master passwords
Set --manage-master-user-password on create or modify. RDS generates a 28-character password, stores it in Secrets Manager (encrypted with aws/secretsmanager or a customer managed key you specify, which cannot be changed later) and rotates it every seven days by default. Rotate on demand with --rotate-master-user-password --apply-immediately. Check MasterUserSecret in describe-db-instances: a status of impaired means credentials can be read but rotation is failing, usually because of KMS or permission changes.
| Scenario | Managed master password supported? |
|---|---|
| RDS DB instances and Multi-AZ DB clusters | Yes |
| Aurora DB clusters | Yes (create, modify, restore from S3 for Aurora MySQL) |
| Creating read replicas from a managed source | No, except RDS for SQL Server and RDS for Db2 |
| Blue/Green Deployments, RDS Custom | No |
| Aurora global databases, cross-Region read replicas, binary log external replication | No |
Enforce it with an IAM or SCP deny on rds:CreateDBInstance, rds:CreateDBCluster and restore actions when the condition key rds:ManageMasterUserPassword is false. AWS notes this does not stop someone disabling management later unless you also cover rds:ModifyDBInstance and rds:ModifyDBCluster, which blocks other modifications on non-compliant resources too. Deleting the instance deletes the secret.
Control-plane least privilege
- Separate duties: database operators need start, stop, reboot and parameter changes; only a small group needs
ModifyDBSnapshotAttribute,DeleteDBInstance,DeleteDBClusterand password changes. - Custom administrator name: Security Hub RDS.24 and RDS.25 flag default administrator usernames; a custom name removes one guessable half of the credential.
- Deletion protection: enable it on clusters (RDS.7) and instances (RDS.8). The PocketOS database deletion, on a different platform, shows what happens when one over-scoped token can delete a production database and its backups in a single call.
- Break-glass: keep a documented procedure for retrieving the managed master secret through a monitored role. See the Break-Glass Account Guide.
Integrations, API tokens and service accounts
RDS Proxy
RDS Proxy separates client-to-proxy and proxy-to-database authentication. It supports database credentials, standard IAM authentication (clients use IAM, the proxy fetches database credentials from Secrets Manager) and end-to-end IAM authentication (IAM all the way through, with the proxy's role granted rds-db:connect, removing per-user secrets). Enable "Require Transport Layer Security" and scope the proxy role to the specific secrets it needs.
Application credentials
- One database user per application: never let applications use the master user. Grant engine privileges per schema or table. See the PostgreSQL Security Guide and the MySQL Security Guide.
- Rotate application passwords: store them in Secrets Manager with rotation, and make sure consumers re-read the secret (containers that inject secrets at start need a redeploy). See the Amazon ECS and Fargate Security Guide.
- Third-party tools: BI, migration and monitoring tools often receive broad read access and static passwords. Give each its own user, read-only where possible, and record an owner.
- Encryption in transit: require TLS at the engine (Security Hub RDS.38, RDS.39, RDS.41 and RDS.44 cover PostgreSQL, MySQL, SQL Server and MariaDB) and verify server certificates in clients against the RDS CA bundle.
Encryption and snapshot sharing
Encryption at rest
RDS encryption uses AES-256 and covers storage, logs, automated backups, read replicas and snapshots. It can only be enabled at creation (--storage-encrypted, optionally with --kms-key-id), cannot be disabled, and the key cannot be changed in place: switch keys by copying a snapshot with a new key or with a Blue/Green deployment. Same-Region read replicas must use the source's key. If the KMS key becomes inaccessible, the instance moves to inaccessible-encryption-credentials-recoverable, and after seven days to a terminal state, so key policy changes are an availability risk as well as a security control. See the AWS KMS Security Guide.
| Key choice | Snapshot sharing | Access control | Use when |
|---|---|---|---|
| AWS managed key for RDS | Cannot be shared with other accounts | Any principal with RDS access in the account | Single-account, low-sensitivity workloads |
| Customer managed KMS key | Share snapshot plus key access with named accounts | Key policy and grants, auditable in CloudTrail | Default for production, cross-account backup and regulated data |
| Unencrypted (legacy) | Can be shared with accounts or made public | RDS permissions only | Never for new databases; migrate |
Snapshot sharing
- Limits: manual snapshots can be shared with up to 20 AWS accounts. Automated snapshots must first be copied to a manual snapshot. Snapshots of Multi-AZ DB clusters cannot be shared.
- Public snapshots: setting the
restoreattribute toalllets every AWS account restore your data. AWS's documentation warns against this for any private data, and it is only possible for unencrypted snapshots. Security Hub RDS.1 rates a public snapshot as Critical. - Encrypted sharing: the recipient also needs access to your customer managed key, and must copy the shared encrypted snapshot before restoring.
- Review: list sharing with
describe-db-snapshot-attributesand alert onModifyDBSnapshotAttributeand its cluster equivalent in CloudTrail.
Use cross-account sharing for backup isolation deliberately: share to a dedicated backup account with its own key, rather than to developer or partner accounts. See the Backup Identity Isolation Guide.
Logging and detection
| Source | What it shows | Alert on |
|---|---|---|
| CloudTrail (control plane) | All RDS API calls | ModifyDBSnapshotAttribute, snapshot copy to unknown accounts, master password changes, disabling managed passwords, DeleteDBInstance, deletion protection off, PubliclyAccessible true |
| Engine logs exported to CloudWatch Logs | Connections, errors, audit events (PostgreSQL logs, MySQL and MariaDB audit plugin, Aurora MySQL audit) | Failed logins, master user logins outside break-glass, logins from unexpected hosts |
| Secrets Manager events in CloudTrail | GetSecretValue on database secrets | Retrieval by principals other than the owning workload |
| Security Hub RDS controls | Configuration posture | New failures on RDS.1, RDS.2, RDS.3 or RDS.10 |
| GuardDuty RDS Protection (Aurora and supported engines) | Anomalous login activity | Findings for suspicious or brute-force logins |
Because IAM database authentication is not logged by CloudTrail, enable engine connection logging (Security Hub RDS.9, RDS.34, RDS.36, RDS.37 and RDS.45 cover log publishing and audit logging) so you can answer "who connected" during an incident.
Metrics
- Percentage of instances and clusters with RDS-managed master passwords.
- Number of public or externally shared snapshots (target: zero public, every external share documented).
- Percentage of databases encrypted with customer managed keys.
- Percentage of application connections using IAM authentication or rotated secrets.
- Age of the oldest application database password.
Hardening baseline
- Inventory: list instances and clusters, encryption state and key, public accessibility, master user management, snapshots and their sharing attributes. Enable Security Hub RDS controls and assess against the CIS AWS Database Services Benchmark (v2.0.0).
- Close public exposure: remove public snapshot sharing immediately, set
PubliclyAccessibleto false (RDS.2), and restrict security groups to application subnets. - Adopt managed master passwords: modify existing instances to
--manage-master-user-password, update anything that used the old password, then add the SCP deny for new databases. Test on a non-production instance first; roll back by turning management off, which restores the ability to set a password yourself. - Move applications off static passwords: IAM authentication or rotated Secrets Manager credentials per application, introduced service by service.
- Fix encryption: new databases encrypted with customer managed keys by policy; migrate unencrypted ones via encrypted snapshot copy during a maintenance window.
- Protect against deletion: deletion protection, automated backups (RDS.11) and an AWS Backup plan (RDS.26) with copies in an isolated account.
- Log and alert: engine log export, CloudTrail alerts above and Secrets Manager access monitoring.
Small teams should do steps 2, 3 and 6 first: they remove the most likely catastrophic outcomes for the least effort. Large organisations should enforce encryption, managed passwords and no public snapshots with SCPs and AWS Config, and centralise snapshot sharing through a backup account.
Common misconfigurations
- Public snapshot of an unencrypted database: made public "temporarily" to move data between accounts.
- Snapshot shared with a departed vendor's account: sharing attributes are never reviewed after the project ends.
- Master user used by the application: any SQL injection or leaked config yields full database control.
- Default AWS managed key everywhere: blocks secure cross-account backup and gives no key-level access control.
- Broad
rds-db:connect: a wildcard resource lets any role holding it sign in as any IAM-enabled database user, including administrators. - Rotation that breaks consumers: rotation is enabled but applications cache the old password, so teams disable rotation instead of fixing the consumer.
Framework mapping
| Framework | Reference | RDS control |
|---|---|---|
| NIST SP 800-53 Rev. 5 | IA-5 | Managed master passwords, rotation, IAM tokens |
| NIST SP 800-53 Rev. 5 | AC-6 | Scoped RDS actions, per-application users, rds-db:connect per user |
| NIST SP 800-53 Rev. 5 | SC-28, SC-8 | Encryption at rest with KMS, TLS in transit |
| NIST SP 800-53 Rev. 5 | AU-2, AU-12 | Engine log export, CloudTrail |
| NIST CSF 2.0 | PR.AA-05, PR.DS-01, PR.DS-11 | Least privilege, data at rest protection, backups |
| MITRE ATT&CK | T1537, T1078.004, T1485 | Transfer data to cloud account (snapshot sharing), cloud accounts, data destruction |
Practitioner checklist
- Remove any public snapshot sharing and alert on
ModifyDBSnapshotAttribute. - Enable RDS-managed master passwords and deny new databases without them.
- Restrict
ModifyDBInstance,ModifyDBClusterand delete actions to a small group. - Use IAM authentication or rotated per-application secrets; never the master user in applications.
- Scope
rds-db:connectto specific database users. - Encrypt every database with a customer managed key at creation.
- Require TLS at the engine and in clients.
- Enable deletion protection, automated backups and isolated backup copies.
- Export engine connection and audit logs, since IAM authentication is not in CloudTrail.
- Track Security Hub RDS controls and the CIS AWS Database Services Benchmark.
Standards and references
- AWS: IAM database authentication for MariaDB, MySQL and PostgreSQL
- AWS: Password management with Amazon RDS and AWS Secrets Manager
- AWS: Password management with Amazon Aurora and AWS Secrets Manager
- AWS: Sharing a DB snapshot for Amazon RDS
- AWS: Encrypting Amazon RDS resources
- AWS: RDS Proxy concepts and terminology
- AWS: Security Hub controls for Amazon RDS
- CIS: Amazon Web Services Benchmarks
Related NHI Mgmt Group resources: Database Credential and Access Security Guide · Database Security Guide · Cloud Secrets Managers Guide · AWS Security Guide · Amazon Redshift Security Guide