Ask any security leader how many people hold administrator rights in production and you will usually get a number. Ask how they know, and the answer becomes less certain. Admin is granted during migrations, incidents, acquisitions and late-night fixes, and almost never taken away, because removing it carries a risk nobody wants to own: what if something breaks? So it accumulates. The access nobody remembers granting is precisely the access an attacker hopes to find.

This post walks through retiring standing access in the demo organisation, Northwind Labs. Discovery found eight open items, including four standing administrators and one escalation path. We take each one in turn: what it is, how risky it is, and whether to convert it to on-request access, accept it with a reason, or send it to its owner as a proposal.

In short

  • You cannot retire what you have not found. Discovery reads AWS accounts and IAM, PostgreSQL roles and Kubernetes bindings, and lists every always-on privilege with a risk score and a last-used date.
  • Unused and critical are different problems. An administrator unused for 118 days is easy to remove; a deploy role used four hours ago that can escalate its own privileges needs its owner.
  • Three answers per line. Convert to JIT (make it requestable, then remove it), Accept (keep it, with a reason on record) or Proposal (send a drafted change to the owner).
  • The cleanup agent drafts, people decide. It runs at L1 by default: it prepares proposals and a person acts. Every removal goes through the broker in your network.
  • Measure the burn-down. “Standing admins left” is a number on the home page, and it should fall every month.

Why standing privilege is a board-level risk

Standing privilege turns any credential theft into a privileged incident. A phished password or a leaked token on an ordinary account is a nuisance; on an account with AdministratorAccess to the payments environment, it is a reportable breach. The size of the exposure is set not by how many administrators you need, but by how many you have.

Industry
data

Cloud permissions research has found that the large majority of granted permissions go unused, and that privileged identities far outnumber the tasks that need them. Separately, stolen credentials consistently rank among the most common initial access vectors, and IBM’s 2024 report put the global average cost of a breach at around US$4.9 million.

Sources: Microsoft State of Cloud Permissions Risks report (2023); Verizon Data Breach Investigations Report; IBM Cost of a Data Breach Report 2024. Figures vary by study and year.

There is a compliance angle as well. SOC 2, ISO 27001 and PCI DSS all ask, in their own words, that privileged access is restricted to those who need it and reviewed. Auditors increasingly sample the administrator list and ask for the business reason behind each name. “They were added in 2023 for the migration” is not a reason.

Step 1: discovery finds what exists

Discovery runs through the same broker that grants access, inside the customer’s network. For AWS it reads accounts, permission sets and assignments, and the full IAM authorisation details, then analyses them for administrator access, privilege-escalation paths and unused roles. That analysis is shared with InsightFortify, VerticalServe’s cloud security posture product. For PostgreSQL it reads roles and their privileges; for Kubernetes, role bindings.

At Northwind, the standing-access page summarises the result: 8 open items, 4 administrators, 1 escalation path, 2 unused for more than 90 days. The admin home page shows the same headline: 4 standing admins left.

Integrations page: the broker online with its local policy digest and load, and the demo-cloud and payments-db integrations with their discovery results
Where the list comes from. The broker, online in Northwind’s network with its local policy digest, and the integrations it discovers through: demo-cloud and payments-db.

Discovery is read-only. Finding standing access changes nothing in the estate; it only produces the list. That makes it a safe first step for a security team that wants evidence before it asks any owner to give anything up, and it is often the step that settles the internal argument about whether there is a problem at all. Nobody disputes a list with names, dates and permissions on it.

Standing access list: 8 open, 4 administrators, 1 escalation path, 2 unused 90+ days; rows for alex.ops, breakglass-admin, jordan.dev, insight, ci-deployer, priya.sre and legacy-migration with risk, last used and Convert to JIT, Accept and Proposal
The standing-access list at Northwind. Who, where, what, when last used, the risk and why, and three actions on every line.

Step 2: read the list as a risk register

WhoWhereAccessLast usedRiskLikely answer
alex.ops@prod-paymentsAdministratorAccess118 days agoCritical 95Convert to JIT
breakglass-adminprod-coreAdministratorAccess200 days agoCritical 90Convert; replace with the break-glass flow
jordan.dev@eks-prod/paymentsClusterRoleBinding to cluster-admin45 days agoCritical 80Convert to namespace entitlements
insight (service)payments-dbSUPERUSER, BYPASSRLS, CREATEROLENeverCritical 75Proposal to the owner
ci-deployer (role)prod-coreiam:PassRole, lambda:CreateFunction, lambda:InvokeFunction4 hours agoHigh 55Proposal: narrow, keep the pipeline working
priya.sre@prod-paymentsReadOnlyAccess, always on1 day agoMedium 40Convert to JIT (low-risk reads stay automatic)
legacy-migration (role)prod-cores3-allNeverMedium 40Convert; it has no users to break

Read the list from two directions at once. The risk score tells you what an attacker would most like to find. The last-used date tells you what will break if you remove it. A line with a high score and an old date is the best trade you will ever make: maximum risk removed, minimum disruption. alex.ops@ with AdministratorAccess on the payments account, untouched for 118 days, is exactly that.

An eighth item, morgan.lead@ with PowerUserAccess, sits further down the same list and follows the same reasoning.

flowchart TD A["Standing privilege found"] --> B{"Used in the last 90 days?"} B -- No --> C{"A person or a workload?"} C -- Person --> D["Convert to JIT"] C -- Workload --> E["Proposal to owner, then remove"] B -- Yes --> F{"A person or a workload?"} F -- Person --> G["Convert to JIT, make the entitlement requestable first"] F -- Workload --> H{"Can it escalate or is it admin?"} H -- Yes --> I["Proposal: narrow the permission"] H -- No --> J["Accept with reason and review date"]

A triage rule that suits most estates. People get on-request access; workloads get narrower permissions.

Step 3: the three answers, line by line

Convert to JIT is the answer for people. Done properly it is two things in order. First, the access is made requestable: an entitlement exists in the catalogue with a ceiling, an owner and a flow. Then the standing assignment is removed, through the broker. The person loses nothing they need; they gain a request box. For alex.ops@, the AdministratorAccess assignment goes, and admin on prod-payments becomes a request under the two-person flow, #30. For priya.sre@, always-on ReadOnlyAccess becomes reads under flow #10, automatic when the risk is low, so Priya’s day hardly changes.

breakglass-admin is a special case of the same answer. It exists for emergencies, and flow #5, break-glass for whoever is on call, covers emergencies without a standing account. Convert it once that flow has been rehearsed.

jordan.dev@ holds cluster-admin through a ClusterRoleBinding on the production cluster. Converted, that becomes namespace-scoped requests: a RoleBinding per grant, to a role scoped to one namespace, removed at expiry.

Proposal is the answer for workloads and for anything where the owner needs to agree. The ci-deployer role was used four hours ago. It is a deployment pipeline, not a person, and it cannot fill in a request form. But it can escalate its own privileges: with iam:PassRole, lambda:CreateFunction and lambda:InvokeFunction, it can create a Lambda function that runs as a more powerful role and invoke it. The proposal is to narrow it, for example restricting which roles it may pass, and the platform team makes that change in their infrastructure code. Similarly, the insight service login on payments-db holds SUPERUSER, BYPASSRLS and CREATEROLE and has never been used. Before removing a service login, confirm with its owner which application, if any, still depends on it.

Accept is a legitimate answer, not a failure. Some standing access is right: a read-only monitoring role, a narrowly scoped service account. Accepting records who accepted it and why, and standing access stays in scope for the next quarterly access review rather than disappearing.

The cleanup agent at L1: drafts, not deletions

The standing-access cleanup agent looks for standing admin, escalation paths, unused roles and database superusers and proposes converting each to on-request access. By default it runs at L1, “Draft”: it prepares the proposal and a person does the work. At Northwind the home page shows 8 agent proposals waiting across all agents.

Agent settings showing the L1 to L4 autonomy dial for each agent with run statistics, including the standing-access cleanup agent at L1 Draft
The autonomy dial. Each agent has its own level, capped by the deployment ceiling. Cleanup starts at L1: it drafts, people decide.

L1 is the right default for removal. Removing access is the one action in this product most likely to break something, and a person who knows the system should look at each line. As confidence grows, an organisation can move the agent up a level for a narrow class, but nothing forces it to. Every agent action is in the inbox with approve, reject and undo, and in the audit trail.

Whatever the level, the removal itself is done by the broker in Northwind’s network, under a signed instruction, checked against the broker’s local policy. InsightKeys’ servers never hold a credential that can change Northwind’s permissions, including to take them away.

sequenceDiagram participant D as Discovery via broker participant A as Cleanup agent (L1) participant S as Security participant O as Resource owner participant B as Broker participant T as AWS, Postgres or Kubernetes D->>A: Standing admin, escalation paths, unused roles A->>S: Drafted proposal per line with reason S->>O: Agree the conversion O-->>S: Agreed, entitlement and flow in place S->>B: Convert to JIT, signed removal B->>T: Remove standing assignment B-->>S: Removed, recorded Note over S,T: Next discovery confirms the line is closed

One conversion. The agent drafts; security and the owner decide; the broker removes.

A ninety-day standing-access clean-upIllustrative runbook with typical owners
1
Connect discoveryPlatform

Run the broker and connect AWS, PostgreSQL and Kubernetes integrations. Read-only discovery comes first.

2
Agree the risk registerSecurity

Sort by risk; note last used; tag each line person or workload.

3
Build the entitlements people will requestSecurity + owners

Catalogue entries with ceilings, owners and flows, so conversion never leaves someone without a route.

4
Convert the unused firstSecurity

High risk, not used in 90 days: the safest, biggest wins. Removal through the broker.

5
Convert the active peopleSecurity + team leads

Tell them first; show them the request box; convert.

6
Send proposals for workloadsPlatform

Narrow escalation paths and superusers in infrastructure code, with the owner.

7
Accept the rest, with reasonsSecurity

Each acceptance recorded and included in the next quarterly review.

30 days

Find and sort

  • Discovery connected
  • Risk register agreed with owners
  • Unused administrators converted
60 days

Convert people

  • Active human admins converted to on-request
  • Break-glass flow rehearsed; shared account retired
  • First requests flowing
90 days

Narrow workloads

  • Escalation paths narrowed in code
  • Remaining lines accepted with reasons
  • Standing admin count reported monthly

Honest limits

Discovery and analysis report what is granted; treat the risk scores as a starting point for a conversation with each owner, not a verdict. In the demo, the AWS and Kubernetes integrations run on the simulator; the AWS drivers are tested against moto, the AWS API emulator, PostgreSQL against a real database, and Kubernetes against its REST API shape. None has yet been run against a very large production estate. Google Cloud, Azure, Okta and Entra group membership are on the roadmap, so standing access there is out of scope today. Workload identities cannot request access, so for them the answer is narrowing, not just-in-time.

What to report upwards

The board does not need the list. It needs three numbers and their direction: standing administrators in production, identities that can escalate their own privileges, and privileged lines unused for 90 days. At Northwind today those are 4, 1 and 2. A credible programme brings the first two close to zero and keeps the third there, while the share of requests approved automatically shows the business that tighter control did not mean slower work.

The administrator nobody remembers granting is the one an attacker hopes to find.

Find every standing privilege, read it as a risk register, convert the people to on-request access, narrow the workloads, and accept the rest out loud. Then report the number until it stops moving.

Keep reading