Authority Tenant Model

Authority tenant records define authentication boundaries and tenant-scoped metadata used by downstream Stella Ops services.

Platform-Side Propagation Contract

Authority is the source of truth for tenant lifecycle writes. Platform-side tenant resolution uses shared.tenants as the local directory for services that store tenant-scoped rows in the platform database.

Every successful console-admin tenant create, update, suspend, or resume writes Authority first, then calls ISharedTenantsPropagator to upsert the matching shared.tenants row. Propagation failures do not roll back the Authority write: the API returns the tenant result with a Warning header, writes an *.propagation_failed audit event, and records tenant.propagation.outcome=warning on the successful tenant audit event. This keeps the operator able to recover by running devops/compose/scripts/reconcile-tenants.ps1 or devops/compose/scripts/reconcile-tenants.sh.

Startup orphan handling is controlled by Authority:Propagation:OnOrphan:

Why reconcile rather than a forward-only SQL backfill migration (ADR-004)? authority.tenants lives in stellaops_authority and shared.tenants in stellaops_platform; a single SQL migration cannot cross databases. The Authority startup reconciler (OrphanedTenantHealthCheckISharedTenantsPropagator) reads the Authority repository and writes the platform table at the application layer, and is the §2.7-compliant convergence path for this two-database case.

Downstream F11-style slug resolvers, including PostgresEvidenceLockerTenantResolver and sibling resolvers in Scanner, Concelier, Findings, Policy, Notify, and Timeline, depend on this contract: an Authority tenant missing from shared.tenants can authenticate but will resolve to 403/404 in platform-side services.

Compliance Profile

Authority exposes an optional complianceProfile on tenant views and console admin tenant summaries. The contract is tenant-compliance-profile.v1.

Profiles are nullable. Tenants without DORA, NIS2, or CRA obligations should leave the field absent rather than carrying empty regime flags.

Current persistence:

Validation is offline-only. LEIs are checked with the ISO 17442 checksum and no live registry lookup. Jurisdiction and NACE reference data are bundled in devops/runtime-assets/eu-compliance/.

Assurance Pack Enablement

Authority stores tenant/operator Assurance pack enablement under tenant.settings.operatorCompliance.assurancePacks. This is not a Europe-specific tenant model; it is the shared setup surface for optional packs such as NIS2 evidence support and CRA technical documentation support.

Tenant/operator fields:

Sealed/environment fields:

Runtime consumers can read the Authority-owned readiness projection through GET /api/v1/tenants/{tenantId}/assurance-packs. NIS2 SoA live-export readiness is reported as reason codes over the tenant profile and operator approver state. CRA product-publication readiness is represented separately from local CRA technical-file export readiness so mailbox/key publication preflight does not block local evidence exports. The route accepts authority:tenants.read, policy:read, or policy:audit, but remains tenant-self: X-StellaOps-TenantId is required and must match {tenantId}.

Runtime Submission Authorization Projection

Runtime services that need to gate operator-owned submissions read GET /api/v1/tenants/{tenantId}/submission-authorizations?purpose=<purpose>[&channelId=<channel>] with authority:tenants.read and the matching X-StellaOps-TenantId header. The response contract is tenant-submission-authorization.v1.

The projection is intentionally narrow. It returns the tenant id, requested purpose, optional channel id, derived regime, operator settings hash, optional pack config revision, autoSubmitEnabled, approvalRequired, freshAuthRequired, active approver summaries for the matching regime/actions, and stable fail-closed reason codes. For purpose=dora-incident, Authority derives regime dora and accepts active approvers with either submit or autoSubmitApproval; both actions are fresh-auth-gated by the normalized operator-compliance settings.

The projection never returns channel destinations, channel credentials, secret refs, signing providers, private keys, trust roots, storage roots, public base URLs, endpoint fail-closed posture, sealed/offline mode, or network-egress posture. Cross-tenant path/header mismatches are forbidden before a projection is returned.

Persistence Decision

The earlier EU compliance sprint requested a dedicated nullable JSON column on the tenant catalog. The modular Assurance-pack design supersedes that as a v1 requirement: metadata.complianceProfile is the durable Authority-owned profile slot. A dedicated column should be reconsidered only if query performance or cross-service reporting requires it, and that would be a generic pack-profile storage decision rather than a NIS2/CRA-specific schema change.