The Group Assignment Default
When teams set up AWS IAM Identity Center, the natural approach is group-based assignment:
- Create a group: “Engineering”
- Add engineers to the group.
- Assign the group to accounts with permission sets: Engineering → Production-1 → Developers_Editor.
This means every member of the Engineering group — all 100 engineers — can access Production-1 with Developers_Editor privileges. Always. Whether they need it today or haven’t used it in six months.
Group-based assignment is convenient for administration. One assignment covers 100 people. But it violates a fundamental security principle: access should be as narrow as practically possible. When the group has access, you can’t distinguish between “this engineer actively needs production access right now” and “this engineer was added to the group two years ago and has never used production access.”
The Problem with Group-Level Access
100 People Have Access Because 5 Need It
In a typical engineering team of 100:
- 5 engineers actively work in production on any given day.
- 15 engineers need production access once a week.
- 30 engineers need it once a month.
- 50 engineers rarely need it (maybe once a quarter for an incident).
Group assignment gives all 100 permanent access to cover the 5 who need it daily. The other 95 carry standing privilege they don’t currently need. Each unused assignment is latent blast radius — a credential compromise or account takeover inherits access the user isn’t actively using.
Blast Radius Is Group-Sized
If one engineer’s credentials are compromised (phished, malware, stolen laptop), the attacker gets:
- With group-based access: whatever the group has. If Engineering has Developers_Editor on Production, that’s what the attacker gets.
- With user-based JIT: nothing elevated, unless the engineer happens to have an active JIT session at the moment of compromise.
The blast radius of a compromise isn’t what the user is doing — it’s what the user’s group has permanently assigned. Reducing assignments to the individual level (and time-bounding them) reduces the blast radius from “group scope” to “current session scope or nothing.”
Audit Attribution Is Group-Level
With group-based assignment, CloudTrail shows: “user-xyz assumed the Developers_Editor role on Production-1.” But why did they have that access? “Because they’re in the Engineering group.” That’s not governance — that’s inertia.
With user-based JIT assignment, the audit shows: “user-xyz was assigned Developers_Editor on Production-1 at 10:00 AM, approved by devops-lead for 2 hours, because of INC-2341.” Every assignment has a reason, a time boundary, and an approval chain.
Offboarding Is Incomplete
When an engineer leaves the company, their identity is deprovisioned. But group-based assignments mean you need to verify:
- Which groups were they in?
- Which assignments did those groups provide?
- Are there cached sessions or tokens still active?
With JIT, there’s nothing to offboard beyond the identity itself. The engineer has no standing assignments to remove because all access is temporal — already expired or never granted.
The Better Model: Group Defines Policy, JIT Controls Assignment
The solution isn’t to abandon groups. Groups are the right abstraction for who is eligible for what. The improvement is separating eligibility from actuality:
Group = Eligibility (Policy Boundary)
“Members of the Engineering group are eligible to request Developers_Editor on Production accounts.”
This defines the boundary: engineers can request this access. Non-engineers cannot. The group determines what appears as a requestable option in the JIT interface.
JIT Assignment = Actuality (Temporal State)
“engineer@company.com currently has Developers_Editor on Production-1, granted at 10:00, expiring at 12:00.”
This is the real-time access state. Only one specific engineer has the assignment, for a specific duration, for a specific reason. The 99 other engineers in the group have no Production-1 assignment right now.
The Result: Clean Separation of Concerns
| Concern | Mechanism |
|---|---|
| Who can request what | Group membership → JIT policy |
| Who actually has access right now | Individual JIT assignment |
| When does access expire | JIT duration (hard time limit) |
| Why was access granted | JIT request reason + approval chain |
| Who approved | Group Level Approver |
| How to revoke one user’s access | End their JIT session (doesn’t affect group) |
| How to change eligibility | Modify group membership (doesn’t affect active sessions) |
Practical Comparison
Scenario: Engineer Needs Production Access
Group-based (traditional):
- Engineer is in Engineering group.
- Engineering group is assigned to Production-1 with Developers_Editor.
- Engineer opens SSO portal, sees Production-1, clicks.
- Engineer is working in production. And tomorrow. And next week. And next month.
- Audit: “engineer assumed Developers_Editor on Production-1.” (No approval, no time-bound, no reason.)
User-based (JIT):
- Engineer is in Engineering group (eligibility).
- Engineer requests Developers_Editor on Production-1 for 2 hours via Slack.
- Approver approves (or auto-approval applies for this combination).
- Cloudanix creates individual assignment: this user, this account, this permission set, 2 hours.
- Engineer opens SSO portal, sees Production-1 (just appeared), clicks.
- Two hours later: assignment removed. Production-1 disappears from portal.
- Audit: “engineer requested, devops-lead approved, access granted 10:00-12:00, reason: INC-2341.”
Scenario: Investigating a Security Event
Group-based: “Which engineers had access to Production-1 when the data was exfiltrated at 3 AM?” Answer: “All 100 members of the Engineering group had standing access.” Investigation scope: 100 people.
User-based JIT: “Which engineers had access to Production-1 when the data was exfiltrated at 3 AM?” Answer: “Two engineers had active JIT sessions: engineer-A (2:30-4:30 AM, approved for INC-2341) and engineer-B (2:45-3:15 AM, approved for deployment monitoring).” Investigation scope: 2 people, with full context.
Doesn’t User-Level Assignment Create Admin Overhead?
The obvious concern: “Managing 100 individual assignments is more work than managing 1 group assignment.”
With manual processes, yes — user-level assignment is unsustainable at scale. That’s why group-based assignment became the default: it’s the only model that works with manual administration.
But JIT automates the assignment lifecycle:
- Creation: Automatic on approval (no admin creates the assignment manually).
- Expiry: Automatic at duration end (no admin removes the assignment manually).
- Policy: Configured once (which groups can request which roles on which accounts).
After initial policy configuration, the admin overhead is zero for routine access. The system handles individual assignments automatically, at a scale no human could manage manually.
The admin’s role shifts from “process each access request individually” to “define policies that govern how the system handles requests automatically.”
What About Service Accounts and Non-Human Identities?
For non-human identities (CI/CD pipelines, service accounts, Kubernetes pods), the same principle applies with a different mechanism:
- Traditional: Service account has a permanent IAM role with broad permissions.
- Agentic JIT: Service account (registered as an agent) elevates for the specific step that needs privilege, then revokes.
The assignment is still individual (one agent, one elevation, one duration), not group-based (all CI/CD pipelines sharing one broad role). The blast radius is the 30-second elevation window, not the permanent role.
Implementation Notes
Migration from Group Assignment to User JIT
- Identify high-risk group assignments (production accounts, admin roles).
- Remove group assignments for high-risk combinations.
- Configure JIT policies using the same group membership as the eligibility boundary.
- Test: Engineers can still request the same access, but now it requires a JIT request.
- Verify: SSO portal no longer shows production roles by default. They appear only during active sessions.
Keeping Some Group Assignments
Not every assignment needs JIT. Consider keeping static group assignments for:
- Read-only on development where the blast radius is negligible.
- Infrastructure baseline that engineers need to do their basic job (assuming it’s truly low-risk).
The goal isn’t “no group assignments anywhere” — it’s “no elevated group assignments for sensitive environments.”
The Principle
Least privilege isn’t “the minimum access someone might ever need.” It’s “the minimum access someone needs right now, for this specific task.”
Group-based assignment answers the first definition. User-based JIT answers the second. The difference is blast radius: when a credential is compromised, group-based means the attacker has everything the group has. User-based JIT means the attacker has whatever the user’s active session has — which is usually nothing, because sessions are temporary and most time is spent without elevated access.
Ready to Move from Group Assignment to User-Level JIT?
If your IAM Identity Center assigns permission sets to groups — giving all members standing access whether they need it today or not — Cloudanix JIT converts those group assignments into individual, time-bound, approved sessions while using group membership as the policy boundary. Same groups, same permission sets — but access exists only during active approved work.
Learn more about Cloud Console JIT or book a demo to see how user-level assignment works with your IAM Identity Center groups.