Skip to content

Security

Target Architecture — Final-State Design

Security in the Runtime & Cloud Platform is defense-in-depth: every call is authenticated and tenant-scoped, secrets never leave Azure Key Vault, and tenant isolation declared at generation time becomes enforced runtime isolation. Policy and audit integrate with the Governance, Security & Compliance Platform.

Authentication

  • Service callers (Control Plane, DevOps, Studio) authenticate with OAuth2 / OpenID Connect bearer tokens issued by the factory authorization server (OpenIddict).
  • Workload-to-Azure authentication uses managed identities (workload identity on AKS, system/user-assigned identities on Container Apps, Functions, and App Service) — no credentials in config or images.
  • Service-to-service calls inside the platform use mTLS within the cluster mesh plus token-based identity, and assert the canonical envelope tenantId/traceId.

Authorization

  • Coarse-grained access uses runtime.{resource}.{action} scopes (see APIs).
  • Fine-grained, context-aware decisions (e.g. "may this principal deploy to a prod environment for tenant X?") are delegated to the Governance policy engine; production-affecting mutations require an explicit policy decision and are recorded.
  • Authorization is always evaluated after the tenant guard: the principal's tenantId must match the target environment's RuntimeTenantBinding.

Tenant Runtime Isolation

Tenant isolation is the platform's defining security property. RuntimeTenantBinding translates the generation-time tenancy model into enforced runtime boundaries:

Layer Silo Pool Shared
Compute Dedicated environment / node pool Shared cluster, dedicated namespace Shared namespace
Network Dedicated VNet / subnet Network policy per tenant Shared with policy
Data Dedicated database Shared DB, partitioned + row filters Shared DB, row-level tenantId filter
Secrets Dedicated Key Vault Shared vault, per-tenant access policy Shared vault, scoped references
Quota Full environment capacity Allocated quota Allocated quota
  • tenantId is a mandatory predicate on every store access (ConnectSoft.Extensions.Saas.*).
  • Network policies and namespace boundaries are provisioned by Pulumi and reconciled by the DriftDetectionWorker — an unmanaged cross-tenant route is itself a drift finding.

Secret Handling

  • All secrets live in Azure Key Vault; SecretBinding stores references only (keyVaultRef, secretName, currentVersion).
  • Workloads resolve secrets at runtime via managed identity; secret values never appear in RuntimeConfiguration, Blob, logs, telemetry, or events.
  • The SecretRotationWorker rotates secrets on schedule, emitting SecretRotated; bindings refresh to the new version without downtime.
  • Key Vault access is least-privilege per environment and tenant; access is audited to Governance.

Audit

  • Every mutating operation (provision, deploy, rollback, config publish, secret bind/rotate, scale, drift remediation) emits an enveloped event with traceId, principal, and tenantId, persisted as an immutable audit record and forwarded to Governance.
  • Health, scaling, and drift signals are correlated to the same trace, giving an end-to-end, tamper-evident operational record.
  • Audit retention aligns with the data-model retention policy and compliance requirements.

Threat Model

Threat Mitigation
Cross-tenant data access RuntimeTenantBinding enforced on every read/write; isolation drift treated as a finding
Secret leakage Key Vault-only storage; managed identities; no secrets in config/logs/events
Unauthorized deployment to prod Governance policy decision + runtime.deployments.write scope + tenant guard
Supply-chain tampering (images) Images pulled only from trusted ACR; digests recorded in RuntimeDeployment; drift detection flags unexpected images
Configuration drift / unmanaged resources Continuous drift detection vs Git/Pulumi desired state; auto- or review-gated remediation
Privilege escalation via workload identity Least-privilege managed identities scoped per service and environment
Denial of service / noisy neighbour Per-tenant quotas in RuntimeTenantBinding; scaling bounds; namespace resource limits
Replay / poison messages Envelope eventId idempotency; dead-letter with preserved envelope