Restriction rules are the only control in Salesforce that takes record access away. Everything else in the sharing model adds. A rule names a set of users and a record filter, and those users then see only the records that match the filter, whatever their profile, role or sharing rules would otherwise have granted. The catch is the object list, which has never included Account, Opportunity, Case or Lead.
Subtractive, in a model that is otherwise additive
Org-wide defaults set a floor. Role hierarchy, sharing rules, manual shares, teams and territories all raise it. Nothing in that stack lowers access once something else has granted it, which is why “everyone can see all Contracts because of one rule from 2019” is so familiar.
Restriction rules sit outside that stack. They are applied at query time as an extra filter rather than being written into the share tables, so no sharing recalculation runs when you create one. That also means a rule takes effect quickly and can be switched off quickly, which is a genuine operational advantage over redesigning org-wide defaults.
What a rule is made of
Two halves, both required:
- User criteria. Which users the rule applies to, expressed as a field on the User record or on the running user’s permission set assignments. Common choices are a custom field on User, Profile, or a user-level attribute you already maintain.
- Record criteria. Which records those users may see, expressed as a filter on fields of the target object. Supported field types are limited, so check yours before designing around a formula field.
Users who do not match the user criteria are untouched. This is the part people get backwards: a restriction rule is not a global filter on the object, it is a filter applied to the named population.
Where the filter actually applies
The rule follows the record everywhere the platform returns records: list views, reports, SOQL, search, the REST and SOAP APIs, related lists, and lookups. That breadth is the point. A rule you can bypass by opening a report is not a control.
Two things to verify in a sandbox rather than assume. First, how the rule behaves for users holding View All Data or View All on that object. Second, whether a user can still reach a restricted record they own. Test both with a real user, not an admin.
The supported object list is the whole story
Restriction rules work on custom objects and external objects, plus a short list of standard ones that has historically included Contract, Task, Event, Time Sheet and Time Sheet Entry. It does not include the objects most orgs want to restrict. If your requirement is “these users should only see Opportunities in their region”, restriction rules are not the answer today, and you are back to redesigning the sharing model or using scoping rules for the softer version of the requirement.
Limits worth knowing before you design
- You get a small number of rules per object, and the cap depends on edition. Design for one or two per object, not a rule per team.
- Rules on the same object combine restrictively. More rules means less visible data, never more.
- They are metadata.
RestrictionRuledeploys through the Metadata API and belongs in source control alongside the rest of your access model. - They add to query cost. A badly chosen record filter on a large object is a performance problem, not just a security one.
When to reach for one
The honest use cases are narrow. Keeping contractors out of records flagged sensitive on a custom object. Stopping a support team seeing Tasks logged against executive accounts. In each case the alternative is a sharing redesign that takes weeks.
What they should not be is a patch over a sharing model you have lost control of. If you need four rules on one object to get the access picture right, the sharing model is the problem.
Frequently asked
Do restriction rules replace sharing rules? No. They narrow what an already-granted set of records looks like. You still need the sharing model to decide what gets granted in the first place.
Do they trigger a sharing recalculation? No, which is why they can be deployed and reversed quickly. Sharing rule changes do, and on a large object that matters.
Can a user tell they are being restricted? Not directly. Records simply do not appear. There is no message, which makes support calls about “missing” records harder to diagnose if the rule is undocumented.
What if the object I need is not supported? Look at scoping rules if the requirement is about default visibility rather than enforcement, or move the sensitive data to a related custom object that is supported.