Use this page for any request for cloud, database, bucket, repo or tool access, and for periodic access reviews. Access requests are high volume and low complexity, which makes them a good candidate for automation, as long as a human approves every grant.
Every request must answer five questions
| Question | Example answer |
|---|---|
| Who? | A named person or a service role, never a shared login |
| What resource? | <bucket> read, <database> read-only schema reports |
| What level? | read, write, admin (admin needs a strong reason) |
| Why? | Ticket and business reason |
| Until when? | 30 days, end of project, or permanent with quarterly review |
If any answer is missing, ask once in the ticket and wait.
Prefer groups and roles over direct grants
- Add the person to an existing group or permission set that fits. Do not create a new policy per person.
- For AWS, grant through IAM Identity Center permission sets assigned to groups.
- For databases, grant roles (for example
reports_read) and add users to roles. - Production write and admin access is just-in-time where possible, with automatic expiry.
Write the smallest policy that works
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadReportsBucket",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::<bucket>",
"arn:aws:s3:::<bucket>/reports/*"
]
}
]
}
- No
"Action": "*"and no"Resource": "*"for write actions. - Use conditions where they help:
aws:PrincipalTag,aws:SourceVpc,aws:RequestedRegion. - Check with IAM Access Analyzer policy validation before the MR.
aws --profile <readonly-profile> accessanalyzer validate-policy \
--policy-type IDENTITY_POLICY --policy-document file://policy.json \
--query 'findings[].{type:findingType,issue:issueCode,msg:findingDetails}'
Database access pattern
-- Run by an admin through the approved change process, not by the agent
CREATE ROLE reports_read NOLOGIN;
GRANT CONNECT ON DATABASE <database> TO reports_read;
GRANT USAGE ON SCHEMA reports TO reports_read;
GRANT SELECT ON ALL TABLES IN SCHEMA reports TO reports_read;
ALTER DEFAULT PRIVILEGES IN SCHEMA reports GRANT SELECT ON TABLES TO reports_read;
GRANT reports_read TO <user>;
Prefer IAM database authentication or short-lived credentials from a secret manager over static passwords.
The flow
- Ticket has the five answers and an approver (the resource owner, not the requester's friend).
- Change is an MR to the access-as-code repo (Terraform for IAM, Identity Center assignments, groups).
- Plan shows only the expected grant.
- Approver approves the MR or the ticket; the link goes in the MR.
- Apply, then ask the requester to confirm it works.
- Record the expiry and set a reminder or automated revoke.
Access reviews
- Quarterly: list who has admin or production write, per account and system.
- Flag unused access (IAM last-accessed data, database login history).
- Revoke via MR, with the owner's sign-off.
aws --profile <readonly-profile> iam generate-service-last-accessed-details --arn <role-arn>
aws --profile <readonly-profile> iam get-service-last-accessed-details --job-id <job-id>
Pitfalls
- Granting
AdministratorAccess"temporarily". Temporary grants without an expiry are permanent. - Copying another user's permissions wholesale. Ask what they actually need.
- Long-lived IAM user access keys for people. Use SSO. If keys exist, follow secret rotation to retire them.