Identity Governance Is Not Optional Anymore
If your organization is pursuing SOC 2 or ISO 27001 certification -- or if you already hold them and need to maintain compliance -- identity governance is not a nice-to-have. It's one of the areas auditors scrutinize most heavily, and it's one where organizations most commonly fail.
Identity Governance and Administration (IGA) is the discipline of ensuring that the right people have the right access to the right resources for the right reasons -- and that you can prove it. This sounds straightforward until you try to implement it across a hybrid environment with hundreds of applications, thousands of users, and constantly shifting roles.This guide covers how to build an IGA framework that satisfies both SOC 2 and ISO 27001 requirements, with practical advice on the controls that matter most.
The Joiner-Mover-Leaver Model
Every IGA framework starts with the Joiner-Mover-Leaver (JML) model. This is the foundation of identity lifecycle management:
Joiner: When Someone Arrives
When a new employee, contractor, or partner joins, they need access to systems and data. The governance questions are:
- What access should they receive automatically? This is "birthright" provisioning -- access granted based on role, department, and location. Defined through RBAC role models.
- How is provisioning executed? Ideally through automated user provisioning via SCIM or API integrations. Manual provisioning is slow, error-prone, and un-auditable.
- How is the identity verified? The joiner process must include identity proofing, especially for remote workers.
# Example: Birthright access policy for Engineering role
role: software-engineer
department: engineering
birthright_access:
- application: github-enterprise
role: developer
provisioning: scim
- application: jira
role: contributor
provisioning: scim
- application: slack
role: member
provisioning: scim
- application: aws-dev
role: developer-readonly
provisioning: api
requires_approval: false
- application: aws-prod
role: none # Must be requested separately
requires_approval: true
approvers: [manager, security-team]
Mover: When Someone Changes Roles
Movers are where access creep happens. When an employee transfers from Engineering to Product Management, they should lose their engineering access and gain product access. In practice, most organizations only add new access -- they never remove the old access. Over time, users accumulate far more access than they need, violating least privilege.
The fix: Automated role-change triggers connected to your HR system. When a role change is detected, the system:- Removes access no longer associated with the new role
- Provisions birthright access for the new role
- Triggers an access review for any non-birthright (manually requested) access
Leaver: When Someone Departs
Deprovisioning is the most time-sensitive lifecycle event. When someone leaves the organization:- All access must be revoked immediately (within minutes, not days)
- Active sessions must be terminated
- Shared credentials the user had access to must be rotated
- The deprovisioning must be logged and auditable
Access Reviews: The Core of Governance
Access reviews (also called access certifications) are periodic audits where access owners verify that current access assignments are still appropriate. This is a direct requirement of both SOC 2 and ISO 27001.How to Structure Access Reviews
Frequency:- Privileged access: Quarterly (or more frequently for highly sensitive systems)
- Standard access: Semi-annually
- Service accounts and machine identities: Quarterly
- Manager reviews: The user's direct manager certifies the user's access is appropriate for their role
- Application owner reviews: The application or resource owner certifies that all users with access should have it
- Entitlement owner reviews: For fine-grained permissions, the entitlement owner reviews who has specific roles or permissions
- System generates a review campaign with all current access assignments
- Reviewers approve, revoke, or flag each assignment
- Revocations are executed automatically (or queued for manual execution with SLA)
- Results are documented and stored for audit evidence
Common Access Review Failures
- Rubber-stamping: Reviewers approve everything without actually reviewing. Combat this with micro-certifications (smaller, more frequent reviews), risk-based prioritization (highlight anomalous access), and management oversight of review completion quality.
- Incomplete scope: Reviews only cover some applications. Ensure your review campaign covers all in-scope systems.
- No remediation: Reviews identify excessive access but nothing is revoked. Tie review outcomes to automated deprovisioning.
Segregation of Duties (SoD)
Separation of duties prevents a single user from having conflicting access that could enable fraud or errors. Classic examples:- A user should not be able to both create and approve purchase orders
- A user should not have both developer and production admin access
- A user should not be able to both create and approve their own access requests
Implementing SoD Controls
# Example: SoD policy engine
SOD_CONFLICTS = [
{
"name": "PO Creation + Approval",
"role_a": "purchase_order_creator",
"role_b": "purchase_order_approver",
"severity": "high",
"action": "prevent", # or "alert" for detective control
},
{
"name": "Dev + Prod Admin",
"role_a": "developer",
"role_b": "production_admin",
"severity": "high",
"action": "prevent",
},
{
"name": "User Admin + Auditor",
"role_a": "user_administrator",
"role_b": "audit_reviewer",
"severity": "medium",
"action": "alert", # Allow but flag for review
},
]
def check_sod_violations(user_id: str, requested_role: str) -> list:
"""Check if granting a role would create an SoD conflict."""
current_roles = get_user_roles(user_id)
violations = []
for conflict in SOD_CONFLICTS:
if requested_role == conflict["role_a"] and conflict["role_b"] in current_roles:
violations.append(conflict)
elif requested_role == conflict["role_b"] and conflict["role_a"] in current_roles:
violations.append(conflict)
return violations
def process_access_request(user_id: str, requested_role: str) -> dict:
violations = check_sod_violations(user_id, requested_role)
if not violations:
return {"status": "approved", "violations": []}
preventive = [v for v in violations if v["action"] == "prevent"]
detective = [v for v in violations if v["action"] == "alert"]
if preventive:
return {
"status": "denied",
"reason": "SoD conflict detected",
"violations": preventive,
}
if detective:
# Allow but create alert for security team review
create_sod_alert(user_id, requested_role, detective)
return {
"status": "approved_with_alert",
"violations": detective,
}
Mapping to SOC 2 and ISO 27001
Here's the practical mapping between IGA controls and compliance requirements:
Audit Trails: What Auditors Want to See
Both SOC 2 and ISO 27001 auditors will ask for evidence. Here's exactly what you need to produce:
For Every Access Change
Every provisioning, deprovisioning, and access modification event must be logged with:
- Who requested the change
- What access was changed (application, role, entitlement)
- When the change was requested and when it was executed
- Why the change was made (ticket reference, business justification)
- Who approved the change (for non-automated changes)
{
"event_type": "access_granted",
"timestamp": "2026-02-15T14:32:18Z",
"user_id": "emp-12345",
"user_email": "jdoe@example.com",
"target_application": "aws-production",
"target_role": "developer-readonly",
"requested_by": "emp-12345",
"approved_by": "mgr-67890",
"approval_timestamp": "2026-02-15T14:30:05Z",
"provisioning_method": "scim",
"provisioning_status": "success",
"business_justification": "Sprint 42 deployment support - JIRA-4521",
"expiration": "2026-02-22T14:32:18Z",
"sod_check_result": "pass"
}
For Access Reviews
- Complete list of access reviewed in each campaign
- Reviewer actions (approved, revoked, flagged) with timestamps
- Remediation evidence (proof that revocations were executed)
- Exceptions with documented business justification and compensating controls
For SoD Controls
- SoD conflict matrix documenting all defined conflicts
- Logs of conflict detections (both prevented and alerted)
- Exception approvals with risk acceptance documentation
Automation: The Key to Sustainable Governance
Manual identity governance does not scale and does not survive audit. Here's what to automate:
Provisioning and Deprovisioning
Use SCIM (System for Cross-domain Identity Management) to automate user provisioning and deprovisioning across SaaS applications. Most modern SaaS platforms support SCIM 2.0.
For applications that don't support SCIM, build API integrations or use an IGA platform with pre-built connectors.
Access Reviews
Automate the generation, distribution, and remediation of access reviews:
- Auto-generate review campaigns on schedule (no manual kickoff)
- Auto-assign reviewers based on the user's manager and the application owner
- Auto-revoke access for items not reviewed within the SLA
- Auto-close campaigns and archive evidence
SoD Enforcement
Implement separation of duties checks as preventive controls in the access request workflow, not as detective controls after the fact. It's much easier to prevent an SoD violation than to remediate one.
Joiner-Mover-Leaver Triggers
Connect your IGA system to your HR system (Workday, BambooHR, etc.) as the authoritative source for identity lifecycle events:
- New hire record triggers joiner workflow
- Department/role change triggers mover workflow
- Termination record triggers leaver workflow
Building Your RBAC Model
A well-designed RBAC model is the foundation of scalable governance. Tips from real implementations:
- Start with job functions, not applications. Define roles based on what people do, not what tools they use.
- Keep roles coarse. 20-50 roles for a 1000-person organization is reasonable. 500 roles is not -- that's just individual access assignments with a "role" label.
- Use role mining. Analyze existing access patterns to discover natural role clusters. Most IGA platforms include role mining tools.
- Document role ownership. Every role must have a business owner who is accountable for what access it includes.
- Review roles periodically. Roles drift over time as applications and entitlements change. Include role definition review in your governance cadence.
Privileged Access Management
PAM is a subset of IGA that deserves special attention because privileged accounts represent disproportionate risk:- Vault credentials. Store privileged credentials in a secrets manager. No one should know the root password.
- Just-in-time provisioning. Grant privileged access only when needed, with automatic expiration.
- Session recording. Record privileged sessions for forensic analysis.
- Break-glass procedures. Document and monitor emergency access procedures for when normal governance must be bypassed.
Getting Started: A 90-Day Plan
Days 1-30: Assessment- Inventory all applications and their access models
- Map current provisioning and deprovisioning processes
- Identify gaps against SOC 2 CC6.x and ISO 27001 A.9.x controls
- Select an IGA platform (if you don't have one)
- Define your RBAC model (start with 10-20 critical roles)
- Connect your HR system as the authoritative identity source
- Implement automated deprovisioning for your top 10 applications
- Configure your first access review campaign
- Run your first access review cycle
- Implement SoD conflict detection for critical conflicts
- Document policies, procedures, and evidence collection
- Conduct a mock audit with your compliance team