|
| 1 | +# Security pre-merge checklist |
| 2 | + |
| 3 | +Use this checklist for changes to a protocol, request handler, decoder, storage format, authorization path, cluster path, or egress integration. |
| 4 | + |
| 5 | +## Entry points and authorization |
| 6 | + |
| 7 | +- [ ] Every new client entry point authenticates through the protocol's established authentication path and routes operations through `control::server::shared::authorization` before dispatch. |
| 8 | +- [ ] Client entry points **MUST** route through shared authorization and **MUST NOT** construct `AuthenticatedIdentity` directly. Identity comes only from verified credentials or a narrowly scoped trusted-internal service constructor. |
| 9 | +- [ ] The handler dispatches an `AuthorizedTask` through the authorized dispatch/gateway path; it does not construct a client-controlled `PhysicalTask` and send it to the Data Plane. |
| 10 | +- [ ] The required capability is explicit for every new `PhysicalPlan` or operation, and permission mapping is exhaustive. |
| 11 | +- [ ] Authentication failures, catalog lookup failures, authorization failures, and unknown scopes fail closed with no default tenant/database or unauthenticated fallback. |
| 12 | +- [ ] New public/admin/health endpoints have an explicit authentication, authorization, startup-gate, rate-limit, and deployment-exposure decision. |
| 13 | + |
| 14 | +## Identity, tenant, database, and RLS |
| 15 | + |
| 16 | +- [ ] Claims, API-key data, client certificates, session values, request bodies, and headers are treated as untrusted until their verifier and server-side binding accept them. |
| 17 | +- [ ] Tenant authority is server-owned; an asserted token/payload tenant cannot override provider, credential, or session binding. |
| 18 | +- [ ] Database selection resolves to a catalog descriptor and is checked against the authenticated identity. A database name/header/query parameter selects a target; it does not grant access. |
| 19 | +- [ ] Every task, stream, descriptor, cache key, lease, route, audit event, and egress record that needs scope carries and checks both database ID and tenant ID. |
| 20 | +- [ ] Engine-specific identity and persisted state—including Array schema/op-log/ACK/snapshot/cursor/GC state and function/trigger/schedule registries—use explicit `(database, tenant, object)` keys. Legacy unscoped rows are accepted only by documented DEFAULT-database migration paths with scoped records taking precedence. |
| 21 | +- [ ] Session refresh/re-authentication cannot silently change tenant or database while retaining subscriptions, cursors, presence, sync engines, or other authority. Scope changes are rejected or atomically revoke and rebuild all identity-bound state. |
| 22 | +- [ ] RLS is applied after capability authorization and uses the server-derived `AuthContext`. |
| 23 | +- [ ] `X-On-Deny`, SQL `ON DENY`, and session denial settings only choose RLS-denial presentation (silent filter or error). They cannot grant database/RBAC/collection access or bypass authorization. |
| 24 | +- [ ] No raw JWT, MessagePack field, sync value, or SQL parameter is decoded into an identity override. |
| 25 | + |
| 26 | +## Parsing, allocation, and query construction |
| 27 | + |
| 28 | +- [ ] Decoders **MUST bounds-check before allocation**: validate framing, declared size, nesting/depth, field/label counts, decompressed size, batch size, and semantic ranges before allocating, buffering, or dispatching. |
| 29 | +- [ ] HTTP JSON/NDJSON body and stream limits, WebSocket/native/sync/RESP frame limits, ILP line/batch limits, PromQL range/result limits, and deadlines are explicit and tested. |
| 30 | +- [ ] Malformed, truncated, duplicate, oversized, invalid-UTF-8, invalid-compression, and adversarial-depth inputs are rejected without panic, unbounded work, or partial authorization. |
| 31 | +- [ ] SQL is parsed and planned; untrusted identifiers and values are not concatenated into reconstructed SQL. Use structured plans and correct identifier/value quoting where generation is necessary. |
| 32 | +- [ ] MessagePack, ILP, PromQL, sync, CRDT, and remote-read/write payloads receive equivalent syntax, type, length, and semantic validation. |
| 33 | +- [ ] Filenames and COPY/import/export paths are normalized and constrained to configured authorized roots before open; traversal and symlink escape are rejected. |
| 34 | + |
| 35 | +## CDC, streams, and leases |
| 36 | + |
| 37 | +- [ ] CDC poll/SSE/named-stream authorization happens before buffer reads and is bound to `(database_id, tenant_id, stream/collection)`. |
| 38 | +- [ ] CDC cursors are treated as opaque, validated positions rather than authority. They cannot be replayed across a different database, tenant, stream, or collection. |
| 39 | +- [ ] CDC offsets preserve the composite WAL position (`CdcOffset`: LSN plus sequence); consumer commits are monotonic and reject regression, including per-partition cases. |
| 40 | +- [ ] Subscription, poll, SSE, LIVE, consumer-group, and egress queues have bounded retention, fan-out, cancellation, and shutdown behavior. |
| 41 | +- [ ] Descriptor leases cover planning, dispatch, and lazy/streamed response consumption for their full lifetime; transaction/savepoint rollback releases aligned scopes, and DDL/metadata changes drain or fence conflicting work. |
| 42 | +- [ ] Parse, Describe, and EXPLAIN use metadata-only planning: they do not allocate durable identities, mutate catalogs, expand execution-only work, acquire execution leases, cache executable plans, or dispatch. |
| 43 | +- [ ] Original tasks are authorized before implicit task expansion or other side effects; the final expanded task set is authorized again before lease admission and dispatch. |
| 44 | +- [ ] Cached plans and metadata are revalidated/authorized for the current identity, database, tenant, descriptor version, and lease context before execution. |
| 45 | + |
| 46 | +## Planes, cluster transport, and durability |
| 47 | + |
| 48 | +- [ ] Control Plane code owns client parsing/authentication/planning/authorization; Data Plane code accepts only admitted work; Event Plane side effects re-enter through Control-to-Data authorization. |
| 49 | +- [ ] Cross-plane traffic uses the bounded SPSC bridge or Event Bus—no direct shared mutable cross-plane shortcut. |
| 50 | +- [ ] Cluster QUIC/Raft frames authenticate the peer first, then validate framing, size, version, membership, group/node identity, and message semantics before apply. |
| 51 | +- [ ] SWIM liveness information is not treated as data, membership, or authorization authority without the corresponding authenticated metadata/cluster transition. |
| 52 | +- [ ] Bootstrap/join validates one-time/expiry token lifecycle and node identity; failed joins revoke temporary peer authorization. |
| 53 | +- [ ] New WAL/segment/snapshot/catalog formats validate lengths, versions, and integrity before use and have explicit corruption/quarantine/recovery behavior. |
| 54 | +- [ ] An operation acknowledged as durable has an authoritative WAL/Raft/persistent-log write and tested restart/failover recovery; an in-memory retention buffer is never described or acknowledged as durable. |
| 55 | +- [ ] A definition and its executable content are replicated consistently. Content-addressed WASM modules are present and hash-verified on every node that may execute the function, and missing modules fail closed. |
| 56 | +- [ ] Publish and subscribe APIs for one logical topic use the same database/tenant-scoped authoritative topic subsystem; compatibility protocols do not subscribe to an unrelated change stream or abandoned registry. |
| 57 | +- [ ] CRC is described only as corruption detection. Claims of authenticity require AEAD or authenticated transport and must state the applicable configuration. |
| 58 | + |
| 59 | +## Cryptography, shutdown, and operations |
| 60 | + |
| 61 | +- [ ] TLS/mTLS certificate validation, hostname/SPKI policy, key rotation, revocation, and insecure/private-only mode constraints are preserved. |
| 62 | +- [ ] Encryption changes define key ownership, KMS/key-file permissions, nonce uniqueness, nonce/key usage budgets, rotation, backup/restore, and failure behavior. |
| 63 | +- [ ] Secrets, bearer tokens, private keys, raw authorization headers, and sensitive payloads are not logged, returned in errors, added to metrics labels, or placed in traces. |
| 64 | +- [ ] New webhook/Kafka/alert/telemetry egress configuration has outbound allowlisting/SSRF controls, TLS and credential handling, payload minimization, timeout/retry limits, and bounded pending work. |
| 65 | +- [ ] Startup readiness remains false until required recovery is complete. Shutdown uses the one canonical phased bus, stops admission, drains listeners and Event Plane/delivery work before final watermark/WAL phases, joins correctness-critical no-abort loops, and reserves forced process exit for a second OS signal. |
| 66 | + |
| 67 | +## Verification and supply chain |
| 68 | + |
| 69 | +- [ ] Unit/integration tests cover allowed and denied access, same-name cross-tenant/database attempts, malformed/oversized payloads, cursor/offset tampering, cancellation, drain, restart, recovery, failover, and registry/catalog divergence. |
| 70 | +- [ ] Fuzz/property/static tests cover parsers and decoders, integer narrowing/overflow, decompression, SQL/PromQL parsing, MessagePack/native/sync framing, and storage/frame corruption where applicable. |
| 71 | +- [ ] Tests confirm that a new entry point cannot bypass shared authorization, RLS, database binding, descriptor lease rules, or shutdown gates. |
| 72 | +- [ ] Dependency changes are reviewed with the repository's advisory policy and cargo-vet baseline for advisories, license and maintenance status, minimal features, and transitive network/crypto parsers; CI actions and tool versions remain immutable/pinned. |
| 73 | +- [ ] Secrets are supplied by approved runtime configuration, never committed; full-history secret scanning remains enabled, and release artifacts include the required dependency inventory/SBOM and provenance attestations. |
0 commit comments