This checklist is a release-review entry point. Every checked item should link to a configuration snapshot, test report, dashboard, audit query, or rehearsal record. Verbal confirmation is not commercial-GA evidence.
Run Host startup guards
RuntimeConfigurationGuard rejects Shell/default infrastructure in Production and Staging. It currently checks database, RabbitMQ, Redis, trusted proxies, OTLP, object storage, Webhook delivery, and Runtime License configuration.
# Missing production-like dependencies should produce a non-zero startup.ASPNETCORE_ENVIRONMENT=Staging \ dotnet run --project src/Hosts/BitzOrcas.Api/BitzOrcas.Api.csproj
# Repeat with deployment-injected configuration and retain the startup log.ASPNETCORE_ENVIRONMENT=Production \ dotnet run --no-build --project src/Hosts/BitzOrcas.Api/BitzOrcas.Api.csprojPassing proves required keys and explicit conditions, not remote permissions, certificate chains, rotation, or recoverability.
Identity and authentication
- JWT issuer/audience/signing material is controlled; unknown
kid, expiry, and wrong audience deny; - signing-key overlap, switch, and old-key revocation were rehearsed;
- HMAC timestamp/nonce/body, API Key hash, and isolated SCIM scheme have negative tests;
- Development fixtures are absent in Production/Staging;
- privileged users and actions require MFA/step-up;
- account/MFA recovery and session revocation do not bypass authentication;
- failure responses do not disclose account, tenant, or credential state.
evidence: authentication contract report + key rotation drill + fixture sweepowners: Identity owner + Platform Securityblockers: weak default key, unknown kid accepted, production test credentialsAuthorization and data scope
- every public Command/Query resource/action is inventoried;
- deny-first, all-neutral default deny, and dependency-failure deny are tested;
- Application scope cannot impersonate User RBAC;
- DataScope is compiled into query predicates;
- permission, relation, and Feature changes invalidate caches;
- delegated callers bypass normal authorization caching;
- batch, export, search, and complex joins have unauthorized tests.
Run the same use case as a same-tenant unauthorized user, another tenant, an application caller, and a delegated caller—not only as an administrator.
Tenant isolation
- tenant ID comes only from trusted claims, credentials, Host maps, or job scope;
- conflicting Header/Path tenant signals deny;
- ORM query, key lookup, update, delete, and uniqueness include tenant;
- cache, idempotency, rate-limit, message, and object keys include tenant;
- background work restores tenant/caller context explicitly;
- every commercial persistence profile passes Consumer Contract Tests;
- Host/customer privilege boundaries have independent tests.
Negative tests must prove other-tenant data is absent or denied, not merely assert a 2xx response.
Network, proxy, and browser
- public traffic forces TLS; internal mTLS/ACL matches topology;
- KnownProxy/KnownNetwork or DirectExposure passes startup guard;
- forged forwarded headers cannot influence IP limits or audit;
-
Host/X-Forwarded-Hostpreserves the public port, and a forgedX-Forwarded-Portcannot rewrite a trusted Host; - CORS lists only production origins and rejects unknown origins;
- HSTS, CSP, frame, MIME, referrer, and permissions headers are verified at the edge;
- Gateway/API duplicates do not conflict or weaken policy;
- OpenAPI/Scalar is disabled in production; if an exception enables it, the product Host sets
RequireAuthentication=trueand adds HTTPS plus VPN, IP allowlisting, or gateway SSO as defense in depth; - Documentation login/logout routes are reachable, and formal product logout also clears the
bitzorcas.docssession; - shared documentation environments disable Scalar authentication persistence and contain no username, token, API key, or HMAC secret in configuration or documentation;
- health responses reveal no connection string or internal topology.
Secrets, keys, and licensing
- repository, history, logs, image, and source maps pass secret scanning;
- every secret has owner, readers, version, rotation, and revoke path;
- API Key/SCIM plaintext is shown once and runtime stores only hashes;
- Webhook/provider secrets are protected with distinct purposes;
- Redis key ring cross-decrypts across replicas and restores from backup;
- Runtime License private keys never ship; public keys resist replacement;
- deployment identity and license cache use stable restricted storage;
- logs, audit, and ProblemDetails contain no credential plaintext.
Data, files, and privacy
- databases, objects, backups, and exports use encryption at rest;
- migration, runtime read/write, and operations accounts are separated;
- upload size/type/object-key/access checks have negative tests;
- current Files gaps are not overclaimed, including malware scanning and upload-session expiry;
- PII classification, retention, deletion, and export are defined;
- restored data is re-tested for tenant and key integrity;
- production data is excluded from non-production or irreversibly masked.
Messaging, jobs, and Webhooks
- at-least-once consumers protect side effects with stable idempotency keys;
- retry limits, backoff, dead letters, and owners are defined;
- outbox/inbox, broker, and database failure windows have injection tests;
- Webhook signature covers event ID, timestamp, and payload hash;
- receiver separately enforces freshness and atomically deduplicates event IDs;
- secret overlap and old-key revocation were rehearsed;
- job failures are observable and tenant context is never silently lost.
Abuse, limits, and timeouts
- anonymous, login, OTP, upload, search, export, and Webhook endpoints are limited;
- production-like deployments use shared Redis quotas;
- partition keys use trusted tenant/caller/IP facts;
- request size, page size, query complexity, and concurrency are bounded;
- cancellation propagates to database, HTTP, and messaging;
- timeout/cancellation leaves no half-completed effect;
- expensive requests and limit denials have metrics and alerts.
Audit and detection
- authentication failure, authorization denial, delegation, role, and key events are queryable;
- actor/impersonator and origin/target tenant are both retained;
- CorrelationId and TraceId join API, message, and Job activity;
- audit store cannot be None in production-like environments;
- log injection, sensitive fields, and high-cardinality labels were reviewed;
- alerts have threshold, owner, escalation, and runbook;
- immutable evidence can reconstruct a security incident timeline.
Supply chain and artifacts
- dependencies are locked and scanned for vulnerabilities/licenses/malicious packages;
- SBOM, provenance, and artifact signatures are generated;
- containers run non-root with minimal capabilities and read-only filesystem where possible;
- base image and runtime upgrades have an SLA;
- the artifact traces to an approved commit and CI run;
- production accepts only trusted signed artifacts;
- debug tools and diagnostic ports are absent from the image.
Backup, recovery, and response
- database, objects, config, key ring, and license state are recoverable;
- rehearsal measures RPO/RTO rather than only backup existence;
- post-restore smoke tests cover auth, tenant, messages, and files;
- rollback does not require destructive down migrations;
- irreversible migrations have forward-fix plans;
- secret leak, account takeover, cross-tenant event, and broker backlog have runbooks;
- break-glass access is short, strong-MFA, audited, and regularly tested.
Evidence package
# Refer to secret versions, never plaintext values.# Every link must bind the same commit, environment, and config version.release: 2026.07.0commit: <git-sha>evidence: startup_guard: <ci-artifact-url> tenant_negative_tests: <ci-artifact-url> key_rotation_drill: <runbook-record> restore_drill: <runbook-record>accepted_risks: []approvers: [platform-security, service-owner]Bind evidence immutably to artifact, environment, commit, and configuration version. An old-environment screenshot cannot approve a new artifact.
Release decision
Tenant isolation failure, authentication bypass, signing/secret exposure, production test credentials, audit loss, or irrecoverable critical data are blockers. Any other exception needs an owner, due date, compensating control, and explicit risk accepter.
State which capability is proven for which topology by which evidence. Avoid the untestable claim that “security is complete.”