v0.18.0
This release closes every open security finding from the Phase 4 engineering assessment, bringing pg_aqueduct to zero open CVEs and zero open critical or high security issues. The headline change is that consumer view bodies are now validated as a single SELECT statement before any database call is made — meaning a misconfigured or maliciously crafted migration file containing DDL like CREATE TABLE or DROP TABLE can never reach the database, even if it somehow made it into your migrations directory. This is an important defence-in-depth layer for teams running Aqueduct in automated CI/CD pipelines.
Two additional critical security fixes ship in this version: the CloudNativePG preview client now validates TLS certificates by default (previously it silently accepted any certificate), and the age secret backend now validates the identity file path for both path traversal and flag injection before passing it to the age subprocess. Together with the consumer SQL validation, these three fixes mean pg_aqueduct meets the full OWASP A03 (Injection) and A02 (Cryptographic Failures) controls relevant to its operation.
Beyond security, this version improves day-to-day operational quality: aqueduct plan --fail-on-drift now correctly detects drift in consumer views and source tables (not just stream tables), aqueduct destroy auto-migrates a stale catalog before querying it, and several documentation files and CI template files that had stale version pins are updated to match the current release. A new .github/SECURITY.md establishes the project's vulnerability reporting policy.
Added
validate_consumer_sql_is_single_select()is now called immediately before every
CREATE OR REPLACE VIEWin the executor (ManageConsumerViewandSwapConsumerViews
arms). A migration file containing injected DDL is rejected with
AqueductError::UntrustedSqlBodybefore any database call is made (SEC-1).- Integration test
consumer_sql_injection_rejected_at_applyconfirms that a consumer
migration with aCREATE TABLEbody is rejected at the executor level (SEC-1). - CNPG preview HTTP client now validates TLS certificates by default. Set
CNPG_INSECURE_SKIP_VERIFYto skip verification in development environments only.
Emits awarn!when the env var is set (SEC-2). - Unit test
cnpg_tls_default_does_not_skip_verificationconfirms the env-var gate
logic (SEC-2). agesecret backend now validates the identity file path (fromSOPS_AGE_KEY_FILE/
AGE_KEY_FILE) viavalidate_secret_path()and rejects paths starting with-
(flag-injection guard). Unit testsage_identity_file_traversal_rejectedand
age_identity_file_flag_injection_rejectedcover both rejection cases (SEC-3)..github/SECURITY.md: security policy with contact address, response SLA, supported
version matrix, and a summary of implemented controls (L-5).docs/security.md: new sections covering consumer SQL injection protection,
CNPG TLS configuration, andageidentity file security (SEC-1, SEC-2, SEC-3).
Changed
aqueduct plan --fail-on-drift: drift count now includessource_deltasand
consumer_deltasin addition todeltas, matching the already-correctstatus
implementation. Previously, consumer-layer and source-layer drift was silently
ignored (M-2).aqueduct destroy: changed fromconnect()toconnect_and_migrate()so a stale
catalog schema is auto-migrated before destroy queries it (M-5).release.yml: removed globalFORCE_JAVASCRIPT_ACTIONS_TO_NODE24env var — all
actions in the workflow use modern Node.js runtimes that do not require this
workaround (M-6). Addedjust gen-docsstep to regeneratedocs/api-reference.md
on every release tag.ingest.rstest helpers:fs::write(...).unwrap()replaced with descriptive
.expect("...")calls so a failing CI write produces a clear error message (M-7).fmt.rs: renamedKNOWN_FRONTMATTER_KEYStoKNOWN_DIRECTIVE_KEYSwith updated
doc comment explaining it is used to skip already-emitted keys, not enforce ordering
(L-1).main.rs: replaced stale// L7 (v0.14)tracking comment with descriptive
per-platform CI env var documentation (L-3).Cargo.toml: replaced stale# DEP-1 (v0.14): pre-declare serde_yamlcomment with
# YAML serialization for plan/status/diff --format yaml output.(L-4).- Six user-facing integration files updated to reference version
0.18.0:
.github/workflows/aqueduct-plan.yml,.github/workflows/aqueduct-apply.yml,
ci/gitlab/aqueduct.gitlab-ci.yml(also fixes archive name pattern to match
the release pipeline:aqueduct-{version}-{os}-{arch}.tar.gz),
.pre-commit-hooks.yaml,docs/api-reference.md,docs/introduction.md(CI-1). version-lintCI job extended to check nine files:README.md,
docs/installation.md,docs/api-reference.md,docs/introduction.md,
ci/gitlab/aqueduct.gitlab-ci.yml,.pre-commit-hooks.yaml,
.github/workflows/aqueduct-plan.yml,.github/workflows/aqueduct-apply.yml,
andROADMAP.md. Fails if any disagrees with the workspaceCargo.tomlversion
(CI-1, L-6).ROADMAP.mdstatus line updated tov0.18.0 released(L-6).- Workspace version bumped to
0.18.0.