Added jobs, controllers, and PDF generation logic for management report runtime as defined in Spec 379. Includes artifact migrations, payload builders, and testing coverage. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #450
314 lines
11 KiB
Markdown
314 lines
11 KiB
Markdown
# Spec Candidate 380 - Provider Resource Identity & Binding Foundation v1
|
|
|
|
## Candidate Status
|
|
|
|
Candidate for implementation.
|
|
|
|
This candidate introduces the provider-agnostic identity and binding foundation required to resolve baseline subject ambiguity, built-in/default canonicalization, and future provider/resource-class expansion.
|
|
|
|
## Spec Candidate Check
|
|
|
|
- **Problem**: Baseline compare and capture can still treat display-name-derived `subject_key` values as if they were stable identity, which creates ambiguous or false missing states for built-ins, defaults, virtual targets, foundation resources, and tenant-owned duplicate names.
|
|
- **Today's failure**: Operators can see `ambiguous_match`, `policy_record_missing`, or `foundation_not_policy_backed` without a durable way to distinguish real duplicate tenant resources from provider defaults, inventory-only coverage, unsupported classes, or accepted limitations.
|
|
- **User-visible improvement**: Operators get auditable, workspace/environment/provider-scoped binding truth that later compare, evidence, review, and restore workflows can trust without pretending display names are identity.
|
|
- **Smallest enterprise-capable version**: Add the binding table, core value objects, status/mode taxonomy, isolation rules, and audit contract only; do not rebuild matching, UI, evidence, restore, or review behavior in this slice.
|
|
- **Explicit non-goals**: No full baseline compare matching rewrite, no resolution UI, no evidence/review readiness changes, no generic workflow engine, no restore redesign, and no production multi-provider implementation beyond fake-provider contract tests.
|
|
- **Permanent complexity imported**: One persisted binding table, resource identity value object, canonical subject key evolution, descriptor object, resolution mode/status enums, subject/resource class taxonomy, audit requirements, model tests, and workspace/environment isolation tests.
|
|
- **Why now**: Specs 381-384 depend on stable identity; without this foundation, later matching and customer-readiness work would keep encoding display-name ambiguity and false blocker states.
|
|
- **Why not local**: A local compare-only patch cannot preserve manual decisions, exclusions, accepted limitations, or provider-default classification across future compares, evidence snapshots, and review packs.
|
|
- **Approval class**: Core Enterprise.
|
|
- **Red flags triggered**: New axes, new persisted truth, new meta-infrastructure, foundation terminology, and multiple follow-up specs in one domain. The defense is that identity ambiguity currently affects compare trust, evidence gaps, review readiness, and auditability; persistence is required because operator decisions must outlive a single run.
|
|
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 1 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 10/12**
|
|
- **Decision**: approve as the first candidate, with strict scope control and no matching/UI expansion.
|
|
|
|
## Proportionality Review
|
|
|
|
1. **Current operator problem**: Operators cannot tell whether compare blockers are real duplicate resources, expected provider defaults, unsupported coverage, or missing local evidence.
|
|
2. **Why existing structure is insufficient**: `policy_type + subject_key` and current resolution outcomes do not provide durable provider identity or auditable operator decisions.
|
|
3. **Narrowest correct implementation**: Persist only bindings and identity primitives; all matching, result semantics, UI, and readiness work stays in later candidates.
|
|
4. **Ownership cost**: Baseline/domain owners must maintain binding statuses, resolution modes, resource descriptors, and audit semantics.
|
|
5. **Rejected alternative**: Snapshot-JSON-only or baseline-only annotations were rejected because they would not survive across compare runs or support revocation/audit.
|
|
6. **Current-release truth or future prep**: Current-release trust foundation required by existing compare ambiguity and review-readiness gaps; not speculative multi-provider runtime work.
|
|
|
|
## Problem
|
|
|
|
TenantPilot baseline compare currently relies too heavily on `policy_type + subject_key`, where `subject_key` can be derived from normalized display names. This is not enterprise-safe because names are not stable identity.
|
|
|
|
The current model cannot reliably distinguish:
|
|
|
|
- provider-owned built-ins,
|
|
- virtual assignment targets,
|
|
- tenant-owned resources,
|
|
- foundation objects,
|
|
- policy objects,
|
|
- unsupported resource classes,
|
|
- excluded/non-governed resources,
|
|
- duplicate display names,
|
|
- accepted limitations.
|
|
|
|
This causes false or overloaded compare states such as:
|
|
|
|
- `ambiguous_match`,
|
|
- `policy_record_missing`,
|
|
- `foundation_not_policy_backed`.
|
|
|
|
## Goal
|
|
|
|
Create a durable, provider-agnostic identity and binding foundation that future compare, evidence, review, restore, and governance workflows can use.
|
|
|
|
This spec does not yet fully rebuild baseline matching or UI. It creates the data model and core primitives.
|
|
|
|
## Scope
|
|
|
|
### In Scope
|
|
|
|
- Introduce `ResourceIdentity` value object.
|
|
- Introduce or evolve `CanonicalSubjectKey`.
|
|
- Introduce `ProviderResourceDescriptor`.
|
|
- Add persistent `provider_resource_bindings` table.
|
|
- Add resolution mode/status enums.
|
|
- Add subject/resource class taxonomy for baseline resolution.
|
|
- Enforce workspace/environment/provider isolation.
|
|
- Add audit support for manual bindings, exclusions, accepted limitations, and revocations.
|
|
- Add provider-agnostic contracts that future provider adapters can implement.
|
|
- Add unit tests for value objects and binding model behavior.
|
|
|
|
### Out of Scope
|
|
|
|
- Full baseline compare matching rewrite.
|
|
- Built-in canonicalization implementation.
|
|
- Resolution UI.
|
|
- Evidence/review readiness changes.
|
|
- Generic workflow engine.
|
|
- Full historical `OperationRun` backfill.
|
|
- Restore redesign.
|
|
- Multi-provider production implementation beyond fake-provider contract tests.
|
|
|
|
## Design Principles
|
|
|
|
- Display name is not identity.
|
|
- Provider object ID or canonical provider key wins over display name.
|
|
- Core logic must remain provider-agnostic.
|
|
- Provider-specific knowledge belongs behind adapters/registries.
|
|
- Bindings are persisted state, not workflow tasks.
|
|
- Manual decisions must be auditable.
|
|
- No fake green state.
|
|
- No customer blocker for expected provider defaults once canonicalized.
|
|
|
|
## Data Model
|
|
|
|
Add table:
|
|
|
|
```text
|
|
provider_resource_bindings
|
|
```
|
|
|
|
Suggested fields:
|
|
|
|
```text
|
|
id
|
|
workspace_id
|
|
environment_id nullable
|
|
provider_key
|
|
provider_connection_id nullable
|
|
binding_scope
|
|
subject_domain
|
|
subject_class
|
|
subject_type
|
|
subject_key
|
|
canonical_subject_key
|
|
provider_resource_type nullable
|
|
provider_resource_id nullable
|
|
provider_resource_external_id nullable
|
|
provider_resource_discriminator nullable
|
|
provider_resource_fingerprint nullable
|
|
binding_status
|
|
resolution_mode
|
|
resolution_reason
|
|
operator_note nullable
|
|
source_operation_run_id nullable
|
|
source_baseline_snapshot_id nullable
|
|
source_baseline_compare_run_id nullable
|
|
source_inventory_item_id nullable
|
|
source_policy_version_id nullable
|
|
decided_by_user_id nullable
|
|
decided_at nullable
|
|
is_active
|
|
valid_from nullable
|
|
valid_until nullable
|
|
created_at
|
|
updated_at
|
|
```
|
|
|
|
## Binding Status
|
|
|
|
Required values:
|
|
|
|
```text
|
|
active
|
|
inactive
|
|
superseded
|
|
revoked
|
|
```
|
|
|
|
## Resolution Modes
|
|
|
|
Required v1 modes:
|
|
|
|
```text
|
|
exact_provider_identity
|
|
canonical_builtin
|
|
canonical_virtual_target
|
|
manual_binding
|
|
excluded_non_governed
|
|
accepted_limitation
|
|
unsupported_coverage
|
|
missing_expected
|
|
```
|
|
|
|
## Subject Classes
|
|
|
|
Minimum v1 classes:
|
|
|
|
```text
|
|
policy
|
|
foundation
|
|
assignment_target
|
|
virtual_assignment_target
|
|
provider_builtin
|
|
provider_default
|
|
unsupported
|
|
unknown
|
|
```
|
|
|
|
Where possible, reuse or extend the existing governance subject taxonomy instead of creating duplicate enums.
|
|
|
|
## Isolation Rules
|
|
|
|
Bindings must be scoped by:
|
|
|
|
```text
|
|
workspace_id
|
|
environment_id where applicable
|
|
provider_key
|
|
provider_connection_id where applicable
|
|
```
|
|
|
|
No binding may be used across workspaces.
|
|
|
|
Environment-specific binding is the default.
|
|
|
|
Workspace-wide binding is only allowed for explicitly workspace-level subjects.
|
|
|
|
## New Core Objects
|
|
|
|
### ResourceIdentity
|
|
|
|
Represents stable provider resource identity.
|
|
|
|
Must support:
|
|
|
|
- provider key,
|
|
- resource type,
|
|
- provider resource ID,
|
|
- external ID,
|
|
- discriminator,
|
|
- fingerprint/hash,
|
|
- built-in/default/virtual flags,
|
|
- tenant-owned flag.
|
|
|
|
Must not require display name as identity.
|
|
|
|
### CanonicalSubjectKey
|
|
|
|
Represents TenantPilot's stable internal key for a governed subject.
|
|
|
|
Examples:
|
|
|
|
```text
|
|
provider:{provider_key}:policy:{provider_resource_type}:{provider_resource_id}
|
|
provider:{provider_key}:builtin:{canonical_discriminator}
|
|
provider:{provider_key}:virtual-target:{canonical_discriminator}
|
|
provider:{provider_key}:foundation:{resource_type}:{provider_resource_id}
|
|
```
|
|
|
|
Provider-specific canonical values are supplied by adapters.
|
|
|
|
### ProviderResourceDescriptor
|
|
|
|
Represents a candidate provider resource for matching/resolution.
|
|
|
|
Should contain:
|
|
|
|
- resource identity,
|
|
- display label,
|
|
- subject class,
|
|
- provider resource type,
|
|
- support level,
|
|
- source inventory item,
|
|
- source policy version,
|
|
- source operation run,
|
|
- fingerprint/hash where available.
|
|
|
|
## Audit Requirements
|
|
|
|
Every manual or operator-driven binding decision must record:
|
|
|
|
- actor,
|
|
- timestamp,
|
|
- workspace,
|
|
- environment,
|
|
- provider,
|
|
- subject,
|
|
- previous decision,
|
|
- new decision,
|
|
- reason/note,
|
|
- source operation run/compare where available.
|
|
|
|
Revocation must also be audited.
|
|
|
|
Automatic high-confidence canonical built-in bindings may be stored without operator note, but should remain traceable.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- `provider_resource_bindings` exists with workspace/environment/provider isolation.
|
|
- Only one active binding exists per scoped canonical subject unless versioning explicitly allows otherwise.
|
|
- `ResourceIdentity` can represent tenant-owned, built-in, virtual, and unsupported resources.
|
|
- `CanonicalSubjectKey` does not depend on display name alone.
|
|
- Manual binding, exclusion, accepted limitation, unsupported coverage, and revocation modes are representable.
|
|
- Audit records are emitted for manual changes.
|
|
- No baseline compare behavior is made worse.
|
|
- Existing baseline compare records remain readable.
|
|
|
|
## Required Tests
|
|
|
|
- Unit test: `ResourceIdentity` does not require display name.
|
|
- Unit test: `CanonicalSubjectKey` includes provider/resource class/type.
|
|
- Unit test: built-in and tenant-owned identities produce distinct keys.
|
|
- Unit test: active binding uniqueness is enforced per workspace/environment/provider/canonical key.
|
|
- Feature test: binding cannot cross workspace boundary.
|
|
- Feature test: revoked binding is no longer active.
|
|
- Feature test: operator note is required for manual binding/exclusion/accepted limitation.
|
|
- Contract test: fake provider can create provider resource descriptors.
|
|
|
|
## Validation Commands
|
|
|
|
```bash
|
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/Baselines
|
|
```
|
|
|
|
Add new dedicated tests for provider resource bindings and resource identity.
|
|
|
|
## Risks
|
|
|
|
- Over-generalizing into workflow engine.
|
|
- Creating a second taxonomy parallel to existing governance taxonomy.
|
|
- Allowing bindings to leak across workspaces/environments.
|
|
- Treating display names as stable keys again through the back door.
|
|
|
|
## Recommendation
|
|
|
|
Implement this first.
|
|
|
|
This is the foundation required before matching, result semantics, UI, and review readiness can be fixed safely.
|