Back to blog
Access ControlsDrift DetectionSOC 2

Access Control Drift: What It Is, Why It Happens, and How to Catch It Before Your Auditor Does

By Andre Ferreira·
Abstract network node drifting outside policy-compliant boundary

Access control drift is one of the more common and less discussed failure modes in SaaS security programs. It's the slow accumulation of access grants that were legitimate at one point but shouldn't exist anymore — orphaned accounts, over-provisioned roles, stale service account credentials, forgotten administrative grants in systems that only briefly fell within a project's scope.

The reason it's less discussed is that it's hard to see. Unlike an active breach or a configuration change with immediate symptoms, access control drift is passive. Nothing breaks. No alarm fires. The access just persists, quietly, until someone looks for it specifically — or until an auditor does.

How drift happens in practice

Most access control drift follows one of a few predictable patterns.

The most common is offboarding lag — a user leaves the company, their primary identity provider account is deactivated, but accounts in secondary systems that weren't in the offboarding checklist persist. A typical mid-market SaaS company has 15 to 25 systems with some form of user access. A well-run offboarding process covers the critical ones: Okta, GitHub, AWS (if the user had direct IAM access), Jira, and the production application admin panel. But the staging environment's separate AWS account, the Snowflake workspace provisioned for a data analysis project six months ago, the PagerDuty team set up during an on-call rotation experiment — these don't always make the checklist, and access persists.

The second pattern is project-scope creep. A developer needs temporary admin access to a specific AWS account to debug a production issue. The access is granted. The issue is resolved. The access is not revoked. Six months later, the user still has admin privileges in that account, which has since grown to contain production customer data. The original grant was justified; the persistence is drift.

The third pattern is role accumulation. Enterprise SaaS platforms, identity providers, and cloud environments often allow role assignments to stack additively. A user starts in a read-only role, is temporarily elevated to read-write for a project, has an admin role attached for a specific task, and ends up with a privilege set significantly above what their current job function requires. Nobody removed the old roles when the new ones were added.

Why SOC 2 auditors care

CC6.1 and CC6.3 of the SOC 2 Trust Service Criteria are directly implicated by access control drift. CC6.1 requires that logical access is restricted to authorized users with appropriate justification. CC6.3 requires that access is removed when it's no longer needed. Both criteria assume an active access review process — not a one-time setup, but an ongoing program that regularly reconciles actual access grants against the authorization baseline.

During a SOC 2 Type II audit, the typical evidence request for access controls includes a current user access list for each in-scope system and evidence of periodic access reviews — usually quarterly or semi-annual reviews where a responsible owner attests that each user's access is still appropriate. The failure mode that surfaces during audit isn't usually the stale access itself — it's the absence of a documented review that would have caught it.

More specifically: if an auditor pulls your GitHub organization membership and finds a user account belonging to someone who left the company eight months ago, the finding isn't just "stale access." It's evidence that your access review process didn't catch the gap, which suggests either the process didn't run, or it ran but didn't cover this system, or it ran and caught it but remediation didn't happen. Each is a different control failure with a different root cause.

The detection problem

Detecting access control drift is harder than it sounds because it requires cross-referencing multiple systems with different data models, different authentication systems, and no native integration with each other.

Consider the scenario: you want to know whether every current GitHub organization member is an active employee. To answer this, you need the GitHub organization member list (accessible via GitHub API), the current active employee list (from your identity provider or HR system), and a mapping between GitHub usernames and employee identities — which isn't always automatic when GitHub accounts predate your Okta integration and use personal email addresses.

Running this check manually is a multi-step process involving API calls, data exports, and spreadsheet comparisons. It takes time. Because it takes time, it runs infrequently — typically as part of quarterly access reviews or pre-audit evidence collection. That means a user could have active GitHub access for three months after leaving the company before the check runs and catches it.

The same cross-system reconciliation problem exists for AWS IAM (cross-referencing role assignments against the employee directory), for Okta application access (cross-referencing app assignments against current job function requirements), and for data platform access like Snowflake or Databricks where warehouse-level role assignments can diverge from the identity provider's picture of appropriate access.

A practical scenario

Here's a realistic scenario common across growing SaaS companies. An engineering team expands quickly over 18 months. Onboarding is mostly handled through Okta group membership, which provisions access to the primary tool set. But AWS account access for a secondary production account — one that hosts batch processing infrastructure, not the primary API — is provisioned manually by the DevOps team, not through Okta.

Over 18 months, six engineers join and leave the company. All six are properly offboarded in Okta. But the secondary AWS account doesn't appear in the offboarding checklist — it was set up before the current offboarding process was documented, and nobody added it. Four of the six former employees still have IAM users in that account. The account contains production batch jobs processing customer transaction data.

This isn't detected in access reviews because the quarterly access review is based on an Okta application list, and the secondary AWS account doesn't appear in Okta's application catalog. It's discovered during a pre-audit evidence collection exercise when the compliance team does a manual inventory of all AWS accounts in scope and pulls IAM user lists from each one.

The finding is not catastrophic — the IAM users have limited permissions and there's no evidence of unauthorized access — but it produces an audit finding requiring a management response, a remediation action, and documentation of process improvements. It's exactly the kind of gap that systematic drift detection catches in near-real time rather than in a pre-audit scramble.

What effective drift detection requires

Effective access control drift detection requires three things working together: continuous data collection from each access-granting system, a defined authorization baseline to compare against, and a detection mechanism that flags deviations rather than just surfacing raw data.

The authorization baseline is often the hardest part to define. For user accounts, the baseline is typically: every user account in every in-scope system should correspond to an active employee or an authorized service account, and the access level should match the user's current role. For service accounts, the baseline is: every service account should have a documented owner, a defined purpose, and a least-privilege scope. Drift is any departure from this baseline — not just departures you already know about.

The continuous collection requirement is why point-in-time access reviews, while necessary, aren't sufficient for effective drift detection. A quarterly access review creates a 90-day detection window — drift occurring the day after a review won't be caught until the next one. For organizations where production access includes admin privileges over systems processing customer data, a 90-day detection window is a material risk exposure.

Drift detection is not a criticism of your access control process

We want to be clear: the presence of access control drift in your environment is not evidence of a poorly run security program. In environments with more than 20 to 30 people and more than 10 integrated systems, some degree of drift is almost inevitable without automated detection. Organizations with zero drift findings in their access review programs are almost always smaller, or are running automated reconciliation tools — not organizations with unusually disciplined manual processes.

The goal of an access control program is not to prevent drift entirely. It's to detect and remediate drift within a window short enough that risk exposure is acceptable, and to document that process in a way that supports your SOC 2 evidence record. Quarterly access reviews with manual remediation tracking and evidence of prompt closure is a reasonable baseline. Continuous drift detection with near-real-time alerting is a stronger one — and it eliminates the audit surprise problem entirely.

Ready to stop collecting evidence?

See how Tenurex continuously validates your controls instead of waiting for the next audit.

Request Access