Home/Blog/How to Kill Dormant Admin Access Without Breaking Production
Playbooks

How to Kill Dormant Admin Access Without Breaking Production

Dormant admin access is the entitlement nobody defends but nobody removes. It sits in the IdP, unused for six months, until someone leaks a credential or an attacker pivots into the account. Then it is a Sev-0.

Killing it is not hard. Doing it without breaking production is where teams stall. Here is the playbook.

What counts as dormant admin access?

Precision matters. Two thresholds most programs use:

  • Privileged access: 90 days without an authenticated use of the specific entitlement, not just an SSO login. Regulated environments (HIPAA, SOX, PCI) often tighten to 60 days.
  • Standard SaaS access: 60 days without a login or an action. Some programs stretch to 90; anything longer is hard to defend.

Use the source system's audit log for the timestamp, not the IdP's last-login timestamp. Okta shows a user logged into a SAML app; it does not show whether they exercised admin scope inside the app. The distinction matters for AWS, GitHub, Snowflake, and any tool where "logged in" and "used admin" are different events.

Why does dormant access accumulate?

Four causes, in decreasing order of prevalence.

  • Role changes that add permissions but never remove them. A senior engineer becomes a manager, keeps AWS admin, never touches it again. The permission carries forward across every reorg.
  • Break-glass access granted for an incident, never reverted. Someone got admin for a Sev-0 in July. It is still granted in October.
  • Contractor and consultant access that outlives the engagement. The consultant left in Q1. Their GitHub outside-collaborator status did not.
  • Provisioning defaults set too broad. Every new hire in a group gets admin because that was easier than defining the actual permission set.

Every one of these is a provisioning process failure, not a review process failure. But the review is where they get caught.

What is the safe revocation sequence?

Six steps. Follow the order.

  1. Confirm dormancy from the source system's audit log. Not from the IdP. Not from a spreadsheet.
  2. Notify the user and their manager 5 business days ahead. Include the entitlement, the last-used date, and the re-grant path. Most re-grants happen in this window and cost nothing.
  3. Revoke in sandbox and non-production first. For any entitlement that spans environments, remove sandbox before prod. If nothing breaks in sandbox for 48 hours, the prod revocation is lower risk.
  4. Revoke in production during a low-traffic window. For US-centric teams, Wednesday 9pm Pacific is the standard. Not Friday afternoon.
  5. Keep the revocation reversible for 24 hours. Soft-disable rather than hard-delete where possible. Okta group removal is easily reversed; deleting an IAM user is not.
  6. Log the action with before, after, and rollback state. The evidence bundle needs API-level proof, not a screenshot.

The staged sequence is what lets you defend the purge to leadership when something does break.

What is the re-grant path?

Fast, self-service, and logged. Three properties.

  • 15 minutes end-to-end. From "I need this back" to access restored. Anything longer and the team routes around the process.
  • Self-service through a portal or a Slack command. Not a ticket queue. Not an email to IT. The user requests, the approver approves in-thread, the grant executes.
  • Time-bound by default. Re-grants are 30 days, not permanent. If the user still needs the access in 30 days, they re-request, and the pattern shows up in the next dormancy scan.

Programs that skip the re-grant path will not survive the first accidental over-revocation. The re-grant path is the safety net that lets you be aggressive.

Which entitlements need special handling?

Six categories. Each has its own gotcha.

Entitlement type Gotcha Safe handling
AWS root user Cannot be dormant, cannot be MFA-less Move to break-glass process, MFA-required, quarterly rotation
GitHub org owner Rare-use but critical for recovery Keep 2 active owners minimum, rotate quarterly, no dormancy allowed
Domain registrar Rarely used, catastrophic if lost Two humans on record, use dedicated shared vault
Break-glass production DB Standing access defeats the purpose JIT only, alerts on every use, quarterly test of the process
DNS admin Similar to registrar Two humans, MFA required, dormancy allowed but reconfirm quarterly
Payment processor admin Regulatory scrutiny (PCI, SOX) Named owner + backup, no dormancy, SoD with finance

For each of these, dormancy is not a signal to revoke. It is a signal to reconfirm the owner and rotate credentials.

What tickets will you actually get during a purge?

Predictable, in this order.

  • "You revoked my access and I need it for a report." Weekly report, monthly report, quarterly report. Real users of infrequent-but-legitimate access. Re-grant path handles this cleanly.
  • "You revoked my access and now my automation is broken." Automation running under a personal account. This is a bigger problem than the revocation; escalate to service account migration.
  • "You revoked our shared team account." Team was running production on a shared credential. Also a bigger problem; move to per-user auth.
  • "You revoked our contractor's access and they need it back through end of engagement." Contractor's re-grant should be time-bound to end of contract, then auto-expire.

Two of the four "complaints" are actually valuable signals. Automation on personal credentials and shared team accounts are the two dormant-access patterns you most want to catch.

What is the rollback plan?

Documented before the purge starts. Three components.

  • Revocation log with rollback commands. Every revocation logged with the exact API command to reverse it. If you removed a user from an Okta group, the log has the group ID and the user ID for a one-line re-add.
  • 24-hour rollback window. If the revocation causes a production incident inside 24 hours, roll back the entire batch and post-mortem. After 24 hours, individual re-grants are the path forward.
  • Named on-call. One person owns the purge and stays reachable for 48 hours after execution. Not a rotation; a named person.

Programs that skip the rollback plan will do one purge, hit a snag, and then never do another one.

How do you measure whether the purge worked?

Three checks. Post-purge, 7 days out.

  • Dormant privileged rate. Should drop from wherever it was (typically 15 to 30%) to under 5%. Under 3% is the healthy target.
  • Re-grant rate. Percentage of revoked entitlements re-granted within 7 days. Target: under 15%. Above 30%, dormancy threshold was too aggressive.
  • Production incident rate. Incidents attributable to the purge. Target: zero. Any incident is a post-mortem input.

If the re-grant rate is high but the incident rate is zero, the purge worked and the dormancy threshold needs a small adjustment. If the incident rate is non-zero, the staged sequence failed somewhere.

The mistake to avoid

The instinct is to run one big purge, revoke everything dormant in a Friday afternoon, and declare victory. That is how you break production and lose sign-off for the next purge. Instead, run staged: sandbox first, 5-day notice, prod during low-traffic, 24-hour rollback window, self-service re-grant. Do it quarterly. Publish the metric. The first purge is the hardest; by the fourth, dormant admin access is a 2-hour cleanup, not a project.

dormant accessprivileged accessleast privilegeiamrevocation

Frequently asked questions

What counts as dormant?

For privileged access, 90 days without an authenticated action that exercised the entitlement. Just logging into the SSO does not count; the user has to have actually used the permission. For standard SaaS access, 60 days is a defensible baseline. HIPAA and financial services programs sometimes tighten to 45 or 30 days for admin access.

What if the entitlement is for emergency use only?

Emergency access should never be standing. If it is genuinely for emergencies, move it to just-in-time (JIT) elevation with an approval workflow and a break-glass process. Standing emergency access is a contradiction in terms; either it is standing (in which case someone should be using it periodically) or it is emergency (in which case JIT is the right pattern).

How do we detect dormant access on systems without audit logs?

Most systems have audit logs; they are just off by default or expensive to enable. Turn them on. If the system genuinely does not log entitlement use, treat every entitlement as dormant on a rolling window and require reconfirmation quarterly. It is the only defensible fallback.

What is the biggest risk in a dormant-access purge?

Revoking the entitlement someone actually uses infrequently but critically. Mitigate with staged rollout, a 24-hour grace window where the entitlement is soft-disabled but reversible, and a fast re-grant path. If your re-grant path takes 3 business days, you will not get sign-off to run purges.

How often should we run a dormant-access purge?

Quarterly, aligned to the access review cadence. Weekly for orphaned accounts (users with no manager or terminated in the last 30 days). Continuous for terminated users, which should be handled by joiner-mover-leaver automation, not by the review cycle.

Close access reviews in days, not quarters

Orvaron pulls entitlements from every system, routes reviews to the right manager, and executes revocations in the source app so evidence builds itself.

Request early access