docs: amend constitution to v1.8.2 (scope fields)

This commit is contained in:
Ahmed Darrazi 2026-02-14 19:44:35 +01:00
parent 90c4727add
commit e720b9a912
4 changed files with 55 additions and 11 deletions

View File

@ -1,14 +1,15 @@
<!--
Sync Impact Report
- Version change: 1.8.0 → 1.8.1
- Version change: 1.8.1 → 1.8.2
- Modified principles:
- Workspace Isolation is Non-negotiable (new core principle)
- Tenant Isolation is Non-negotiable (clarified tenant-plane scope + canonical tenantless views)
- RBAC-UX-002 / RBAC-UX-003 (clarified workspace + tenant membership semantics)
- Filament UI — Action Surface Contract (NON-NEGOTIABLE) (added micro-rules + clarified CI enforcement phrasing)
- RBAC Context — Planes, Roles, and Auditability (clarified admin vs tenant-context vs workspace-context)
- Tenant Isolation is Non-negotiable (added scope + ownership rules)
- RBAC-UX-007 — Global search must be tenant-safe (added workspace-context rules)
- Filament UI — Action Surface Contract (NON-NEGOTIABLE) (added required spec scope fields)
- Added sections:
- Workspace Isolation is Non-negotiable
- Scope & Ownership Clarification (SCOPE-001)
- Spec Scope Fields (SCOPE-002)
- Removed sections: None
- Templates requiring updates:
- ✅ .specify/templates/plan-template.md
@ -56,11 +57,27 @@ ### Tenant Isolation is Non-negotiable
- Tenant membership is an isolation boundary. If the actor is not entitled to the tenant scope, the system MUST respond as
deny-as-not-found (404).
Scope & Ownership Clarification (SCOPE-001)
- The system MUST enforce a strict ownership model:
- Workspace-owned objects define standards, templates, and global configuration (e.g., Baseline Profiles, Notification Targets, Alert Routing Rules, Framework/Control catalogs).
- Tenant-owned objects represent observed state, evidence, and operational artifacts for a specific tenant (e.g., Inventory, Backups/Snapshots, OperationRuns for tenant operations, Drift/Findings, Exceptions/Risk Acceptance, EvidenceItems, StoredReports/Exports).
- Workspace-owned objects MUST NOT directly embed or persist tenant-owned records (no “copying tenant data into templates”).
- Tenant-owned objects MUST always be bound to an established workspace + tenant scope at authorization time.
Database convention:
- Tenant-owned tables MUST include workspace_id and tenant_id as NOT NULL.
- Workspace-owned tables MUST include workspace_id and MUST NOT include tenant_id.
- Exception: OperationRun MAY have tenant_id nullable to support canonical workspace-context monitoring views; however, revealing any tenant-bound runs still MUST enforce entitlement checks to the referenced tenant scope.
### RBAC & UI Enforcement Standards (RBAC-UX)
RBAC Context — Planes, Roles, and Auditability
- The platform MUST maintain two strictly separated authorization planes:
- Tenant plane (`/admin/t/{tenant}`): authenticated Entra users (`users`), authorization is tenant-scoped.
- Tenant/Admin plane (`/admin`): authenticated Entra users (`users`).
- Tenant-context routes (`/admin/t/{tenant}/...`) are tenant-scoped.
- Workspace-context canonical routes (`/admin/...`, e.g. Monitoring/Operations) are tenantless by URL but MUST still enforce workspace + tenant entitlement before revealing tenant-owned records.
- Platform plane (`/system`): authenticated platform users (`platform_users`), authorization is platform-scoped.
- Cross-plane access MUST be deny-as-not-found (404) (not 403) to avoid route enumeration.
- Tenant role semantics MUST remain least-privilege:
@ -108,9 +125,12 @@ ### RBAC & UI Enforcement Standards (RBAC-UX)
- CI MUST fail if unknown/unregistered capabilities are used.
RBAC-UX-007 — Global search must be tenant-safe
- Global search results MUST be scoped to the current tenant.
- Global search MUST be context-safe (workspace-context vs tenant-context).
- Non-members MUST never learn about resources in other tenants (no results, no hints).
- If a result exists but is not accessible, it MUST be treated as not found (404 semantics).
- In workspace-context (no active tenant selected), Global Search MUST NOT return tenant-owned results.
- It MAY search workspace-owned objects only (e.g., Tenants list entries, Baseline Profiles, Alert Rules/Targets, workspace settings).
- If tenant-context is active, Global Search MUST be scoped to the current tenant only (existing rule remains).
RBAC-UX-008 — Regression guards are mandatory
- The repo MUST include RBAC regression tests asserting at least:
@ -178,6 +198,17 @@ ### Filament UI — Action Surface Contract (NON-NEGOTIABLE)
- A change is not “Done” unless the Action Surface Contract is met OR an explicit exemption exists with documented reason.
- CI MUST run an automated Action Surface Contract check (test suite and/or command) that fails when required surfaces are missing.
Spec Scope Fields (SCOPE-002)
- Every feature spec MUST declare:
- Scope: workspace | tenant | canonical-view
- Primary Routes
- Data Ownership: workspace-owned vs tenant-owned tables/records impacted
- RBAC: membership requirements + capability requirements
- For canonical-view specs, the spec MUST define:
- Default filter behavior when tenant-context is active (e.g., prefilter to current tenant)
- Explicit entitlement checks that prevent cross-tenant leakage
### Data Minimization & Safe Logging
- Inventory MUST store only metadata + whitelisted `meta_jsonb`.
- Payload-heavy content belongs in immutable snapshots/backup storage, not Inventory.
@ -213,4 +244,4 @@ ### Versioning Policy (SemVer)
- **MINOR**: new principle/section or materially expanded guidance.
- **MAJOR**: removing/redefining principles in a backward-incompatible way.
**Version**: 1.8.1 | **Ratified**: 2026-01-03 | **Last Amended**: 2026-02-09
**Version**: 1.8.2 | **Ratified**: 2026-01-03 | **Last Amended**: 2026-02-14

View File

@ -35,7 +35,7 @@ ## Constitution Check
- Read/write separation: any writes require preview + confirmation + audit + tests
- Graph contract path: Graph calls only via `GraphClientInterface` + `config/graph_contracts.php`
- Deterministic capabilities: capability derivation is testable (snapshot/golden tests)
- RBAC-UX: two planes (/admin vs /system) remain separated; cross-plane is 404; non-member tenant access is 404; member-but-missing-capability is 403; authorization checks use Gates/Policies + capability registries (no raw strings, no role-string checks)
- RBAC-UX: two planes (/admin vs /system) remain separated; cross-plane is 404; tenant-context routes (/admin/t/{tenant}/...) are tenant-scoped; canonical workspace-context routes under /admin remain tenant-safe; non-member tenant/workspace access is 404; member-but-missing-capability is 403; authorization checks use Gates/Policies + capability registries (no raw strings, no role-string checks)
- Workspace isolation: non-member workspace access is 404; tenant-plane routes require an established workspace context; workspace context switching is separate from Filament Tenancy
- RBAC-UX: destructive-like actions require `->requiresConfirmation()` and clear warning text
- RBAC-UX: global search is tenant-scoped; non-members get no hints; inaccessible results are treated as not found (404 semantics)

View File

@ -5,6 +5,18 @@ # Feature Specification: [FEATURE NAME]
**Status**: Draft
**Input**: User description: "$ARGUMENTS"
## Spec Scope Fields *(mandatory)*
- **Scope**: [workspace | tenant | canonical-view]
- **Primary Routes**: [List the primary routes/pages affected]
- **Data Ownership**: [workspace-owned vs tenant-owned tables/records impacted]
- **RBAC**: [membership requirements + capability requirements]
For canonical-view specs, the spec MUST define:
- **Default filter behavior when tenant-context is active**: [e.g., prefilter to current tenant]
- **Explicit entitlement checks preventing cross-tenant leakage**: [Describe checks]
## User Scenarios & Testing *(mandatory)*
<!--
@ -83,7 +95,7 @@ ## Requirements *(mandatory)*
If security-relevant DB-only actions intentionally skip `OperationRun`, the spec MUST describe `AuditLog` entries.
**Constitution alignment (RBAC-UX):** If this feature introduces or changes authorization behavior, the spec MUST:
- state which authorization plane(s) are involved (tenant `/admin/t/{tenant}` vs platform `/system`),
- state which authorization plane(s) are involved (tenant/admin `/admin` + tenant-context `/admin/t/{tenant}/...` vs platform `/system`),
- ensure any cross-plane access is deny-as-not-found (404),
- explicitly define 404 vs 403 semantics:
- non-member / not entitled to workspace scope OR tenant scope → 404 (deny-as-not-found)

View File

@ -20,6 +20,7 @@ # Tasks: [FEATURE NAME]
- non-member / not entitled to workspace scope OR tenant scope → 404 (deny-as-not-found)
- member but missing capability → 403,
- capability registry usage (no raw capability strings; no role-string checks in feature code),
- stating which authorization plane(s) are involved (tenant/admin `/admin` + tenant-context `/admin/t/{tenant}/...` vs platform `/system`),
- tenant-safe global search scoping (no hints; inaccessible results treated as 404 semantics),
- destructive-like actions use `->requiresConfirmation()` (authorization still server-side),
- cross-plane deny-as-not-found (404) checks where applicable,