Skip to content

feat(security): ADR-0057 ERP authorization core + open/paid hierarchy seam (closes #2077)#2084

Merged
xuyushun441-sys merged 4 commits into
mainfrom
adr/0057-erp-authz-core
Jun 21, 2026
Merged

feat(security): ADR-0057 ERP authorization core + open/paid hierarchy seam (closes #2077)#2084
xuyushun441-sys merged 4 commits into
mainfrom
adr/0057-erp-authz-core

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

What

ADR-0057 — a Dataverse-core / Salesforce-discipline authorization model on top of the existing widening layer, the open/paid seam that keeps hierarchy-relative visibility an enterprise capability, and the close-out of #2077 (declared roles/sharingRules now seed at boot).

Highlights (each with a runtime dogfood proof)

  • D1 scope-depth grants own / own_and_reports / unit / unit_and_below / org — security stashes the grant's depth, sharing widens the owner-match (owner_id IN …) and still OR-s in shares. No RLS-compiler change. showcase-scope-depth (5/5, incl. fail-closed).
  • D2 sys_departmentsys_business_unit clean pre-launch rename (object + member table + graph + recipient enum + fields + i18n).
  • D4 sys_user_role — platform-owned RBAC assignment, decoupled from better-auth's membership role; merged in resolve-execution-context.
  • D5 role_and_subordinates re-homed onto the working BU subtree. showcase-bu-hierarchy-sharing (4/4).
  • D6 / ADR-0056 D6: activate declarative roles + sharingRules at runtime (enforce-or-remove) — unblocks role_and_subordinates showcase demo #2077 seed declared roles + sharingRules at boot (CEL→criteria_json for field-equality; owner/group rules honestly skipped as experimental). showcase-declarative-rbac-seeding (4/4).
  • Open/paid seam — hierarchy scopes delegate to a pluggable IHierarchyScopeResolver; the open edition ships none and fails closed to owner-only (never fail-open); defineStack errors if a grant uses a hierarchy scope without requires: ['hierarchy-security']. The enterprise resolver lives in the private @objectstack/security-enterprise.
  • Bug fixengine.find({filter}) was silently ignored (driver reads where) → over-grant; normalized filterwhere in the engine.
  • D8 authz-conformance matrix rows for the new primitives (CI-checked).

Tests

Full build 75/75 · objectql 670 · runtime 395 · plugin-security 112 · plugin-sharing 63 · plugin-approvals 90 · full dogfood 21 files / 123 tests — all green; no blast-radius regression from activating declared rules.

Notes

  • Pre-launch clean rename (no back-compat aliases) — see ADR-0057.
  • Commercial open/paid boundary is documented in the private cloud repo (ADR-0016); this PR is the open-side seam only.

Closes #2077.

🤖 Generated with Claude Code

os-zhuang and others added 2 commits June 21, 2026 02:24
…ss units, seed declared RBAC (#2077)

Dataverse-core / Salesforce-discipline hybrid. Adds the ERP partition + scope-depth
+ hierarchy-rollup core on top of the existing widening layer, and makes the role
system self-owned (decoupled from better-auth membership). Closes #2077.

- D1 scope-depth grants on ObjectPermission (own/unit/unit_and_below/org): security
  stashes the grant's depth, sharing widens the owner-match (owner IN unit-set) and
  still OR's in shares. No RLS-compiler change. Proof: showcase-scope-depth (4).
- D2 rename sys_department → sys_business_unit (pre-launch clean rename, no aliases):
  object + member table + BusinessUnitGraphService + recipient enum + fields + i18n.
- D3 BU rollup via BusinessUnitGraphService subtree expansion.
- D4 sys_user_role (platform-owned RBAC assignment); resolve-execution-context merges
  it with sys_member.role.
- D5 re-home role_and_subordinates onto the working BU subtree. Proof:
  showcase-bu-hierarchy-sharing (4).
- D6 seed stack-declared roles + sharingRules at boot (bootstrapDeclaredRoles /
  bootstrapDeclaredSharingRules; AppPlugin surfaces security metadata; seeders read
  the engine registry; field-equality CEL→criteria_json; owner/group experimental).
  Proof: showcase-declarative-rbac-seeding (4). Closes #2077.
- D8 authz-conformance matrix rows for the new primitives.
- Fix latent over-grant: engine.find({filter}) was silently ignored (driver reads
  `where`); normalize filter→where in the engine. objectql 670 green.

Full dogfood 21 files / 122 tests; objectql 670 / runtime 395 / security 112 /
sharing 63 / approvals 90 — all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uggable IHierarchyScopeResolver

Hierarchy-relative visibility (scope unit/unit_and_below/own_and_reports) is an
enterprise capability, not open-core. The open framework keeps the secure baseline
(RLS/sharing/roles/own·org scope, BU data model + explicit business_unit recipient)
and a pluggable seam; the resolver implementation ships in the private
@objectstack/security-enterprise.

- spec/contracts: IHierarchyScopeResolver + HierarchyScope.
- plugin-sharing: SharingService delegates unit*/own_and_reports to a late-bound
  resolver (hierarchy-scope-resolver service); fails CLOSED to owner-only when absent
  (never fail-open). Removed the BU/manager rollup logic from the open SharingService.
- spec/defineStack: compile-error if a grant uses a hierarchy scope without
  requires:['hierarchy-security'] (ADR-0049 — no silent lie).
- dogfood showcase-scope-depth: registers a reference resolver (test fixture) to prove
  the seam (5/5), incl. a fail-closed case (no resolver → owner-only).
- authz-conformance + ADR-0057: record the seam.

Full build 75/75; spec 6599; dogfood 21/123; sharing 63; security 112 — all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 21, 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 Jun 21, 2026 2:57am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests size/xl labels Jun 21, 2026
@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 8 package(s): @objectstack/dogfood, @objectstack/objectql, @objectstack/platform-objects, @objectstack/plugin-approvals, @objectstack/plugin-security, @objectstack/plugin-sharing, @objectstack/runtime, @objectstack/spec.

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

  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/cloud-artifact-api.mdx (via packages/runtime, packages/spec)
  • content/docs/concepts/cluster-semantics.mdx (via @objectstack/spec)
  • content/docs/concepts/core/services.mdx (via @objectstack/objectql)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/objectql, @objectstack/plugin-approvals, @objectstack/plugin-security, @objectstack/runtime, @objectstack/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 @objectstack/objectql, packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/runtime, packages/spec)
  • content/docs/concepts/packages.mdx (via @objectstack/objectql, @objectstack/platform-objects, @objectstack/plugin-approvals, @objectstack/plugin-security, @objectstack/plugin-sharing, @objectstack/runtime, @objectstack/spec)
  • content/docs/concepts/setup-app.mdx (via @objectstack/platform-objects, @objectstack/spec)
  • content/docs/concepts/skills.mdx (via @objectstack/spec)
  • content/docs/concepts/webhook-delivery.mdx (via @objectstack/spec)
  • content/docs/getting-started/architecture.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/getting-started/core-concepts.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/guides/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/guides/ai-capabilities.mdx (via @objectstack/spec)
  • content/docs/guides/airtable-dashboard-analysis.mdx (via @objectstack/spec)
  • content/docs/guides/analytics-datasets.mdx (via @objectstack/spec)
  • content/docs/guides/api-reference.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/guides/authentication.mdx (via @objectstack/objectql, @objectstack/runtime)
  • content/docs/guides/business-logic.mdx (via @objectstack/plugin-approvals, @objectstack/spec)
  • content/docs/guides/cheatsheets/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/error-catalog.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-type-gallery.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-validation-rules.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx (via packages/plugins/plugin-security, packages/plugins/plugin-sharing, @objectstack/spec)
  • content/docs/guides/cheatsheets/protocol-diagram.mdx (via packages/spec)
  • content/docs/guides/cheatsheets/query-cheat-sheet.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/quick-reference.mdx (via @objectstack/spec)
  • content/docs/guides/client-sdk.mdx (via @objectstack/spec)
  • content/docs/guides/cloud-deployment.mdx (via @objectstack/runtime)
  • content/docs/guides/common-patterns.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/auth-service.mdx (via packages/spec)
  • content/docs/guides/contracts/cache-service.mdx (via packages/spec)
  • content/docs/guides/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/index.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/guides/contracts/storage-service.mdx (via packages/spec)
  • content/docs/guides/data-modeling.mdx (via @objectstack/spec)
  • content/docs/guides/deployment-vercel.mdx (via @objectstack/objectql, @objectstack/runtime, @objectstack/spec)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/guides/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/guides/formula.mdx (via packages/objectql, @objectstack/spec)
  • content/docs/guides/hook-bodies.mdx (via @objectstack/runtime, packages/spec)
  • content/docs/guides/kernel-services.mdx (via @objectstack/objectql, @objectstack/spec)
  • content/docs/guides/metadata/dashboard.mdx (via @objectstack/plugin-security, @objectstack/spec)
  • content/docs/guides/metadata/field.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/flow.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/index.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/object.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/validation.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/workflow.mdx (via @objectstack/spec)
  • content/docs/guides/objectql-migration.mdx (via @objectstack/objectql)
  • content/docs/guides/packages.mdx (via @objectstack/objectql, @objectstack/platform-objects, @objectstack/plugin-approvals, @objectstack/plugin-security, @objectstack/plugin-sharing, @objectstack/runtime, @objectstack/spec)
  • content/docs/guides/plugin-chatbot-integration.mdx (via @objectstack/runtime)
  • content/docs/guides/plugin-development.mdx (via @objectstack/spec)
  • content/docs/guides/plugins.mdx (via @objectstack/objectql, @objectstack/plugin-security, @objectstack/spec)
  • content/docs/guides/production-readiness.mdx (via @objectstack/runtime)
  • content/docs/guides/project-scoping.mdx (via @objectstack/spec)
  • content/docs/guides/public-forms.mdx (via @objectstack/spec)
  • content/docs/guides/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/index.mdx (via packages/spec)
  • content/docs/guides/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/guides/security.mdx (via @objectstack/plugin-security, @objectstack/plugin-sharing, @objectstack/spec)
  • content/docs/guides/seed-data.mdx (via @objectstack/spec)
  • content/docs/guides/single-project-mode.mdx (via @objectstack/runtime)
  • content/docs/guides/skills.mdx (via @objectstack/spec)
  • content/docs/guides/standards.mdx (via @objectstack/spec)
  • content/docs/guides/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @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/objectql, @objectstack/runtime)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/runtime, @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @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/plugins/plugin-sharing, packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/objectql, @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/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/objectql, @objectstack/plugin-approvals, @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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r (ADR-0057)

Spec property liveness gate (ADR-0054) requires every authorable property be
classified. readScope/writeScope are live (consumed by permission-evaluator
getEffectiveScope + sharing owner-match; hierarchy values delegated to the
enterprise resolver, fail-closed in open).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xuyushun441-sys
xuyushun441-sys merged commit e16f2a8 into main Jun 21, 2026
17 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the adr/0057-erp-authz-core branch June 21, 2026 03:22
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/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ADR-0056 D6: activate declarative roles + sharingRules at runtime (enforce-or-remove) — unblocks role_and_subordinates showcase demo

2 participants