Skip to content

feat(security): ADR-0090 P2 — everyone/guest audience anchors, additive baseline, anchor binding gate#2708

Merged
os-zhuang merged 3 commits into
mainfrom
claude/adr-0090-p2-audience-anchors
Jul 9, 2026
Merged

feat(security): ADR-0090 P2 — everyone/guest audience anchors, additive baseline, anchor binding gate#2708
os-zhuang merged 3 commits into
mainfrom
claude/adr-0090-p2-audience-anchors

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Implements ADR-0090 P2 (D5 + D9; follows #2697's P1 wave). Tracks #2696.

What

  • Anchor constantsEVERYONE_POSITION / GUEST_POSITION / AUDIENCE_ANCHOR_POSITIONS exported from @objectstack/spec (identity/position.zod.ts).
  • Seeding — both anchors seeded system-managed alongside the four builtin identity names (bootstrap-builtin-positions), idempotently.
  • everyone is implicit for every authenticated principal (resolve-authz-context pushes it before position→set resolution), so sets bound to it resolve as ordinary position-bound grants — additive, per-request, no materialized copies.
  • Fallback cliff abolished — the configured baseline (fallbackPermissionSet, default member_default) applies in addition to explicit grants (the old "only when the user had nothing else" conditional meant your first real grant silently cost you the baseline). The baseline is also seeded as an everyone binding so it lives in the same table / audit / explain path as admin-authored defaults — validated by the same high-privilege predicate before seeding.
  • Guest principal at the HTTP entry — a sessionless request resolves principalKind: 'guest' holding exactly ['guest'] (resolve-execution-context); internal bare contexts are untouched, so the engine's empty-context semantics keep their meaning.
  • Audience-anchor binding gate — an unconditional data-layer boundary next to the ADR-0086 package gate: sys_position_permission_set writes binding a set that carries VAMA, delete/purge/transfer, system permissions, or a '*' wildcard to everyone/guest are rejected (describeHighPrivilegeBits exported and shared with seed-time validation).

Out of scope (per ADR phasing)

Install-time suggestion prompt UI (objectui, ships with the major-13 alignment); guest-position enforcement surfaces for portals; P3 linter family / delegated admin.

Verification

New behavior tests: anchor seeding + idempotency + predicate matrix (5, plugin-security audience-anchors.test.ts), everyone-additive + anonymous-never-everyone (2, core resolver), guest/human principal at the HTTP entry (2, runtime). Affected suites green locally: plugin-security 198, core 313, runtime exec-ctx 21. Full monorepo build + --continue test sweep running as the PR's own CI verifies.

🤖 Generated with Claude Code

https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H


Generated by Claude Code

…ive baseline, anchor binding gate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 9, 2026 4:23am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/core, @objectstack/plugin-security, @objectstack/runtime, @objectstack/spec.

111 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx (via @objectstack/core)
  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/knowledge-rag.mdx (via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx (via @objectstack/core)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/api/wire-format.mdx (via @objectstack/runtime)
  • content/docs/automation/approvals.mdx (via packages/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via @objectstack/runtime, packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/core, packages/runtime, packages/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/index.mdx (via @objectstack/runtime)
  • content/docs/deployment/migration-from-objectql.mdx (via @objectstack/core)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/runtime)
  • content/docs/deployment/single-project-mode.mdx (via @objectstack/runtime)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/vercel.mdx (via @objectstack/runtime)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/core)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/core)
  • content/docs/permissions/access-recipes.mdx (via packages/plugins/plugin-security)
  • content/docs/permissions/authentication.mdx (via @objectstack/core, @objectstack/runtime)
  • content/docs/permissions/authorization.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via packages/plugins/plugin-security, @objectstack/spec)
  • content/docs/permissions/profiles.mdx (via @objectstack/spec)
  • content/docs/permissions/roles.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/anatomy.mdx (via @objectstack/core)
  • content/docs/plugins/development.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/core, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/core, @objectstack/plugin-security, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/objectos/http-protocol.mdx (via @objectstack/runtime)
  • content/docs/protocol/objectos/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/index.mdx (via @objectstack/core, @objectstack/runtime)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/core, @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/core, @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/core, @objectstack/plugin-security, @objectstack/runtime, @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/role-based-interfaces.mdx (via packages/plugins/plugin-security)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…or exports (6 additions, 0 breaking)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H
…e the #1985 owner policies to org_member

The additive `everyone` baseline (P2) surfaced a latent hole: the policy
`positions` field was an UNENFORCED property (ADR-0049 class) — a
members-only restriction inside the baseline set silently bound everyone
who resolved it, which pre-anchor meant "users with no other grants" and
post-anchor meant "every authenticated principal" (the two-doors dogfood
regression: an admin editing an env-authored set hit the baseline's
created_by RLS and got 403).

getApplicablePolicies now filters by the caller's held positions when a
policy declares a domain, and the two #1985 owner-scoped write/delete
policies in member_default declare `positions: ['org_member']` — the
rank-and-file identity, matching the pre-anchor behavior where org/platform
admins simply never resolved this set. tenant_isolation stays undomained
(it is correct for every principal).

Dogfood 39 files / 191 tests green; plugin-security 198 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H
@os-zhuang
os-zhuang marked this pull request as ready for review July 9, 2026 04:35
@os-zhuang
os-zhuang merged commit 01917c2 into main Jul 9, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/adr-0090-p2-audience-anchors branch July 9, 2026 04:35
os-zhuang added a commit that referenced this pull request Jul 9, 2026
…on Model v2 vocabulary (ADR-0090) (#2717)

- roles.mdx → positions.mdx: flat positions (岗位), assignment BU anchor,
  built-in identity positions, everyone/guest audience anchors; the
  hierarchy narrative moves to business units.
- profiles.mdx → migration tombstone: the Profile concept was removed
  (D2); maps each former use to everyone-anchor bindings, isDefault
  suggestions, and position-bound sets.
- permission-sets.mdx: rewritten as the single capability container —
  union semantics, access depth (moved here from profiles), capabilities,
  built-in sets (additive member_default baseline), governed assignment
  tables, isDefault suggestion, adminScope delegated administration,
  package provenance.
- sharing-rules.mdx: OWD default corrected to fail-closed private (D1 —
  the page previously documented the pre-v2 fail-open default), canonical
  four values only, externalSharingModel dial (D11), recipient types
  position / unit_and_subordinates / team.
- authorization.mdx: position vocabulary, D1/D11 in the enforcement
  chain, delegated-admin gate in anti-escalation, new explain-engine
  section (D6), D7 linter + access-matrix snapshot added to governance,
  ADR-0090 in the index.
- permissions-matrix.mdx: role-hierarchy section replaced with
  business-unit hierarchy & positions; isProfile removed from samples;
  position recipients.
- permission-metadata.mdx: isProfile → isDefault/adminScope in the field
  table; union-semantics section replaces Profile-vs-Set;
  current_user.positions.
- index.mdx: five-concepts overview, v2 implementation-status callout,
  best practices and example updated.
- access-recipes.mdx / field-level-security.mdx: link + heading fixes.

Authoritative reference: docs/design/permission-model.md; decision
record: ADR-0090 (P1 #2697, P2 #2708, P3 #2711, P4 #2716).


Claude-Session: https://claude.ai/code/session_012oLzaP8n7A3YKFmgaHWC8H

Co-authored-by: Claude <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 20, 2026
…s (designer parity, #3304) (#3327)

assignment, create/update/delete/get_record, and screen now publish configSchemas mirroring objectui's hardcoded field groups — free-form maps as JSON-Schema open objects (additionalProperties: true) rendered by the designer's keyValue editor (objectui #2708), object references as xRef, screen's visibleWhen as an xExpression CEL column. decision/wait/script/subflow stay deliberately schemaless (documented + tested — a partial schema would drop editors). Verified: parity tests, tsc, 335-test suite green. Descriptor metadata only; no runtime behavior change.

Closes the #3304 implementation series: loop (#3313), map (#3321), objectui adapter (#2708), this PR.
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Jul 20, 2026
…d + Console)

Continues the v16 page from the latest front/back-end code. Since the rc.0 cut,
9 backend changesets landed and the objectui pin advanced 94d4876 -> af1b0db
(objectui objectstack-ai#2706-objectstack-ai#2736). Sourced from each repo's own changesets.

- Retitles the now-stale 'pending the next console pin' subsection: those 4
  frontend items (objectui#2701/objectstack-ai#2706/objectstack-ai#2707/objectstack-ai#2708) are now bundled as the pin
  advanced; points to the new running section.
- Adds a 'Landed since 16.0.0-rc.0' section:
  - Breaking/behavior: aiStudio/aiSeat alias removal (objectstack-ai#3308); date-arithmetic
    now a build-time error (objectstack-ai#3306); checkboxes per-option visibleWhen + string
    option matching (objectstack-ai#3350).
  - New backend: formula null-guard/floor/ceil (objectstack-ai#3306); engine-owned managedBy
    bucket (ADR-0103 addendum, objectstack-ai#3343); approvals viewer gating (objectstack-ai#3344) +
    decision attachments (objectstack-ai#3332); discovery transactionalBatch bit (objectstack-ai#3298);
    action resultDialog i18n (objectstack-ai#3347); collab-notification/storage localization
    + wired notifications REST routes (objectstack-ai#3354).
  - Console (now bundled): option-widget visibleWhen parity, approvals-inbox
    server-viewer gating + composer retirement, related-list pagination,
    inline-analytics renderer retirement, authenticated api-fetch threading,
    result-dialog i18n, engine-owned bucket UI, write-failure surfacing.
- Adds aiStudio/aiSeat and date-arithmetic to the upgrade checklist; updates
  the Console-section intro for the advanced pin.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AHVoqyH9VAjmbyMN1Ri2jf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants