Skip to content

Publish-time lint: sharingModel: controlled_by_parent with no master_detail relation is statically detectable and unreported #7503

Description

@os-zhuang

Found while implementing #7474 (PR splitting the six assertControlledByParentWrite refusal legs). Filed rather than fixed: the maintainer ruling of 2026-08-11 on #7474 ordered the runtime split only, and explicitly left question 2 of that card — lint vs runtime — undecided. This is that question, filed so it is not lost.

What was measured

An object that declares sharingModel: 'controlled_by_parent' and has no relation for the platform to derive access from is now refused at RUNTIME with 422 INVALID_METADATA (the #7474 PR). Nothing reports it before that:

  • packages/lint/src/validate-security-posture.ts carries the adjacent rules — security-owd-unset, security-owd-alias, security-master-detail-ungranted (a detail object that no authored permission set grants), security-private-no-readscope — and none of them checks this one. Grep for controlled_by_parent in packages/lint/src returns only the OWD vocabulary list, the D11 comment, and the security-master-detail-ungranted docblock.
  • The check needs nothing a lint pass does not already hold: the object document carries sharingModel and fields, and the relation resolution is the same three-step fallback resolveCbpRelation performs at runtime (security-plugin.ts) — a required master_detail, then any master_detail, then a required lookup. An object matching none of the three has nothing to derive from.

Why it is worth a rule

The runtime refusal fires when a user attempts a write on that object — i.e. after the app is published and in someone's hands, and only on the detail objects a caller happens to touch. The defect exists from the moment the metadata is authored. This is the shape security-master-detail-ungranted already exists for, one gate earlier.

It matters most for AI-authored metadata: controlled_by_parent is a plausible thing for an agent to write next to a lookup it forgot to mark required, and nothing in the authoring loop says so.

Suggested shape

A new advisory rule alongside SECURITY_MASTER_DETAIL_UNGRANTED in validate-security-posture.tserror rather than warning is arguable, since the runtime answer is already a hard refusal, and that severity choice is the one thing this needs a decision on.

Pointers

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions