Skip to content

Releases: vericto/vericto-proxy

4.15.3 - 2026-10-23

Choose a tag to compare

@vericto vericto released this 23 Oct 16:19
8e15288

Performance: less CPU per statement on the always-on path. No behaviour change:
same verdicts, same bytes to the database and the client, same telemetry content.

The M2 release gate measured 4.15.0 with VERICTO_POLICY_RULES=off at +3.6% proxy
CPU per transaction against 4.14.3 on MySQL (oltp_read_only, 0.5 vCPU). With the flag
off, 4.15.0 runs the same number of instructions per statement as 4.14.3 (within
0.2%; the policy paths take none), so the difference is code layout and cache
behaviour of the larger binary, not extra work. This release takes work out of the
per-statement path instead:

Security

  • ctutils 0.4.3 → 0.4.5 in Cargo.lock (RUSTSEC-2026-0385: non-constant-time mask generation and u128
    comparisons). A transitive dependency; no code change.
  • tokio 1.53.2 → 1.54.1 in Cargo.lock (RUSTSEC-2026-0386: AsyncFd::new and related constructors violate
    I/O safety). No code change.

Changed

  • Telemetry batches are serialized straight from the events. The request body
    of POST /ingest/events used to be built as a serde_json::Value first, which
    copied every field of every event (one event per statement) into a map and a
    string of its own before writing it out. It is now written directly. The body is
    the same JSON document; only the order of the keys inside an event changes (the
    declaration order instead of alphabetical), which JSON does not give any meaning.
  • A flagged statement's rule code and AST path are moved, not copied, into the
    decision the session acts on.
  • Together, on a fixed MySQL oltp_read_only replay (16 statements per transaction):
    -10.4% user-space instructions per transaction against 4.14.3, 4.15.0 and 4.15.1
    (3.35 M against 3.73 M, callgrind), with the same system calls.

4.15.2 - 2026-10-22

Choose a tag to compare

@vericto vericto released this 23 Oct 02:59
ea43d23

Security: the runtime image moves to Chainguard glibc-dynamic, with no shell.
The proxy's behaviour, configuration and wire traffic are 4.15.1's. What changes is
the image around the binary, and with it how a container health check is written
and which user the process runs as (see Upgrading).

Security

  • Runtime base image: cgr.dev/chainguard/glibc-dynamic:latest@sha256:00696e56…b0e85212
    (Wolfi: glibc 2.44, libgcc and libstdc++ 16.2.0, the CA bundle; 7 packages), from
    debian:bookworm-slim@sha256:7ff6ba31…78efe3f8. The binary links only libc, libm
    and libgcc_s, all provided by the base (checked with the image's own
    ld.so --list), and TLS is rustls with the compiled-in webpki-roots store, so
    libssl3 and ca-certificates are no longer installed. Scanned on 2026-10-22 with
    Trivy 0.76.1 and Grype 0.121.0, both platforms: 0 findings of any severity
    (4.15.1: 1 Critical, 12 High unique CVEs with Trivy, 1 Critical, 20 High with
    Grype, none of them with a Debian 12 fix). This closes the residual util-linux,
    zlib, glibc, OpenSSL and perl-base findings listed under 4.15.1.
  • The image has no shell, package manager or coreutils, which removes them as
    tools for anyone who gets code execution in the container.
  • Container scan gate in CI and before release. ci.yml builds the image on
    every pull request and push and scans it with Grype (pinned by digest);
    release.yml scans each platform image before it is pushed. Both fail on a
    Critical or High finding that has a fix available. A weekly workflow
    (image-scan.yml) rebuilds main and scans it and the released latest image.
  • SBOM. Each released platform image carries a Sigstore-signed SPDX SBOM
    attestation (Syft) for its platform digest, also uploaded as a workflow artifact:
    gh attestation verify oci://ghcr.io/vericto/vericto-proxy@<platform digest> --repo vericto/vericto-proxy --predicate-type https://spdx.dev/Document/v2.3.
  • Dependabot (docker) runs weekly (it was monthly), so the digest pin follows
    what cgr.dev serves: only latest is free, and Chainguard does not promise to keep
    old digests.

Added

  • vericto-proxy healthcheck: the container health check as a subcommand,
    since the image has no shell. It connects to the healthz listener
    (VERICTO_HEALTHZ_PORT, on 127.0.0.1 or the address VERICTO_HEALTHZ_ADDR
    names), closes, and exits 0 on success, 1 on failure or on a port that is not a
    number, and 0 when the port is unset (the listener is optional). It never
    contacts the database. The image's HEALTHCHECK uses it in exec form.

Upgrading

  • Health checks must call the binary, in exec form:
    ["CMD", "/usr/local/bin/vericto-proxy", "healthcheck"] (Docker Compose
    healthcheck.test, ECS healthCheck.command, Kubernetes exec probes). A
    CMD-SHELL check, bash -c '... /dev/tcp/...', curl or wget fails in this
    image and marks the container unhealthy. NLB/ALB TCP target-group checks are
    unaffected. Change the check and the image together: up to 4.15.1 the binary
    ignores its arguments, so vericto-proxy healthcheck against an older image starts
    a second proxy, which fails to bind the ports already in use and exits 1.
  • The process runs as 65532:65532 (Chainguard's nonroot), not 1001:1001. A
    host or named volume written by an older image (for example a disk telemetry spool)
    needs chown -R 65532:65532, or run the container with --user 1001:1001. An EFS
    access point with a PosixUser enforces its own uid and is not affected.
  • docker exec <container> sh and ECS Exec shells no longer work. Copy files out
    with docker cp; /metrics and the EMF line report the telemetry spool.

4.15.1 - 2026-10-22

Choose a tag to compare

@vericto vericto released this 23 Oct 02:16
370d065

Security: the runtime image moves to the current debian:bookworm-slim. No code
change; the binary, the configuration and the behaviour are exactly 4.15.0's.

Security

  • Runtime base image bumped to debian:bookworm-slim@sha256:7ff6ba31…78efe3f8
    (Debian 12.15 with the perl-base 5.36.0-7+deb12u4 security update), from
    sha256:7c7b2c96…6ccc587. Amazon ECR scanning of the 4.15.0 image reported 26
    findings (5 Critical, 13 High) in four base packages; the 5 Critical and all the
    perl-base findings (8 CVEs, among them CVE-2026-42496, CVE-2026-13221,
    CVE-2026-8376, CVE-2026-12087 and CVE-2026-57433) are fixed by this base.
  • Still open, no Debian 12 fix published yet: util-linux 2.38.1-5+deb12u3
    (5 High, 1 Medium), zlib 1.2.13.dfsg-1 (CVE-2026-85091, High) and
    glibc 2.36-9+deb12u14 (1 Medium, 2 Low). Dependabot (docker) moves the digest
    again when Debian ships them. Debian 13 (trixie) was evaluated and not adopted: it
    still reports High findings in glibc and zlib and is a major base change.

4.15.0 - 2026-10-21

Choose a tag to compare

@vericto vericto released this 22 Oct 15:58
282f5b1

Business policy rules, behind VERICTO_POLICY_RULES (default off). With the
flag off the proxy behaves exactly as 4.14.3: same rule-sync request, same bytes to
the database, same verdicts, same telemetry. This is a preview for the business
policy rules milestone M2; nothing turns it on by itself.

Added

  • VERICTO_POLICY_RULES=off|observe|enforce, any case; unset or empty is off,
    and any other value fails startup (as VERICTO_TELEMETRY_BUFFER does), so a typo
    can neither leave enforcement off nor turn it on silently.
  • Policy bundle compiled at sync. With the flag on, every GET /sync/rules
    carries X-Vericto-Policy-Language: cel/1, and each applied response (the rules
    cache included) is compiled once with the engine's PolicySet::compile into an
    ArcSwap, together with the very rules it was compiled from and the response's
    version (reported as policy_bundle_version). A policy that does not compile
    is logged and fails closed in its scope (engine behaviour).
  • Principals. The principals section of /sync/rules (identify: db_user,
    db_user_pattern with medium trust, application_name, listener with weak
    trust; narrow; attrs; {db_user} templates) is resolved once per session,
    and again only when a sync swaps the bundle or a MySQL COM_CHANGE_USER changes the
    user. The strongest identifying signal wins; narrowing must also match and never
    raises trust; two principals at the same top trust are ambiguous and the session
    is unknown with weak trust, as is a session nothing matches. A malformed
    section, or entry, is ignored with a warning and never fails the sync.
  • Session signals. Postgres application_name (StartupMessage parameter or
    -c application_name= in options), MySQL program_name (connect attributes),
    and the listener (the address the proxy binds). No client address is captured:
    session.client_ip is left unset.
  • Session context: vericto.ticket and vericto.tenant. From the Postgres
    StartupMessage (-c vericto.ticket=… / --vericto.ticket=… in options, or a
    vericto.* parameter), from MySQL connect attributes, or from SET [SESSION] vericto.ticket {= | TO} '…' sent on its own as a simple query. The proxy consumes
    them and never forwards them: the StartupMessage and the HandshakeResponse reach
    the database without them, and a SET is answered by the proxy (CommandComplete
    SET + ReadyForQuery, or an OK_Packet) carrying the session's real transaction
    state: the relay follows the last ReadyForQuery status (I, T, E) and the
    last MySQL OK/EOF status flags (SERVER_STATUS_IN_TRANS, autocommit), so the
    proxy's own replies (a consumed SET, a refusal, the Sync that ends a refused
    extended sequence) report what the server reported last. In a failed
    Postgres transaction block (E) a SET vericto.*, simple or extended, gets
    25P02 as the server would answer it, and its value is not taken. MySQL has no
    failed-transaction state, so it has no equivalent. Each key is set once per session: a
    second SET, a RESET, SET … TO DEFAULT or a set_config of a key already
    set, any other vericto.* name, SET LOCAL, and a SET vericto.* sent as a
    prepared statement or among other statements, are blocked with
    VERICTO-SESSION-CONTEXT (and reported). A startup setting the proxy cannot
    accept refuses the connection before it reaches the database. Values are 1 to
    128 characters without control characters.
  • Evaluation with context. With the flag on, each statement is evaluated with
    the engine's evaluate_with_context (mode proxy, the principal, db.id, the
    time in UTC, the ticket, the tenant, application_name and the listener).
    enforce: the policies decide with the rest of the rules, including the engine's
    block of a statement it cannot read when an enforced blocking policy may apply.
    observe: the verdict is the one evaluate() gives; what the policies found is
    added to the event, every block lowered to a flag, so a statement only a policy
    would have blocked is forwarded and reported FLAGGED. In observe a bundle
    with policies costs a second evaluation per statement. An empty policy set costs
    nothing over 4.14.3 in either mode (the engine short-cuts it).
  • Telemetry fields, only with the flag on: principal_id, principal_type,
    principal_trust, principal_via, application_name, policy_bundle_version,
    ticket_id and session_tenant. No client address.
  • docs/CONFIGURATION.md ("Business policy rules"), .env.example and the README
    document the flag.

Security

  • rustls-webpki 0.103.15 → 0.103.16 (RUSTSEC-2026-0382, certificate verification
    may accept distrusted intermediates) and webpki-roots 1.0.8 → 1.0.10
    (RUSTSEC-2026-0381, bundled roots allowed distrusted emSign intermediates). Both
    advisories were published on 2026-10-19 and also affect 4.14.3, whose CI
    supply-chain job now fails on them. Lockfile only: these are the TLS
    verification of the upstream (UPSTREAM_SSLMODE=verify-*) and control-plane hops.

Changed

  • vericto-engine 4.3.0 → 4.4.0 (business policies, CEL in custom rules). Its
    evaluate() keeps the 4.3.0 contract, so with the flag off no verdict changes.
    pg_query 6.2 and sqlparser 0.63 stay aligned with the engine. The engine adds
    regex, already in the lockfile.
  • README: the quickstart and Docker examples use vericto/vericto-proxy:4.15.0.

Not yet verified

  • The BENCH quick suite (features off within the 95% interval of 4.14.3) has not
    been run for this release: the proxy repository has no local benchmark.

4.14.3 - 2026-10-20

Choose a tag to compare

@vericto vericto released this 20 Oct 04:31
a821ca6

The default log level is now info, as documented. No other behaviour change.

Fixed

  • Without RUST_LOG, the proxy logged at info,vericto_proxy=debug (one or more
    debug lines per statement), while docs/CONFIGURATION.md documents info. The
    default is now info. The Docker image already set RUST_LOG=info, so containers
    that do not override it log exactly as before; binaries run without RUST_LOG,
    and deployments that copied RUST_LOG=info,vericto_proxy=debug from
    .env.example, are the ones that change. .env.example now says RUST_LOG=info
    and shows how to turn the debug lines back on.
  • The evaluation-cost comment in src/tcp/query_limit.rs said "roughly 0.35 ms/KB".
    It now gives the measured end-to-end slope with its conditions (about 0.23 ms/KB
    of SQL on PostgreSQL and 0.18 ms/KB on MySQL at 0.25 vCPU, proxy 4.12.0) next to
    the original table, and the 64 MiB extrapolation that follows from both (15 to
    22 s instead of 23 s). Comment only.
  • README: the quickstart and Docker examples use vericto/vericto-proxy:4.14.3.

4.14.2 - 2026-10-19

Choose a tag to compare

@vericto vericto released this 19 Oct 20:04
ec634ca

Documentation only; no code change. The proxy behaves exactly as 4.14.1 did.

Changed

  • README: the opening now says what the proxy is for and the problem it solves,
    states the license (FSL-1.1-ALv2, Apache-2.0 two years after each release) near
    the top, and the quickstart and Docker examples use vericto/vericto-proxy:4.14.2
    from Docker Hub (GHCR serves the same digest) instead of
    ghcr.io/vericto/vericto-proxy:4.5.1.
  • README shortened. The advanced configuration (control-plane link, monthly quota,
    disk spool size, several proxies on one volume, TLS, query size limit, health
    check, observability and metrics, engine-specific and MySQL notes) moved, unchanged,
    to docs/CONFIGURATION.md; the full sensitive-column and agent-access references
    to docs/SENSITIVE_COLUMNS.md and docs/AGENT_ACCESS.md, with a summary left in
    the README; "Run from source" to CONTRIBUTING.md. Comments and .env.example
    that pointed to the README's "Disk spool size" now point to docs/CONFIGURATION.md.

4.14.1 - 2026-10-19

Choose a tag to compare

@vericto vericto released this 19 Oct 15:08
b46844f

The image is now also on Docker Hub, and no code change. The proxy behaves
exactly as 4.14.0 did.

Added

  • Docker Hub: vericto/vericto-proxy. The release workflow now also
    publishes the image to Docker Hub,
    next to ghcr.io/vericto/vericto-proxy, which keeps working as before. It does
    not build twice: it copies the multi-arch index it pushed to GHCR, by digest,
    and checks that Docker Hub serves the same digest, under the same tags
    (<version>, <major>.<minor>, <major>, latest). The Docker Hub copy has
    its own build provenance attestation, verifiable with
    gh attestation verify oci://docker.io/vericto/vericto-proxy:<version> --repo vericto/vericto-proxy.
    The Docker Hub token lives in a dockerhub GitHub environment that only
    release tags (v*.*.*) can use, read by a separate job; without it the
    workflow publishes to GHCR only and says so in a notice.
  • README: Docker Hub badge, docker pull / docker run examples and the
    verification command for the Docker Hub name.

4.14.0 - 2026-10-18

Choose a tag to compare

@vericto vericto released this 19 Oct 00:50
b69ce7d

A new license, and no code change. From this version on, vericto-proxy is
licensed under the Functional Source License, Version 1.1, ALv2 Future License
(SPDX FSL-1.1-ALv2) instead of the Elastic License 2.0. All previously
released versions, 4.13.0 and earlier, remain under the Elastic License 2.0.

The proxy behaves exactly as 4.13.0 did. It moves to vericto-engine v4.3.0,
which has the same code as v4.2.0 under the same new license.

Changed

  • License: FSL-1.1-ALv2, which becomes Apache-2.0 after two years. LICENSE
    is the FSL-1.1-ALv2 text from fsl.software, unmodified, with
    "Copyright 2026 Vericto S.A.S." in its notice. It lets you use, copy, modify
    and redistribute the proxy for any purpose other than a Competing Use: a
    commercial product or service that substitutes for the proxy, or for a
    Vericto product that uses it, or that offers substantially similar
    functionality. Running the proxy in front of your own databases, including in
    production at a company, is a permitted purpose. Each version is also
    licensed under the Apache License 2.0 from the second anniversary of the date
    it is made available, irrevocably. Compared with the Elastic License 2.0, the
    FSL also covers self-managed competing products (ELv2 only restricted hosted
    and managed services) and drops the license-key clause.
  • vericto-engine v4.3.0 (from v4.2.0): the engine's own relicensing
    release, FSL-1.1-ALv2, with no code change. The whole binary, engine
    included, is now under one license, so NOTICE, deny.toml and
    third-party/about.toml need no exception for an Elastic-2.0 engine.
  • Cargo.toml and Cargo.lock declare license = "FSL-1.1-ALv2" (the SPDX
    identifier) and version 4.14.0. The image label is
    org.opencontainers.image.licenses=FSL-1.1-ALv2 (release.yml).
  • NOTICE states the copyright, the license, the Apache-2.0 future license,
    that versions up to 4.13.0 stay under the Elastic License 2.0, and where the
    third-party notices are.
  • New LICENSING.md: which versions are under which license, and a short
    FAQ (what is allowed, what a Competing Use is, when a version becomes
    Apache-2.0, commercial licenses). New TRADEMARKS.md: the license grants
    no right to the Vericto name or logo, and what you may do without asking.
  • THIRD_PARTY_LICENSES in the image: third-party/about.toml no longer
    accepts Elastic-2.0 for any crate. It accepts FSL-1.1-ALv2 for
    vericto-proxy and vericto-engine only, and the file's header explains it.
    deny.toml does the same with exceptions, so a third-party dependency
    under a source-available license still fails cargo deny check.
  • Every Rust source file and third-party/build-notices.sh start with
    SPDX-FileCopyrightText and SPDX-License-Identifier lines (the REUSE
    convention).
  • README (badge and License section), CONTRIBUTING and the Dockerfile comments
    name the new license. CONTRIBUTING explains that CLA 1.0, which names the
    Elastic License 2.0, also covers later and other licenses.

4.13.0 - 2026-10-18

Choose a tag to compare

@vericto vericto released this 19 Oct 00:50
b9e1354

A security update of the bundled PostgreSQL parser and vericto-engine v4.2.0
(from v4.1.3). This release can block statements that 4.12.3 let through
(see "Changed"). No wire-protocol or configuration changes.

Security

  • pg_query 6.2.1 (libpg_query 17-6.2.5), from 6.2.0 (libpg_query 17-6.2.2).
    It fixes GHSA-6ggm-xmc9-8ffg
    (High, CVSS 3.1 8.1; CWE-125, CWE-170, CWE-787): pg_query_normalize() could
    read and write heap memory out of bounds on specially crafted query text.
    The advisory is published by pganalyze in the libpg_query repository; it has
    no CVE and no RustSec entry, so cargo audit does not report it. Parsing,
    fingerprinting and deparsing are not affected.
    • The proxy is affected. For PostgreSQL traffic it passes the client's SQL
      to pg_query::normalize to strip literals from sanitized telemetry, from
      VERICTO-085 suggestions in sanitized mode, and from the query preview in
      every block log line, whatever the reporting mode. A client that can send
      SQL through the proxy could reach the bug. MySQL text is normalized with
      the proxy's own tokenizer and was not affected.
    • 6.2.1 also hardens the deparser that the engine uses for mask rewrites
      (strict checks for unexpected pointer values, parentheses kept around
      subscripted array constructors).
    • third-party/pg_query-bundled.txt names the new versions; the license
      texts did not change.

Changed

  • vericto-engine v4.2.0. What changes for traffic through the proxy:
    • The decision is the strongest action across all violations. When the
      workspace policy softens a severity (for example Critical to Flag), 4.1.3
      could let the softened violation decide for the whole statement and
      forward a script that also held a violation that blocks. With 4.2.0 such a
      script is blocked: DROP TABLE a; INSERT INTO archive SELECT * FROM accounts
      under a policy that maps Critical to Flag now blocks with VERICTO-040
      instead of being forwarded as a Flag. Nothing that 4.12.3 blocked is
      allowed now, and a statement whose violations all resolve to the same
      action gets the same decision and the same reported rule as before.
    • When the sensitive-column code shares an action with a rule, the reported
      winner can change (VERICTO-085 now ranks by severity like any rule); the
      decision and the forwarded rewrite do not.
  • The built-in ruleset is the engine's standard ruleset. The proxy used to
    keep its own copy of the 42 built-in rules for use before its first rule
    sync and whenever a sync fails; it now uses vericto_engine::standard_rules().
    The codes, severities and default actions are the same; a test still pins
    them.

CI

  • The CLA check runs in GitHub Actions instead of cla-assistant.io, whose
    webhook failed on every delivery on 2026-10-17 and 2026-10-18 and left pull
    requests without a status. .github/workflows/cla.yml (CLA Assistant Lite,
    pinned by commit SHA) reports the CLA check. The agreement is unchanged
    (ICLA v1.0, now also in CLA.md). Contributors sign it by commenting
    I have read the CLA Document and I hereby sign the CLA on their pull
    request, and recheck reruns the check. Signatures are kept on the
    cla-signatures branch. The workflow never checks out pull request code.
    No code change.

4.12.3 - 2026-10-18

Choose a tag to compare

@vericto vericto released this 18 Oct 16:58
651db7b

Requires vericto-engine v4.1.3 (from v4.1.1): fewer false positives, short
last4 values no longer shown, and -1 < 0-style tautologies now caught on
MySQL. Two upstream TLS fixes: a TLS mode the proxy does not recognise no
longer turns TLS off, and the MySQL path honours the CA bundle and client
certificate. No wire-protocol changes.

Changed

  • vericto-engine v4.1.3 (4.1.2 and 4.1.3). What changes for traffic
    through the proxy:
    • last4 masks no longer return short values in clear. A value of 8
      characters or fewer under a last4 tag is now returned as '[redacted]',
      like full; longer values keep '****' and their last four characters.
      Up to 4.1.1, '1234' came back as '****1234'. Only the rewritten SQL
      changes: which queries are allowed, flagged or blocked does not.
    • Fewer false positives on tautology rules (VERICTO-003, -030, -040,
      -042, -090). A comparison with NULL (WHERE NULL = NULL,
      WHERE NOT (NULL = 1)), a string comparison a collation can decide either
      way (NOT ('a' < 'b'), 'a' <> 'A'), literals of different kinds
      (NOT (1 = '1')) and bind parameters compared by their text (? = ?) are
      no longer reported as always true, so such a DELETE or UPDATE is no
      longer blocked. Real tautologies ('a' = 'a', 1 = 1, ' OR 'a'='a)
      still are.
    • -1 < 0 is now detected on MySQL. Negative literals were decided only
      on PostgreSQL, so DELETE … WHERE -1 < 0 (VERICTO-003) and … OR -1 < 0
      (VERICTO-090) passed the MySQL proxy. They are now blocked there, as they
      already were on Postgres. This is the one change that can block a query
      4.12.2 allowed.
    • Snowflake ORDER BY ALL is read correctly. Snowflake has no wire protocol
      for this proxy, so it does not reach the proxy.
    • No API used by the proxy changed. 4.1.3 makes the engine's constant
      comparison three-valued (parser::mod's Truth, replacing
      is_always_true / is_always_false), but all of it is crate-private and
      the proxy never called it.
  • rcgen joins the dev-dependencies, to generate throwaway CAs and
    certificates for the new TLS handshake tests. It is not in the binary, and
    no private key is committed.

Fixed

  • An unknown UPSTREAM_SSLMODE or PROXY_TLS_MODE no longer disables TLS.
    Up to 4.12.2, any value the proxy did not recognise (verify-ca, prefer,
    required, a typo) silently meant disable, so traffic on that hop went out
    in plaintext. Both variables are now read in any case with surrounding
    whitespace ignored, and any other value stops the proxy at startup with an
    error naming the variable and the accepted values, as 4.12.2 did for
    VERICTO_TELEMETRY_BUFFER. Unset or empty is still disable for both.
  • UPSTREAM_SSLMODE=verify-ca is supported, with libpq's meaning: the
    database certificate must chain to the CA in UPSTREAM_SSLROOTCERT and be
    valid, but its name is not compared with UPSTREAM_HOST. It is common in
    libpq configurations, where the database is reached through an address its
    certificate does not name (an IP, a load balancer, a tunnel). Like libpq,
    it needs UPSTREAM_SSLROOTCERT: against the public web roots, a chain check
    without a name check would accept any publicly trusted certificate and
    authenticate nothing.
  • prefer and allow are refused, not mapped to another mode. In libpq
    both connect in plaintext when the server does not offer TLS. A firewall
    proxy must not fall back to plaintext on its own, and mapping them to
    require would silently change what the operator wrote, so the error says
    why and lists require, verify-ca and verify-full.
  • The MySQL upstream path honours UPSTREAM_SSLROOTCERT. It verified
    against the public web roots only, so with verify-full a MySQL server whose
    certificate a private CA issued failed every handshake. It now uses the same
    CA bundle as Postgres, and presents UPSTREAM_SSLCERT / UPSTREAM_SSLKEY
    for mutual TLS (MySQL REQUIRE X509) when they are set. The MySQL proxy
    also loads this material at startup, as the Postgres proxy has since 4.12.2:
    a missing, empty or unparseable file, or half a pair, stops it before it
    listens.

Upgrade notes

  • Behaviour change: an unsupported TLS mode now fails startup. A
    deployment with an UPSTREAM_SSLMODE other than disable, require,
    verify-ca or verify-full, or a PROXY_TLS_MODE other than disable or
    require, ran in plaintext on that hop and now exits with, for example,
    UPSTREAM_SSLMODE="prefer" is not supported: …. Check both values before
    upgrading. A deployment with verify-ca used to run in plaintext: it now
    encrypts and verifies, and needs UPSTREAM_SSLROOTCERT.
  • Behaviour change on MySQL with upstream TLS. UPSTREAM_SSLROOTCERT,
    UPSTREAM_SSLCERT and UPSTREAM_SSLKEY were ignored on MySQL and are now
    used, and checked at startup. A MySQL deployment that sets them to a file
    that is missing or does not parse now exits at startup, and one with
    verify-full whose bundle does not hold the CA of a publicly trusted server
    certificate now fails the handshake: remove the variable, or point it at the
    right CA.
  • The engine's MySQL tautology fix can block queries that passed before
    (WHERE -1 < 0 and the like). Run the new version under monitor_mode
    first if your application issues such statements.

Tests

  • New tests for both fixes, written first and failing on 4.12.2: every
    accepted spelling of both TLS modes, unknown values and prefer/allow as
    startup errors, real handshakes against a private CA on the Postgres and
    MySQL paths (verify-full with the bundle, refused without it or with
    another CA; verify-ca accepting another name but not another CA;
    mutual TLS on both paths), a full MySQL connection phase through the proxy
    to a private-CA server, and the startup checks of the MySQL proxy.