ObjectOS
ConfigurePermissions

Record Access

Control which records a user can see or modify.

Record access controls which rows a user can see or modify after object permissions allow the operation.

Mechanisms

MechanismPurpose
Row-level securityEnforce tenant or organization isolation
Sharing rulesGrant access based on declarative criteria
Record sharesGrant access to a specific user, team, position, business unit, or a unit and its subordinates
Ownership/hierarchyGrant access through the owner and the business-unit tree

Sharing model defaults

Every object declares (or inherits) a sharingModel that sets the organization-wide default: private, public_read, public_read_write, or controlled_by_parent.

Since ObjectStack 13, custom objects that carry an owner field and do not declare a sharingModel default to private — records are visible to their owner (and admins) until a sharing rule, record share, or wider default opens them up. Declare the model explicitly to restore open behavior:

defineObject({
  name: 'crm_lead',
  sharingModel: 'public_read_write',
  // …
});

The pre-13 aliases read, read_write, and full were removed; os compile flags unset or aliased models via the security-owd-unset and security-owd-alias lints.

Default tenant isolation

The security plugin enforces tenant isolation through the current user's context. For standard platform objects, default rules protect global tables that do not carry the normal organization field.

The practical customer expectation is:

Users only see records that belong to their organization or records
explicitly shared with them.

Sharing rules

Use sharing rules for repeatable business policies:

  • all regional managers can read accounts in their region;
  • support managers can see escalated cases;
  • finance can read approved invoices;
  • auditors can read records tagged for audit review.

A rule is a CEL condition over field values, compiled at author time into a row filter; matching records materialize sys_record_share grants for the resolved recipients (a user, team, position, business unit, or a unit and its subordinates). criteria rules are the only authorable form.

Both switches fail closed

Two things a reader is entitled to assume, and which have been true only since ObjectStack 17.0:

  • A sharing rule with no criteria shares nothing. A rule stored without a criteria predicate used to evaluate as every record of the object — the empty filter — so a typo through an unvalidated write path silently opened the whole table. Writing a match-all criteria is now rejected, and the evaluator treats an empty one as matching nothing.
  • An RLS policy with enabled: false is disabled. A policy switched off used to keep contributing its OR-branch grant, so turning a policy off did not take the access away. A disabled policy is now simply not evaluated.

If you audited access under an earlier release and concluded "this rule grants nothing" or "this policy is off", it is worth re-running the explain engine — the answer may have been wider than the metadata said.

Record shares

Use record shares for exceptions:

  • share one opportunity with a specialist;
  • grant temporary access during an escalation;
  • give an external integration access to a specific record.

Troubleshooting visibility

When a user cannot see a record, check in this order:

  1. Is the user authenticated and in the expected organization?
  2. Does the user have object read permission?
  3. What is the object's sharingModel (custom objects default to private since ObjectStack 13)?
  4. Does row-level security allow the record?
  5. Is there a sharing rule that should apply?
  6. Is there a direct record share?
  7. Is the record owned by a user in the expected business-unit subtree?
  8. Is the user looking at the correct project/hostname?

The explain engine answers all of these in one call — it reports each layer's verdict and which grant (or missing grant) decided the outcome.

On this page