This is the final post in our 3-part series on revamping our cloud IAM. Be sure to check out Part 1 and Part 2 if you haven't already.
In Part 2, we walked through the detailed, 4-phase implementation of our Just-in-Time access model.
The Flaw
During our implementation, we found an obvious security flaw. Our initial IAM roles in all member accounts had a trust policy that allowed any principal within the landing account to assume them.
The Original Trust Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
This configuration meant that if any user or service within the landing account were compromised, the attacker could pivot and assume these privileged roles.
We fixed this by updating the policy to be highly specific, using a Condition
to ensure that the role could only be assumed by a specific, AWS SSO-generated role.
The Improved Trust Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"ArnEquals": {
"aws:PrincipalArn": "arn:aws:iam::123456789012:role/aws-reserved/sso.amazonaws.com/ap-southeast-1/AWSReservedSSO_SecurityTeam_1a2b3c4d5e7f8a9b"
}
}
}
]
}
This aws:PrincipalArn
is the specific SSO IAM role that links back to our IAM Identity Center permission set, ensuring only the right employee coming from the right team can access the role.
Lessons Learnt
A technical solution is only half the battle. The real challenge is making security an enabler, not a barrier. We learned two major lessons along the way.
Lesson 1: JIT access requires a gentle introduction
- The Problem: When we first rolled out the JIT model, our Dev and Infra teams were confused, leading to a surge in access-related support tickets.
- The Fix: We realized technology alone wasn't enough. We implemented company-wide training sessions, created detailed architecture diagrams and documentation, and set up Slack notifications for faster access approvals. This transformed the process from a point of friction into a streamlined, understandable workflow.
Lesson 2: Least privilege should be a journey, not a decree
- The Problem: We initially took a very strict least privilege approach, locking down roles to the bare minimum permissions. This backfired. Teams constantly hit permission walls, velocity dropped, and the security team was seen as a blocker.
- The Fix: We pivoted to a "trust with monitoring" approach. We started with broader, role-based permissions and implemented continuous governance using IAM Access Analyzer. Now, we regularly monitor and remove unused permissions, delete dormant roles, and track utilization metrics, achieving least privilege without hindering productivity.
Moving Forward
Our journey from permanent access to Just-in-Time IAM wasn't just about implementing new technology. It was about changing how we think about security in a fast-moving startup environment. We eliminated standing privileges, closed critical security gaps, and most importantly, proved that security and velocity aren't opposing forces.
The key insight? Security transformations succeed when you treat them as change initiatives, not just technical projects. Start with the people, iterate on the permissions, and let monitoring guide you toward true least privilege over time.
If you're considering a similar shift in your organization, remember that perfection is the enemy of progress. Ship something functional, gather feedback, and refine continuously. Your security will strengthen, and you'll build something no compliance framework can measure: a culture where security and velocity aren't trade-offs.
Top comments (1)
From Permanent Access to Just-in-Time: A Startup's IAM Journey