本文へ移動
cccskills
無料GitHub で公開

sharing-rules

Use when access must reach past the record owner's role hierarchy. Trigger keywords: sharing rule, criteria-based sharing rule, owner-based sharing rule, sharing rule recalculation, guest user sharing rule, share with a public group, SharingRules metadata. NOT for org-wide defaults - use admin/sharing-and-visibility. NOT for programmatic shares - use apex/apex-managed-sharing. NOT for subtracting access - use admin/restriction-rules.

インストール方法を見る

含まれるファイル(7)

  • SKILL.md26.2 KB
  • references/examples.md10.6 KB
  • references/gotchas.md19.5 KB
  • references/llm-anti-patterns.md12.2 KB
  • references/well-architected.md15.6 KB
  • scripts/check_sharing_rules.py22.5 KB
  • templates/sharing-rules-template.md9.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Sharing Rules

A sharing rule is a standing instruction to the platform: whenever a record matches this condition, write an access grant for this group. It is the workhorse declarative mechanism for granting record access sideways — to peers, to a service desk, to a partner team — without changing ownership, without a manual share per record, and without inventing a role that does not reflect the business.

This skill owns the rules themselves. The surrounding access model — org-wide defaults, the role hierarchy, manual sharing, implicit sharing, View All bypasses — belongs to admin/sharing-and-visibility, and this skill assumes that model is already decided.


Before Starting

Gather this context before designing or touching any rule:

  • What is the object's org-wide default? Access grants exist only where the OWD is restrictive. Salesforce documents that "when an object has its organization-wide default set to Private or Public Read Only, Salesforce uses access grants to define how much access a user or group has to that object's records" — outside that, the share table is not the mechanism and a sharing rule buys nothing.
  • Owner-based or criteria-based? The question is not "which is easier" but "what actually determines who should see this." If the answer is a sentence about who owns it, the rule is owner-based. If it is a sentence about what is on the record, the rule is criteria-based. A rule written in the wrong shape silently stops matching the moment ownership or the field changes.
  • Is the target group already a real Salesforce group? Sharing rules can only target things the platform can name: public groups, roles, roles and internal subordinates, managers, queues, territories, portal roles, guest users. If the intended audience is "the people who work on this account," no rule can express that — that is teams or Apex managed sharing.
  • How many rules does the object already carry? The Salesforce Security Guide states the cap directly: "You can define up to 300 total sharing rules for each object, including up to 50 criteria-based or guest user sharing rules, if available for the object." The 50 sits inside the 300 rather than on top of it, and guest rules draw on the same 50. Treat the count as a budget from the first rule, not something to discover at the ceiling.
  • What is the record and user volume? Recalculation cost scales with records × affected group membership. On an object with a few thousand records nobody notices. At millions, a single role move can queue hours of maintenance.

Core Concepts

Owner-based vs criteria-based

Owner-based (SharingOwnerRule)Criteria-based (SharingCriteriaRule)
Matches onWho owns the record (sharedFrom)Field values on the record (criteriaItems + booleanFilter)
Re-evaluates whenOwnership changes, or source/target group membership changesThe criteria fields change, plus group membership changes
Typical use"Everything the West reps own goes to the Services desk""Every Account with Type = Partner goes to the channel team"
Extra required field—includeRecordsOwnedByAll, and you can't edit it after the rule is created
API version33.0+33.0+

Both extend SharingBaseRule, which carries the fields that actually decide access: accessLevel (required), sharedTo (required), label (required), an optional description of up to 1,000 characters, and — on Account rules only — accountSettings.

What a rule can and cannot grant

A sharing rule adds an access grant. It never removes one. There is no "deny" sharing rule, no ordering between rules, and no precedence: the most permissive grant on a record wins, whatever produced it. If the requirement is "these users must stop seeing records they currently see," a sharing rule is the wrong tool — see admin/restriction-rules.

Design for Read or Edit. All — Full Access, where "the specified user or group can view, edit, transfer, share, and delete the record" — appears in the enumeration inherited from the removed CriteriaBasedSharingRule type and on the share row, but it is not access a sharing rule can ask for. The Apex Developer Guide scopes it to "managed sharing" and the share-object field reference is blunter: "The All access level is an internal value and can't be granted." Account rules carry a nested accountSettings block whose caseAccessLevel, contactAccessLevel, and opportunityAccessLevel are each required and each take None, Read, or Edit — this is how one Account rule cascades to the account's children, and it is where over-sharing usually enters an org unnoticed.

Who you can share to

sharedTo names the recipient. The elements that matter in practice:

sharedTo elementGrants toNote
groupA public groupThe workhorse; see admin/queues-and-public-groups
roleUsers in one roleNarrow — no subordinates
roleAndSubordinatesInternalA role plus its internal subordinatesCurrent name after the Secure Roles rename
queueA queueSalesforce: "Applies only to lead, case, and CustomObject sharing rules"
territory / territoryAndSubordinatesTerritory membersPairs with SharingTerritoryRule
managers / managerSubordinatesA user's management chain / their subordinatesManager groups, not the role hierarchy
allInternalUsers"A group containing all internal and nonportal users"Effectively org-wide; justify it in writing
guestUserNamed guest usersSharingGuestRule only

Prefer a public group over a bare role even when the role is currently the right population. The group survives a reorg; the role reference does not.

Guest user sharing rules

SharingGuestRule (API 47.0+) is a separate array on SharingRules, not a variant of the other two. Two hard constraints come straight from the Metadata API reference: "For SharingGuestRule, the accessLevel field can be set only to Read", and includeHVUOwnedRecords is required and "you can't edit this field after the sharing rule is created." Criteria (criteriaItems, booleanFilter) arrived in API 48.0.

Everything else about unauthenticated access — which objects the guest profile can even read, what the site exposes — is admin/experience-cloud-guest-access and security/guest-user-security. Come here only for the rule itself.

The share row a rule produces

Every grant lands as a row in the object's share table: AccountShare, OpportunityShare, and for a custom object, MyCustomObject__Share. Four fields carry the meaning:

FieldHoldsNote
ParentId (custom) / AccountId etc. (standard)The shared record"This field can't be updated."
UserOrGroupIdThe recipientUser or Group Id
AccessLevel (custom) / AccountAccessLevel etc. (standard)Read, Edit, or All"The All access level is an internal value and can't be granted."
RowCauseWhy the grant exists"This field can't be updated."

RowCause is the field that makes an access audit possible. Salesforce: "when a record owner manually shares a record with a user or group, Salesforce creates a sharing row with a Manual row cause. When a sharing rule shares the record with a user or group, Salesforce creates a sharing row with a Rule row cause." The documented set also includes Owner, Team, ImplicitChild, ImplicitParent, TerritoryRule, TerritoryManual, and Territory2AssociationManual.

The consequence to internalise: RowCause = 'Rule' rows are system-maintained. "The reason determines the type of sharing, which controls who can alter the sharing record." You do not insert them, you do not delete them, and deleting one by hand is not how you revoke access — changing the rule, the criteria, or the ownership is.

-- Which grants exist on one Account, and what produced each of them
SELECT Id, UserOrGroupId, AccountAccessLevel, OpportunityAccessLevel, RowCause
FROM AccountShare
WHERE AccountId = '001XX000003DHPh'

-- Only the rule-produced grants on a custom object
SELECT Id, ParentId, UserOrGroupId, AccessLevel, RowCause
FROM Project__Share
WHERE RowCause = 'Rule'

Recalculation

Salesforce does not evaluate sharing rules at query time. "Rather than applying every sharing rule, traversing all hierarchies, and analyzing record access inheritance in real time, Salesforce calculates record access data only when configuration changes occur." Those precomputed rows are what a query joins against, which is why access is fast and why changing the model is expensive.

Recalculation is asynchronous — "automatic sharing recalculation is processed asynchronously and in parallel" — but it is not unobservable, and most advice on this topic gets that backwards. Salesforce documents both a progress view and a completion signal: "You can monitor the progress of your parallel sharing rule or organization-wide default recalculation on the Background Jobs page or view recent sharing operations on the View Setup Audit Trail page," and "You receive an email notification when the recalculation is completed for all affected objects." It is triggered by far more than editing a rule: role moves, group membership edits, queue changes, ownership transfers, and criteria-field updates all cause the platform to rewrite share rows and group maintenance tables. The architect guidance is explicit that "it can take some time to recalculate access for a large number of users, and adjust the tables that record their access rights," and that "the size and complexity of an organization's queues and hierarchies directly affect the duration of record access calculations."

While the job runs the model is partly frozen. The Security Guide documents share locks: "You can't modify the org-wide defaults when a sharing rule recalculation for any object is in progress. Similarly, you can't modify sharing rules when recalculation for an org-wide default update is in progress" — though "You can make changes to the org-wide defaults and sharing rules for other objects." That lock, not politeness, is why an impatient admin cannot simply re-edit their way out of a slow rule.

For bulk structural change there is a deliberate escape hatch: defer sharing calculation, "which allows users to defer the processing of sharing rules until after new users, rules, and other content have been loaded." It is gated by a specific permission and it suspends and resumes two distinct processes — group membership calculation and sharing rule calculation. Deferral does not make the work smaller; it batches many small recalculations into one large one you schedule.

Deep-dive on the failure modes — the unwatched recalculation, the ownership-change deletions, the criteria-churn trap — is in references/gotchas.md. Read it before you promise a business stakeholder a completion time.


Common Patterns

Pattern: Peer visibility inside a region

When to use: OWD on Opportunity is Private. Reps in one region must read each other's pipeline. The role hierarchy gives their manager visibility but gives them nothing, because hierarchy access travels up, never sideways.

How it works:

  1. Build one public group holding the region's roles (admin/queues-and-public-groups), not a list of named users.
  2. Create an owner-based rule: sharedFrom = that group, sharedTo = the same group, accessLevel = Read.
  3. New joiners inherit access the moment they land in a member role. There is no per-user step.

Why not the alternative: a criteria-based rule on a region field looks equivalent and is not. It re-evaluates when the field changes, so a mis-keyed region silently moves the record out of the group's view; and it does not follow ownership, so a transferred deal keeps matching the old region until someone edits the field.

Pattern: Field-driven access to a sensitive subset

When to use: One team should see only the records carrying a particular classification — Type = 'Partner', Stage = 'Legal Review', a compliance checkbox. Ownership is irrelevant and scattered.

How it works: a criteria-based rule with criteriaItems and, when there is more than one condition, an explicit booleanFilter. Set includeRecordsOwnedByAll deliberately — it decides "whether records owned by users who can't have an assigned role are included in the records shared," which is exactly the integration users and portal-adjacent accounts everyone forgets — and remember you cannot change it later without recreating the rule.

Why not the alternative: granting the team View All on the object is one click and is unbounded. The criteria rule is the narrow version of the same access.

Pattern: Publishing records to an Experience Cloud site

When to use: anonymous visitors must read a catalogue, a knowledge-adjacent custom object, or a public listing.

How it works: a SharingGuestRule targeting the site's guest user via sharedTo → guestUser, accessLevel = Read (the only value it accepts), with includeHVUOwnedRecords set correctly on the first attempt.

Why not the alternative: an ordinary criteria-based rule pointed at a group that happens to contain the guest user is not the same object and is the single most common way orgs accidentally over-expose data to the internet.


Decision Guidance

SituationRecommended approachReason
Access follows who owns the recordOwner-based rule, source and target as public groupsSurvives reorgs; no field to keep clean
Access follows a value on the recordCriteria-based rule with explicit booleanFilterThe record carries its own routing
Criteria field changes on most records every weekReconsider — use owner-based or a teamEach change is a recalculation event
Access must be removed from a populationadmin/restriction-rulesSharing rules only add
Recipient is "whoever is working this record"Account/Opportunity/Case teams, or apex/apex-managed-sharingNot a group the platform can name
Logic needs cross-object or computed conditionsapex/apex-managed-sharing with a custom sharing reasonCriteria evaluate fields on the record only
Anonymous site visitorsSharingGuestRule, Read onlyThe only supported guest mechanism
Manager chain, not the role hierarchysharedTo → managers / managerSubordinatesManager groups are a separate axis
Loading users, roles, groups and rules togetherDefer sharing calculation, then resume onceOne large recalculation beats hundreds of small ones
Rule count on the object is climbing every quarterConsolidate onto groups; re-examine OWD and hierarchyRule sprawl is a symptom of a wrong baseline

Metadata Shape

All rules for one object live in a single file. Retrieve the object's existing file and add to it rather than authoring the envelope by hand — a retrieved file already carries the element order the API validates against. operation takes a value from the FilterOperation enumeration: equals, notEqual, lessThan, greaterThan, lessOrEqual, greaterOrEqual, contains, notContain, startsWith, includes, excludes.

<!-- force-app/main/default/sharingRules/Account.sharingRules-meta.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<SharingRules xmlns="http://soap.sforce.com/2006/04/metadata">
    <sharingOwnerRules>
        <fullName>West_Reps_To_Services_Desk</fullName>
        <accessLevel>Read</accessLevel>
        <accountSettings>
            <caseAccessLevel>Read</caseAccessLevel>
            <contactAccessLevel>Read</contactAccessLevel>
            <opportunityAccessLevel>None</opportunityAccessLevel>
        </accountSettings>
        <description>Services desk reads accounts owned by West sales, cases and contacts included, pipeline excluded.</description>
        <label>West Reps to Services Desk</label>
        <sharedFrom>
            <group>West_Sales_Reps</group>
        </sharedFrom>
        <sharedTo>
            <group>Services_Desk</group>
        </sharedTo>
    </sharingOwnerRules>
    <sharingCriteriaRules>
        <fullName>Partner_Accounts_To_Channel</fullName>
        <accessLevel>Edit</accessLevel>
        <accountSettings>
            <caseAccessLevel>Read</caseAccessLevel>
            <contactAccessLevel>Edit</contactAccessLevel>
            <opportunityAccessLevel>Read</opportunityAccessLevel>
        </accountSettings>
        <label>Partner Accounts to Channel Team</label>
        <sharedTo>
            <group>Channel_Team</group>
        </sharedTo>
        <booleanFilter>1 AND 2</booleanFilter>
        <criteriaItems>
            <field>Type</field>
            <operation>equals</operation>
            <value>Partner</value>
        </criteriaItems>
        <criteriaItems>
            <field>Active__c</field>
            <operation>equals</operation>
            <value>true</value>
        </criteriaItems>
        <includeRecordsOwnedByAll>false</includeRecordsOwnedByAll>
    </sharingCriteriaRules>
</SharingRules>

The manifest addresses the concrete rule types, not the SharingRules container. This is the sample the Metadata API Developer Guide ships for "retrieving a specific criteria-based sharing rule for the lead object, retrieving all ownership-based sharing rules for all objects, and retrieving all territory-based sharing rules for the account object":

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Lead.testShareRule</members>
        <name>SharingCriteriaRule</name>
    </types>
    <types>
        <members>*</members>
        <name>SharingOwnerRule</name>
    </types>
    <types>
        <members>Account.*</members>
        <name>SharingTerritoryRule</name>
    </types>
    <version>33.0</version>
</Package>

Recommended Workflow

  1. Confirm the baseline. Read the object's OWD and the role hierarchy first. If OWD is Public Read/Write, stop — no rule is needed. If the hierarchy already delivers the access, stop — a rule is redundant weight on every future recalculation.
  2. Name the population as a group. Create or reuse a public group. Reject the design if the audience cannot be expressed as a group, a role, a queue, a territory, or a guest user; route it to teams or apex/apex-managed-sharing.
  3. Choose the rule type from the requirement's grammar. Ownership sentence → owner-based. Field sentence → criteria-based. Write the chosen accessLevel, and for Account also the three accountSettings values, before touching Setup.
  4. Build it as metadata. Retrieve the object's existing <Object>.sharingRules-meta.xml, add the rule, and deploy. Set includeRecordsOwnedByAll (or includeHVUOwnedRecords for guest rules) correctly the first time — neither is editable afterwards.
  5. Run the checker. python3 skills/admin/sharing-rules/scripts/check_sharing_rules.py --manifest-dir <metadata-dir> catches missing required fields, booleanFilter indexes that reference criteria that do not exist, guest rules above Read, and org-wide recipients.
  6. Verify against the share table, not the UI. Watch Setup → Background Jobs until the recalculation clears — or wait for the completion email — then query the object's share object filtered to RowCause = 'Rule' and confirm the expected UserOrGroupId rows exist at the expected access level. Then log in as a target user and open a record that should not match.
  7. Plan the recalculation before any bulk change. For reorgs, mass ownership transfers, or user loads, use deferred sharing calculation, resume once, and treat the resume as a scheduled maintenance window rather than an instant operation.

Review Checklist

  • The object's OWD is Private or Public Read Only — otherwise the rule is inert
  • Rule type matches the requirement's grammar (ownership vs field value)
  • sharedTo targets a public group, not a bare role or a list of individuals
  • accessLevel is the minimum that satisfies the requirement, not Edit by reflex
  • On Account rules, all three accountSettings values were chosen deliberately, not left at the picker default
  • includeRecordsOwnedByAll / includeHVUOwnedRecords was set correctly on creation — it cannot be changed later
  • booleanFilter indexes match the number of criteriaItems actually present
  • Guest rules use SharingGuestRule with accessLevel of Read
  • Criteria fields are stable — not a status or stage that churns on most records weekly
  • RowCause = 'Rule' rows verified by SOQL on the share object, plus one negative test as a non-member
  • Rule count on the object recorded against the documented budget — 300 rules per object, of which at most 50 may be criteria-based or guest rules
  • Any bulk load or reorg that follows has a deferred-sharing-calculation plan

Salesforce-Specific Gotchas

Summaries only — the mechanism, the trigger conditions, and the fix for each are in references/gotchas.md.

  1. Saving a rule is not granting access. Recalculation is asynchronous, so "I created it and nothing happened" is usually a timing report, not a bug — track it on Setup → Background Jobs rather than on the rule page.
  2. Changing the owner rewrites the record's grants. Manual shares are deleted outright and owner-based rules re-evaluate from the new owner's groups — access can silently disappear from a transfer nobody connected to sharing.
  3. includeRecordsOwnedByAll is write-once. Getting it wrong means deleting and recreating the rule, which is a fresh recalculation on the whole object.
  4. Criteria on a churning field turns every record edit into sharing maintenance. The rule is correct and the org is slow.
  5. Account rules cascade to Cases, Contacts, and Opportunities through accountSettings, which is how a "read the account" request becomes pipeline exposure.
  6. RowCause = 'Rule' rows cannot be deleted to revoke access — they are system-maintained and will be rewritten.
  7. Sharing to a queue is object-limited — Salesforce documents queue as applying "only to lead, case, and CustomObject sharing rules."

Output Artifacts

ArtifactDescription
Rule design recordRule type, source group, target group, access level, criteria fields, and the reason for each
<Object>.sharingRules-meta.xmlDeployable rule definitions for the object
package.xml entriesSharingCriteriaRule / SharingOwnerRule / SharingTerritoryRule members for retrieve and deploy
Verification SOQLShare-object query filtered to RowCause = 'Rule', plus a negative test
Recalculation planWhich structural changes are batched, when deferral is enabled, and who owns the resume
Checker outputMalformed, non-deployable, or over-broad rules found in the metadata

Related Skills

  • admin/sharing-and-visibility — the surrounding access model: OWD, role hierarchy, manual sharing, bypass permissions. Decide the baseline there, build the rules here.
  • admin/role-hierarchy-design — when the real fix is the hierarchy rather than another rule.
  • admin/restriction-rules — the only declarative way to subtract access; sharing rules cannot.
  • apex/apex-managed-sharing — programmatic __Share inserts with custom sharing reasons, for logic criteria cannot express.
  • admin/queues-and-public-groups — building the groups that sharedTo targets, and the roleAndSubordinatesInternal rename in its Gotcha 6.
  • data/sharing-recalculation-performance — deep treatment of deferral, recalculation windows, and OWD changes at volume.
  • security/record-access-troubleshooting — tracing one named user's access to one specific record.
  • admin/experience-cloud-guest-access / security/guest-user-security — everything about guest access that is not the sharing rule itself.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use this skill when writing test-first, behavior-driven acceptance criteria in Given/When/Then format for a Salesforce user story. Covers happy path, edge cases, negative paths, permission boundaries, and data-state preconditions so the AC block can drive UAT scripts and Apex test design downstream. Trigger keywords: given when then, gherkin, behavior driven AC, test first acceptance criteria, scenario outline, BDD acceptance criteria. NOT for the user-story format itself (use admin/user-story-writing-for-salesforce). NOT for UAT script writing (use admin/uat-test-case-design). NOT for Apex test method generation (use agents/test-class-generator). NOT for high-level UAT planning (use admin/uat-and-acceptance-criteria). More triggers: acceptance criteria record, ac_id, req_id on a criterion, artefact under test, negative case for a rule-type requirement, no-match fall-through criterion, oracle for a Then clause, test type apex flow manual, criteria linter, check_ac_format.py, --manifest-dir.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Task and Event objects: polymorphic WhatId/WhoId, Activity object model, ActivityHistory vs OpenActivity, activity timeline customization, bulk task creation, Einstein Activity Capture boundaries. NOT for turning on EAC or calendar sync — use admin/einstein-activity-capture-setup. NOT for Email-to-Case — use admin/case-management-setup. Covers ActivitiesSettings metadata, enableActivities, shared Task/Event custom fields and FLS, TaskStatus value sets, Shared Activities and TaskRelation/EventRelation, recurring and child activities, and partial-success bulk DML on Task.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Design Invocable Apex actions that return deterministic, agent-friendly errors instead of surfacing raw exceptions to the LLM. NOT for authoring the action itself — @InvocableMethod schema, labels, security context — use agentforce/custom-agent-actions-apex. NOT for the Apex tests that force each error branch — use agentforce/agent-action-unit-tests.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Use when designing how an Agentforce agent extracts structured input parameters (slots) from a user's natural-language utterance to invoke an action. Triggers: 'agent extract date from user', 'agent action argument extraction', 'agentforce slot filling', 'agent invocable input mapping', 'agent fails to fill required parameter'. NOT for action authoring (use agentforce/agent-actions) or for prompt-template variable binding (use agentforce/prompt-builder-templates).

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Apex test patterns for @InvocableMethod agent actions: per-reason-code branch coverage, bulk safety, callout mocking, deterministic assertions. NOT for testing whether the agent routes to the right topic or answers well — use agentforce/agent-testing-and-evaluation. NOT for designing the error envelope the tests assert on — use agentforce/agent-action-error-handling.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

Designing or reviewing Agentforce actions: Flow actions, Apex invocable actions, prompt-template actions, action naming, input and output contracts, confirmation requirements, and safe error behavior. Triggers: 'agent actions', 'build an agent that can look up an order', 'make the agent able to check order status', 'give the agent a capability', 'agent that can retrieve a record', 'flow action for agent', 'agent invocable action', 'action schema design'. NOT for writing the Apex class itself — use agentforce/custom-agent-actions-apex. NOT for the reason_code error envelope that stops an agent retry loop — use agentforce/agent-action-error-handling.

日本語の概要は準備中です。原文の説明を表示しています。

PranavNagrecha/AwesomeSalesforceSkills192026年10月4日 更新

PranavNagrecha のスキルをすべて見る

このスキルの問題を報告する