The solution
Ramp grew from under 100 to more than 600 employees while still running backend engineering access on 3 AWS roles: Junior-Engineers, Engineers, and Admins. Every new resource access request meant the infrastructure team hand-editing an IAM policy, which created two chronic problems — senior engineers accumulated persistent production access far broader than their actual work, raising the blast radius of any single mistake or compromised account, while junior engineers had to route routine queries through senior engineers, burning their time.
The team's fix had two layers. First, fine-grained access control: they replaced the 3 roles with 20+ AWS SSO groups, one per engineering team, each defined by a Terraform module (`engineers_X.tf`) listing exactly which CI/CD pipelines, Lambda functions, ECS containers, S3 paths, and secrets that team could touch. This made ownership legible — engineers could read their own team's file to see their access, and request changes via pull request instead of an infrastructure ticket.
Second, just-in-time (JIT) access: for every team role, they created a matching elevated production role with no standing membership. Using ConductorOne (already deployed at Ramp for app provisioning), eligible engineers request a production role; a request for their own team's role auto-approves, a request for another team's role routes to that team's tech lead for approval, and grants expire after a chosen window. They rolled it out to one team first, iterated, then deployed it AWS-wide, and folded the request flow into their existing CLI so engineers didn't have to leave their terminal.
The result tightened the security posture — shrinking the standing-access footprint and tying every production action to a stated justification — while keeping the request-to-access latency under 10 seconds, so the security gain didn't reintroduce the friction the original ticket-based system had.
What it achieved
Make every production role a time-boxed superset engineers must request, not a standing grant
Why it worked
Splitting roles by team before automating access created a natural unit for auto-approval (own team) and routed approval (another team's owner) — JIT needs an ownership map to route requests against.
Making production roles supersets of the non-production team roles meant removing standing access didn't change what engineers could already do day to day — it only added a request step.
Auto-approving same-team requests while routing cross-team requests to a tech lead matched approval friction to actual risk: your own resources are routine, someone else's need a second look.
Embedding the request flow in the CLI engineers already used for deploys and SSH meant adoption didn't depend on remembering to open a separate web app under time pressure.
What can be applied
Fine-grained ownership has to exist before just-in-time access can work — without scoped roles mapped to real team ownership first, there's no sensible unit to grant or auto-approve.
Aftermath
Ramp reported the JIT rollout strengthened its posture for frameworks like SOC 2 and ISO 27001, where auditors look for time-boxed access over standing grants, and reduced audit scope by tying every production action to a stated justification. The team's stated lessons: system ownership had to be settled before the access tool was built, onboarding hundreds of engineers took more effort than building the workflow itself, and picking a vendor suited to their scale early saved rework as headcount kept growing.
FOLLOW THE EVIDENCE