Skip to content

docs(adr): ADR-0090 — Permission Model v2: concept convergence, final naming, AI-authoring safety - #2695

Merged
os-zhuang merged 3 commits into
mainfrom
claude/adr-0090-permission-model-v2
Jul 9, 2026
Merged

docs(adr): ADR-0090 — Permission Model v2: concept convergence, final naming, AI-authoring safety#2695
os-zhuang merged 3 commits into
mainfrom
claude/adr-0090-permission-model-v2

Conversation

@os-zhuang

@os-zhuangos-zhuang commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

Two documents, deciding and describing the converged permission model ahead of launch:

  • docs/adr/0090-permission-model-v2-concept-convergence.md — the decision record (Status: Proposed). Twelve decisions:
    • D1 — custom objects default to OWD private; the unset state ceases to exist (existing metadata grandfathered by explicit stamping, no silent behavior change)
    • D2 — the Profile concept is removed (isProfile deleted from PermissionSetSchema); isDefault narrows to an install-time package suggestion
    • D3sys_role / sys_user_role / sys_role_permission_set / ctx.roles[] / current_user.role renamed to position; "role" becomes a lint-enforced reserved-forbidden word (single exception: better-auth's sys_member.role, already projected as org_membership_level)
    • D4 — OWD enum drops the read / read_write / full aliases; authoring rejects, no lenient parse
    • D5 — a built-in, undeletable everyone position carries default grants: packages suggest, admins confirm, resolution is per-request (abolishes the fallback cliff; no second distribution channel)
    • D6 — an explain engine is promoted to P0, and an access-matrix snapshot gates security-domain publishes with semantic diffs
    • D7 — security-domain publish linter + tiered human gates (AI may draft anything; it may not silently publish capability)
    • D8teams receive sharing and never carry capability (no permission-set bindings, no record ownership)
    • D9audience anchors: builtin guest position joins everyone; packages suggest bindings to audiences, never ship shared builtin sets; deliberately no admin anchor (the superuser wildcard already covers every new package)
    • D10principal taxonomy (kind: human | agent | service | guest | system, audience: internal | external, onBehalfOf): AI agents act on the intersection of their own grants and their delegator's, under a lint-enforced ceiling, with human co-sign for destructive operations; services are seatless least-privilege machine identities
    • D11external OWD dimension: optional externalSharingModel, default private, validated external ≤ internal; BU depth inapplicable to externals
    • D12delegated administration: admin scopes (BU subtree + assignable-set allowlist + structural no-self-escalation) so subsidiary admins run their own units without tenant-wide power
  • docs/design/permission-model.md — the companion complete reference for the decided model: the five concepts, the evaluation pipeline, OWD semantics (internal + external dials), a worked CRM-package example (developer story + admin story), the everyone/guest baselines, plain-language sections on principal kinds (the agent "overlap rule") and delegated administration, the AI-safety layers, a "if you come from Salesforce/Dataverse/ServiceNow/SAP/AWS" mapping table, and the glossary/naming rules.

Why

Three forcing facts, argued in the ADR's Context: the pre-launch window is the only zero-cost moment for breaking renames (hence no aliases — explicitly superseding ADR-0057 D5/D7's alias clauses); the metadata is AI-authored, so vocabulary size is attack surface; and a dogfood incident (objectstack-ai/objectui#2348) proved the current "unset OWD = fully public" default silently inverts the admin's mental model into org-wide read/write. D9–D12 add the operating-a-large-organization dimension raised in review: universal audiences, AI-agent/service principals, portal users, and subsidiary-scoped administration.

Relationship to existing ADRs

Builds on 0049 / 0056 / 0057 / 0066 / 0086. Amends: ADR-0056 D7 (default-profile fallback → replaced by the everyone position), ADR-0057 D5/D7 (deprecated-alias discipline → superseded pre-launch). ADR-0057's core (BU tree, scope depth, sys_user_role decoupling) is untouched and load-bearing. Six named follow-up ADRs are scoped out explicitly (grant lifecycle/recertification, SoD, scale hardening, dimension restrictions, ALM promotion, portal identity) and tracked on #2696.

What this PR does NOT do

Docs only — no spec, plugin, or runtime changes. Implementation is phased in the ADR (P1 breaking wave incl. ctx/externalSharingModel spec shapes → P2 audience anchors → P3 linter/gates/delegated admin → P4 explain/matrix), each phase with its own proofs per ADR-0054 discipline.

🤖 Generated with Claude Code

https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H

…naming, AI-authoring safety
Records the eight decisions converging the authorization model ahead of
launch: OWD defaults to private for custom objects (D1), the Profile
concept is removed (D2), sys_role and friends are renamed to position
with "role" as a lint-enforced forbidden word (D3), the OWD enum drops
its legacy aliases (D4), a built-in `everyone` position carries default
grants (D5), an explain engine plus access-matrix snapshot gate is
promoted to P0 (D6), security-domain publishes get a linter and tiered
human gates (D7), and teams are confirmed as sharing recipients that
never carry capability (D8).
Ships with the companion reference docs/design/permission-model.md —
the maintained source of truth for the decided model (concepts,
evaluation pipeline, CRM worked example, AI-safety layers, glossary).
Supersedes ADR-0056 D7 (default-profile fallback) and ADR-0057 D5/D7
alias clauses (pre-launch one-step renames, no compatibility layers).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H
@vercel

vercelBot commented Jul 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 9, 2026 1:09am

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation size/l and removed documentation Improvements or additions to documentation labels Jul 8, 2026
…my, external OWD, delegated admin
Extends the proposed ADR with four decisions raised in review discussion:
D9 — audience anchors: builtin `guest` position joins `everyone`; packages
suggest bindings, never ship shared builtin sets; deliberately no
admin anchor (superuser wildcard already covers new packages).
D10 — principal taxonomy (kind: human|agent|service|guest|system,
audience: internal|external, onBehalfOf). AI agents act on the
INTERSECTION of their own grants and their delegator's, under a
lint-enforced ceiling, with human co-sign for destructive ops.
D11 — external OWD dimension: optional `externalSharingModel`, default
private, validated external <= internal; depth axis inapplicable
to externals.
D12 — delegated administration: admin scopes (BU subtree + assignable-set
allowlist + no self-escalation) so subsidiary admins run their own
units without tenant-wide power.
Non-goals section restructured into deliberate non-goals + six named
follow-up ADRs (grant lifecycle/recertification, SoD, scale hardening,
dimension restrictions, ALM promotion, portal identity). Phasing updated:
P1 additionally lands the ctx principal shape and externalSharingModel
spec shape; P2 becomes both audience anchors; P3 adds delegated admin.
Companion design doc gains plain-language sections: "Who is calling"
(principal kinds, the agent overlap rule, guardrails), "Running a large
organization" (delegated admin worked example), external OWD dial, guest
position, and glossary entries.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H
@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Jul 9, 2026
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude