Admin & Operations

Org health

Permission set debt: how orgs quietly lose track of who can see what

Nobody plans an access model that takes four people and a spreadsheet to explain. It accumulates one urgent request at a time.

A combination padlock resting on a laptop keyboardAdmin & Operations

Open the permission sets list in an org that has been live for five years. You will typically find somewhere between forty and three hundred entries. A handful are well named. Several are named after a person. At least one is called something like Temp Access - DO NOT DELETE, created by someone who left, and nobody will be the one to test that instruction.

This is permission set debt. It is the most common kind of org debt, and unlike a badly built flow it produces no errors, right up until an audit, a departure, or a data incident.

How it accumulates

Nobody chooses this. It arrives through a sequence that is individually reasonable every time.

Somebody urgently needs access to one field. The fastest safe action is a small, targeted permission set. It works, the person is unblocked, everyone moves on. Six months later somebody else needs almost the same thing plus one object, so a second permission set gets cloned from the first. Now two things must be kept in step, and nothing enforces that.

Multiply by five years and a few staff changes. The result is not a design; it is sediment.

The second contributor is the profile-to-permission-set transition. Many orgs are mid-way through moving permissions off profiles, which means access is now expressed in two places with different mental models, and answering "what can this person see" requires checking both.

What it costs

  • Onboarding takes days instead of minutes, because nobody can say which sets a new starter in a given role should get.
  • Offboarding is incomplete. Deactivation covers the login. It does not answer what that person could see, which is the question an auditor asks.
  • Least privilege becomes unprovable. You may well be compliant. You cannot demonstrate it, and in an audit those are the same outcome.
  • Every change is risky. Nobody removes a permission because nobody can predict who breaks.

Measure before you cut

Resist the urge to start deleting. Spend a day producing four numbers instead.

1. Permission sets with no assignments. Free wins. Nothing breaks. This is usually 15-30% of the list in an older org.

2. Users with permissions they have never exercised. Login history, setup audit trail and field history give you a defensible picture. Access that has not been used in twelve months is a strong candidate.

3. Users who could modify all data. Count the profiles and permission sets granting broad administrative or data-wide access, then count the humans. This number is almost always higher than leadership expects, and it is the one that focuses attention fastest.

4. Assigned licences that are not being logged into. Not strictly access debt, but you will find it in the same query, and it funds the clean-up.

Restructure around jobs, not objects

The most common structural mistake is one permission set per object or per feature. It sounds tidy and produces a matrix that grows quadratically. Nobody can answer "what does a field engineer get" without reading forty rows.

Organise around the job instead:

LayerContainsExample
BaselineWhat every internal user getsChatter, core app access, standard objects everyone reads
Job familyThe permissions that define a roleSales rep, service agent, field engineer, finance
ElevationTime-bound or approval-gated extrasData export, mass delete, integration admin

A new starter gets baseline plus one job family. That is it. Elevation is deliberately awkward to obtain, because it should be.

Permission set groups are the right mechanism for the job-family layer, they let you compose the group from smaller sets while assigning one thing to the user. Muting permission sets handle the "this role gets everything in the group except X" case without forking the group.

A clean-up that does not break Monday

Five steps, run in this order. It takes a few weeks of elapsed time, not a project.

  1. Delete the unassigned. No user impact by definition. Do it in a release, not ad hoc, so it is in the record.
  2. Build the target model in a sandbox. Baseline, job families, elevation. Do not attempt to migrate anyone yet.
  3. Map every current user to a target job family. This is the real work, and it is a business conversation, not an admin one. Managers confirm their people. Where someone does not fit a family, that is a finding, either the family list is wrong or the person's role is.
  4. Migrate one department, in production, with the old sets still assigned. Additive first. Nothing is removed yet, so nothing can break.
  5. Remove the old sets for that department after a week of clean running. Then move to the next department.

Additive-then-subtractive is what makes this safe. Every step is individually reversible, and no user ever loses access in the same change that grants new access.

The reporting you want afterwards

Once the model exists, three saved reports keep it honest:

  • Users assigned more than one job family (should be near zero, each one deliberate).
  • Elevation assignments older than their review date.
  • Permission sets with fewer than three assignees (candidates for merging into a family or retiring).

Review them quarterly. Fifteen minutes, four times a year, is the entire ongoing cost of not being back here in 2029.

If you want a second pair of eyes on an access model before an audit or a platform migration, that is exactly the kind of review our managed services team runs.

Common questions

Answered, directly.

The questions this piece settles about Admin & Operations, answered in full on this page.

Produce four numbers first: permission sets with no assignments, users holding permissions never exercised in twelve months, users who can view or modify all data, and assigned licences with no logins. Those quantify the problem and identify the safest changes to make first.

By job, not by object. A baseline every internal user receives, a job family that defines each role, and a deliberately awkward elevation layer for time-bound extras. Permission set groups compose the job family, and muting permission sets handle exceptions without forking the group.

Additively, then subtractively. Delete unassigned sets, build the target model in a sandbox, map every user to a job family with their manager, assign the new sets in production while the old ones remain, and only remove the old ones after a week of clean running.

Free architect conversation

Talk to an architect, not a sales rep.

Salesforce org health check. 60 seconds to brief us, and a certified architect replies within one business day.

What is making the org hard to run?

Pick the closest fit. The health check is free and the findings are yours whether or not we do the work.

Which parts of the org are the problem?

Optional. Choose any that apply, or skip ahead.

Where does your org stand today?

Optional. A few sentences is plenty: what is working, what is stuck, and what you want to be true. Or skip ahead and tell us on the call.

Who should the architect reach?

A certified architect will reply to these details.

Takes about 30–60 seconds · No obligation · Architect replies within one business day

Protected by reCAPTCHA. Google's Privacy Policy and Terms apply.