Not verified hands-on. This article was written from primary documentation rather than reproduced in an org, so it carries no tested-release badge. If you run it and something differs, say so in the comments and it gets tested and corrected.

The short answer: external users read a different org-wide default from internal users, and the mechanism that grants them records depends on their licence. High-volume users (Customer Community) get access through sharing sets, which key off the Contact and Account on the user record. Users with a role (Customer Community Plus, Partner Community) get it through the portal role hierarchy under their account, plus sharing rules and super user access. Confuse the two and you will spend an afternoon wondering why an ordinary sharing rule does nothing.

External org-wide defaults come first

Sharing Settings gives every object two columns: Default Internal Access and Default External Access. The external value can match the internal one or be stricter, never looser. Every external user reads the external column, guests included, and the guest value is forced to Private.

Private is the right default: nothing is visible until you grant it. Every “the partner cannot see it” ticket should begin here. People check the internal column by reflex.

Sharing sets, for high-volume users

A sharing set applies to profiles holding a high-volume licence: Customer Community, High Volume Customer Portal, Authenticated Website. Those users have no role. They cannot be added to public groups. The role hierarchy cannot reach them and neither can an owner-based sharing rule, so a sharing set is not one option among several. It is the option.

It maps a field on the user’s Contact or Account to a lookup on the target object. “Grant access to Cases whose ContactId matches the ContactId on the running user” is the canonical example.

  • Access is Read Only or Read/Write per object, set in the access mapping.
  • The mapping can traverse a lookup to a parent, which is how a custom object with no Contact field of its own gets covered through its Account.
  • It applies to the profiles listed on it, not the whole site. A portal profile added later sits silently outside the set.

Share groups solve the opposite problem

Records owned by a high-volume community user are invisible to internal staff, because the owner sits outside the role hierarchy. A share group, configured on the sharing set, names the internal users, roles or public groups that should see them. Skip it and a case a customer logs on the portal is unreachable for support, which makes for a memorable first morning in production.

Roles, for Customer Community Plus and Partner Community

Enabling an account as a partner or customer account creates a small role hierarchy beneath the account owner’s role, three levels deep by default. The depth is set in Sharing Settings and lowering it later does not retrofit existing accounts.

That buys real hierarchy behaviour. The internal account owner sees records owned by external users under that account. A partner manager sees records owned by partner users below them. Owner-based sharing rules work, and can target portal roles or the All Partner Users group. The bill arrives as roles: every partner account consumes several against your org’s role limit, so a thousand partner accounts is a capacity question you answer before launch.

Why the partner cannot see the record

Work down this list in order. It is almost always the first four.

  • The external org-wide default for the object.
  • Object permissions on the profile or permission set, and whether the licence permits the object at all.
  • Field-level security, if the record opens but looks empty.
  • Who owns the record, and whether that owner sits in the same account and above the user in the portal role hierarchy.
  • Super user access. Partner Super User Access has to be switched on in Sharing Settings before the Portal Super User permission does anything, and it reaches only records owned at or below that role in the same account.

Start by looking at the user, not the record:

SELECT Id, Name, UserType, IsActive, Profile.Name,
       UserRole.Name, ContactId, AccountId
FROM User WHERE Id = '005xx000001Sv6DAAS'

A null UserRole puts you in sharing-set territory, and every sharing rule in the org is then irrelevant. If all six pass, check someone published the site.

Frequently asked

Can a sharing rule grant access to a Customer Community user? Not an owner-based one. They have no role and cannot join public groups, so there is no target to name. Sharing sets, or Apex managed sharing against the user id, are the routes that work.

Does Apex managed sharing work for external users? Yes. Share rows accept an external user id like any other, and a custom row cause survives owner changes. It is the usual fallback when the requirement fits neither model.

Why did access appear only after I changed the owner? The grant was coming from the hierarchy, not from a rule. Access that must survive a reassignment needs a sharing set, a criteria-based rule, or code.