Ask anyone who has run a quarterly access review how many entitlements were revoked. The honest answer is usually close to none.
Not because the access was correct. Because the reviewer got a spreadsheet with four hundred rows of role names, no context and a deadline, and approving all of it was the only option that fit in an afternoon.
The review was not the control. It was the paperwork proving a control existed.
Three design problems, none of them about people
The reviewer cannot tell what a role does. SF_ADMIN_PROFILE_2 means nothing to the manager being asked to approve it. They know their team. They do not know your Salesforce configuration.
There is no consequence to approving. Revoking might break someone's week. Approving costs nothing that anybody will trace back. The incentives point one way.
It arrives all at once. Four hundred rows in one sitting is a data-entry task, and people do data entry the fast way.
A CSV per app, pasted into a sheet, sent to managers, and approved wholesale because reading it properly takes a day.
The fortnight before the audit, spent screenshotting admin consoles to prove something that was true three weeks ago.
Because nothing was watching between one review and the next.
Change what a reviewer is looking at

A SOC 2 review of one app. Two rows are flagged because the employee is Inactive in HR and still holds access, and three of the rows are not people.
That is one app inside a SOC 2 campaign. A few things in it are the whole argument.
Employment status sits next to access. Two rows are flagged because the person is Inactive in HR and still holds access in the app. That is not a finding you go looking for, it is a column, and it is the single most valuable thing a review can surface.
Non-human identities are in the same list. cc_github and the MCP token are reviewed alongside the people, because they hold access like people and are usually the oldest grants in the estate. Splitting them into a separate exercise is how they end up never reviewed.
The decision is on the row. Approve or revoke, there, in the review. Not a note for somebody to action later.
Say what the role can do, not what it is called
The reviewer does not see SF_ADMIN_PROFILE_2. They see that this person can export the full customer list, edit pricing, and delete records owned by others.
That is the same entitlement described in terms someone can decide about. It is also the description that makes an over-broad grant obvious, which a role name is specifically good at hiding.
Show what was used
Every row carries whether the access has been exercised, and when.
Somebody has held NetSuite for eleven months and opened it twice, both in their first fortnight. That single fact drives more revocations than any amount of policy, because it turns an abstract risk question into a concrete one.
Cut the batch down
Anything the system can decide, it decides before the review starts. Access matching policy exactly, granted this cycle, used regularly, does not need a human.
What is left is the residue: unusual, unused or unexplained. Typically a tenth of the original list, and every row is there for a reason the reviewer can see.
Ninety days is a long time to not be looking
A review is periodic by nature, and everything between two of them is unwatched. An entitlement granted the day after a cycle closes sits unexamined for eighty-nine days, and the review that eventually sees it is looking at something three months stale.
That is the structural limit of certification as a control. It is a snapshot, and the thing it governs is a film.
So the review is not where most of the work should happen. It is the attestation on top of work that has already been done.
What runs in between
Every connected app is read every two hours: who has an account, what each account can do, when it was last used. That is a read of the app itself rather than an assumption from what Iden last provisioned, which matters because the two drift, and the drift is where the findings are.
Those reads are correlated against the systems that hold the truth about people. The HRIS says who is employed, in what department, and whether they left. The IdP says who can authenticate and which groups they are in. Access without a matching employment record is a different finding from access without a matching group, and you can only tell them apart if you are reading all three.
Then the analysis, which is looking for a small number of specific shapes:
Orphaned accounts. Terminated in the identity source, still holding accounts in apps. This is the offboarding that did not finish, and it is usually the largest category on a first scan.
Overprovisioned accounts. More access than the role accounts for, whether by accumulation across role changes or by a grant nobody removed.
Third-party accounts. External people holding access, which tend to be the least reviewed because they belong to no manager's team.
Zombie accounts. Live credentials nobody has used in months.
New privileged accounts. Somebody gained admin since the last scan. Worth knowing within hours rather than at the next quarter.
Separation of duties violations. Per app, per rule, because the combination that matters in Salesforce is not the one that matters in NetSuite.
Findings arrive as an inbox

Findings as an inbox. Categories and counts on the left, the queue on the right, and two categories already at zero. Angelina was offboarded three days ago and still holds six apps.
The design goal is inbox zero, and that is a deliberate choice rather than a metaphor. A dashboard shows you a number and asks you to feel something about it. An inbox gives you a queue with an end, and the end is reachable.
Categories sit on the left with their counts, the queue on the right, and two of the categories in that screenshot are already at zero, which is the state the whole thing is pointed at.
Two details in it are the actual design.
Age is on every row, and the recent ones are marked. Angelina was offboarded three days ago and still holds six apps. Manoj was offboarded eight months ago. Those are different problems: the first is a process that just failed, the second is inherited. Ranking by count alone buries the one that happened yesterday under twenty-five that came with the estate.
Nothing here blames you for what you inherited. Findings that existed when Iden first connected are marked as such and kept out of the open count. A tool that opens by telling an admin they have three hundred failures they did not create is a tool they stop opening.
Closing a finding does not always mean fixing it
Three ways to clear something, and only one of them is removal.
Fixed at source. The access is gone, and where it came from is gone with it, so the finding does not come back next scan.
Excepted, with an expiry. This access is correct and here is who says so and until when. A named exception with a date is a governance artefact. An ignored finding is not.
Reviewed. Somebody looked, decided, and recorded the decision. Often an admin cannot remove access because a business owner says no, and the honest thing is to credit the decision rather than pretend the queue is a to-do list of things they control.
That is what makes inbox zero achievable rather than aspirational. If the only way to clear a row were to delete something, the queue would never empty and nobody would try.
What this changes about the review
The quarterly cycle stays, because most frameworks want a named person attesting on a schedule and continuous checks do not satisfy that.
What changes is what arrives in it. A reviewer opening a campaign that continuous checks have already cleaned sees judgement calls at a volume they can actually read, rather than four hundred rows of which three hundred and ninety are obviously fine.
Which is the only reliable way to make an attestation mean anything.
The audit artefact is a byproduct, not a project
Every review records the scope, who reviewed what, what they decided, when, what was revoked, and confirmation it was actually removed. Every continuous finding records what triggered it, how it was resolved, and by whom.
Mapped to SOC 2 CC6.1 through CC6.3 and ISO 27001 A.9, exportable per control.
Which turns the fortnight before an audit into a query. Not because the auditor asks for less, but because the answer already exists.
What actually changes
What this does not do
It does not decide for the reviewer. It makes the decision cheap and informed, and a manager who wants to approve everything still can. What changes is that the record shows they did.
It does not cover an app that is not connected. A review is only as complete as the connectors behind it, which is why coverage and governance are the same problem wearing two names.
And it does not remove the periodic cycle. Most frameworks want a named person attesting on a schedule, and continuous checks do not satisfy that on their own. They make the cycle small, which is a different and better outcome than making it disappear.