How to Set Up Secure Cross-Account AWS DBA Access Using IAM Roles (Step-by-Step)
Managing databases in AWS often requires DBAs to access customer environments securely—without sharing passwords, long-lived keys, or granting excessive permissions. A common and recommended approach is to use AWS IAM roles with cross-account role assumption.
This guide walks through a practical, secure setup for a DBA team to access a client’s AWS environment (for example, to manage Amazon RDS MySQL and a jump host) using:
- IAM users (or SSO users)
- A source “DBA access” role in your AWS account
- A target role in the client AWS account
- AWS Console role switching and AWS CLI role assumption
- Least-privilege permissions and troubleshooting tips
Why use AssumeRole for DBA access?
Instead of giving DBAs direct permanent access into a client account, AWS lets you assume a role in another account. This means:
- Access is temporary (STS tokens)
- Permissions are limited to the target role
- The client controls what the DBA role can do
- All actions are auditable (via CloudTrail)
- No need to share root or static privileged credentials
This is especially useful for:
- Amazon RDS administration
- Jump host access (via SSM or SSH)
- Performance monitoring
- Log and metrics investigation
Example Architecture (Generic)
Source account (your organization)
- AWS Account ID:
111122223333 - IAM user:
dba.engineer - Source role:
Org-DBA-Access
Target account (client / production)
- AWS Account ID:
444455556666 - Target role:
client.dba - Region:
ap-southeast-2
Access flow
- DBA signs in as
dba.engineer - DBA switches to
Org-DBA-Access(same account) - DBA assumes
client.dbain client account - DBA accesses RDS / logs / jump host with least privilege
Step 1 — Create or Confirm the DBA IAM User
If using IAM users (instead of AWS Identity Center / SSO), create the DBA user first.
AWS CLI
aws iam create-user --user-name dba.engineer --profile admin
(Optional) Enable console login
aws iam create-login-profile \
--user-name dba.engineer \
--password "Temp#Password!2026" \
--password-reset-required \
--profile admin
Tip: If the login profile already exists, use
update-login-profileinstead.
Step 2 — Allow the DBA User to Change Their Own Password
A common issue is being forced to reset a password in the console but not having permission to change it.
Attach the AWS-managed policy:
aws iam attach-user-policy \
--user-name dba.engineer \
--policy-arn arn:aws:iam::aws:policy/IAMUserChangePassword \
--profile admin
This avoids “You may not be authorized to perform this action” errors on the password reset screen.
Step 3 — Create the Source Role in Your AWS Account
This is the role your DBAs will switch to before entering the client account.
Role name
Org-DBA-Access
Trust policy (trust the DBA IAM user)
Create a trust policy file (example trust-org-dba-access.json):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowDBAUserToAssume",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:user/dba.engineer"
},
"Action": "sts:AssumeRole"
}
]
}
Create the role:
aws iam create-role \
--role-name Org-DBA-Access \
--assume-role-policy-document file://trust-org-dba-access.json \
--profile admin
Step 4 — Grant the IAM User Permission to Assume the Source Role
This is the caller-side permission many teams forget.
Create an inline policy (example allow-assume-org-dba-role.json):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111122223333:role/Org-DBA-Access"
}
]
}
Attach to the IAM user:
aws iam put-user-policy \
--user-name dba.engineer \
--policy-name AllowAssumeOrgDBARole \
--policy-document file://allow-assume-org-dba-role.json \
--profile admin
Step 5 — Configure the Source Role to Assume the Client Role
Your source role (Org-DBA-Access) needs permission to assume the role in the client account (client.dba).
Create policy file (example allow-assume-client-role.json):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AssumeClientDBARole",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::444455556666:role/client.dba"
}
]
}
Attach to the source role:
aws iam put-role-policy \
--role-name Org-DBA-Access \
--policy-name AllowAssumeClientDBARole \
--policy-document file://allow-assume-client-role.json \
--profile admin
Step 6 — What the Client Must Configure (Target Role Trust)
The client creates role client.dba in their account and sets a trust policy that trusts your source role.
Client-side trust policy (example)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TrustExternalDBARole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/Org-DBA-Access"
},
"Action": "sts:AssumeRole"
}
]
}
Optionally, the client can add conditions later (External ID, session naming rules, IP allowlist). For initial testing, many teams keep it simple.
Step 7 — Test Access in the AWS Console (Role Switching)
A) Sign in as the DBA IAM user
Use the IAM sign-in URL:
https://111122223333.signin.aws.amazon.com/console
Sign in as:
- Username:
dba.engineer
B) Switch to the source role
In the AWS Console:
- Click the account/user menu (top right)
- Click Switch role
- Enter:
- Account ID:
111122223333 - Role name:
Org-DBA-Access
- Account ID:
C) Switch to the client role
After switching to Org-DBA-Access, switch role again:
- Account ID:
444455556666 - Role name:
client.dba
Set the region to:
- Asia Pacific (Sydney) /
ap-southeast-2
If successful, you are now operating in the client’s account using the client-provided DBA permissions.
Step 8 — Test Access with AWS CLI (Recommended)
CLI gives clearer error messages than the console and is excellent for troubleshooting.
1) Verify your base profile
aws sts get-caller-identity --profile admin
2) Assume your source role
aws sts assume-role \
--role-arn arn:aws:iam::111122223333:role/Org-DBA-Access \
--role-session-name DBA-Test \
--profile admin
Export the returned temporary credentials (shell-specific) and verify:
aws sts get-caller-identity
Expected ARN format:
arn:aws:sts::111122223333:assumed-role/Org-DBA-Access/DBA-Test
3) Assume the client role
aws sts assume-role \
--role-arn arn:aws:iam::444455556666:role/client.dba \
--role-session-name DBA-Prod-Test
Export the new temporary credentials and verify:
aws sts get-caller-identity
Expected:
- Account:
444455556666 - ARN contains
assumed-role/client.dba/...
Step 9 — Verify RDS / Logs / Metrics Access
Once inside the client role, test a few read operations:
RDS
aws rds describe-db-instances --region ap-southeast-2
CloudWatch metrics / alarms
aws cloudwatch describe-alarms --region ap-southeast-2
CloudWatch Logs (if RDS logs are exported)
aws logs describe-log-groups --region ap-southeast-2
Performance Insights (if enabled)
Use the AWS Console or PI APIs (permissions required).
Recommended Least-Privilege Policy for External DBA Access (Client Side)
A client-provided role for DBAs should usually include:
RDS (read + limited operations)
rds:Describe*rds:ListTagsForResourcerds:ModifyDBInstance(if agreed)rds:RebootDBInstancerds:CreateDBSnapshotrds:CopyDBSnapshotrds:RestoreDBInstanceFromDBSnapshotrds:DescribeDBLogFilesrds:DownloadDBLogFilePortion
CloudWatch / Logs (read)
cloudwatch:GetMetricDatacloudwatch:GetMetricStatisticscloudwatch:ListMetricscloudwatch:DescribeAlarmslogs:DescribeLogGroupslogs:DescribeLogStreamslogs:GetLogEventslogs:FilterLogEvents
Performance Insights (read)
pi:GetResourceMetricspi:DescribeDimensionKeyspi:GetDimensionKeyDetails
Scope permissions to specific DB instance ARNs, snapshots, and regions whenever possible.
Common Problems and How to Fix Them
1) “Invalid information in one or more fields” when switching roles (Console)
Usually caused by:
- Missing
sts:AssumeRoleon the IAM user or source role - Trust policy on the target role doesn’t trust your source role
- MFA condition exists but user is not authenticated with MFA
- Wrong account ID or role name
2) AccessDenied on sts:AssumeRole
Check both sides:
- Caller-side policy (does the current identity have
sts:AssumeRole?) - Role trust policy (does the role trust the caller?)
3) CLI works with --profile myprofile, but not without profile
Your default profile or environment variables are likely invalid. Check:
aws configure list
And clear conflicting environment variables if needed.
4) Password reset fails in console
Often due to:
- Missing
iam:ChangePassword - Password policy requirements not met
- Expired/invalid login profile
Security Best Practices for DBA Access
- Use roles + STS instead of long-lived access keys wherever possible
- Enforce MFA for IAM users and/or source role assumption
- Use per-engineer session names (e.g.,
DBA-Name-Ticket123) - Keep least privilege on the client role
- Use CloudTrail and session naming for auditability
- Consider SSM Session Manager instead of direct SSH for jump hosts
Final Thoughts
A role-based cross-account access model is one of the safest and most scalable ways to provide external DBA services in AWS. It gives clients confidence that access is controlled and auditable, while giving DBA teams a clean operational workflow for managing RDS, logs, performance, and infrastructure.
Start simple (trust + assume-role + basic read access), test the path end-to-end, and then tighten with conditions like MFA, session naming, and resource scoping.
If you’re implementing this for Amazon RDS MySQL DBA operations, this pattern works especially well for:
- Database administration and troubleshooting
- Log and metric analysis
- Snapshot/restore workflows
- Secure jump-host access via SSM

