Skip to content

Commit a73c31e

Browse files
committed
docs(adr): ADR-0106 — add Business context section
Distills what the disclosure boundary is worth: the claimable FLS invariant (pentest/questionnaire/Salesforce-describe parity), the platform-leverage shape (customers cannot fix /meta exposure in their own tier), unlocked mixed-sensitivity modeling (no object splitting for portal scenarios), and schema shape as business information — against a deliberately near-zero cost side (D3/D8). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AEb4XCVb7iLEBVe9HghjTt
1 parent 562fde7 commit a73c31e

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

docs/adr/0106-metadata-plane-fls-object-schema-masking.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,50 @@ ObjectStack customers build portals and products whose authenticated callers
8585
the platform cannot vouch for. Enforcement must be the platform default
8686
(ADR-0049).
8787

88+
### Business context — what masking is worth
89+
90+
The value scale of this ADR is not "prevents data breaches" (the data plane
91+
already enforces reads and writes); it is what the *disclosure* boundary
92+
buys the platform and its customers:
93+
94+
- **The invariant becomes claimable.** After this ADR the platform can state
95+
— in security questionnaires, audits, and competitive POCs — one complete,
96+
testable sentence: *a field the caller cannot read does not exist for that
97+
caller, on any plane*. Today a competent pentester falsifies the "we have
98+
field-level security" claim with a single unauthenticated-of-privilege
99+
`curl /meta/object/<name>`; a pentest finding is remediation cost and a
100+
deal blocker. The industry benchmark behaves this way already —
101+
Salesforce's `describe` omits fields the caller cannot read — so "FLS
102+
comparable to Salesforce" is only true once this ships.
103+
104+
- **Only the platform can fix it.** Data-plane exposure is configurable by
105+
customers through permission sets; what `/meta` serves is not. A customer
106+
building a dealer/supplier/patient portal has **no** remediation available
107+
in their own tier today except modeling discipline ("keep sensitive fields
108+
off portal-visible objects"). One platform-side fix is inherited by every
109+
deployment — the classic platform-leverage shape.
110+
111+
- **It unlocks mixed-sensitivity modeling.** Without masking, the honest
112+
guidance forces *object splitting*: the same business entity duplicated
113+
into an internal object and a portal object, with synchronization,
114+
reporting, and flow costs doubled. With masking, "one `account` object —
115+
40 fields for staff, 12 for dealers" is a supported, first-class modeling
116+
style. That is a product capability (external users on the primary data
117+
model), not merely hygiene.
118+
119+
- **Schema shape is itself business information.** Field names alone answer
120+
"what does this company record" (`salary_grade`, `layoff_flag`, a
121+
diagnosis field); picklist option sets are operational taxonomies
122+
(customer tiers, risk bands); formula expressions are pricing and scoring
123+
IP; `requiredPermissions` names hand an attacker the exact capability to
124+
escalate toward. Removing the schema removes the reconnaissance map — the
125+
cheapest layer of defense in depth.
126+
127+
Against this, the cost side is deliberately near-zero (D3: unrestricted
128+
callers get byte-identical responses; cache storage unchanged) with an
129+
escape hatch (D8) — which is the business case for shipping it in the
130+
current major rather than deferring.
131+
88132
### What is already in place
89133

90134
- `security.getReadableFields(object, ctx)` (#3547): the authoritative

0 commit comments

Comments
 (0)