From d824b5e6aea558578fc32f322410b135d582be99 Mon Sep 17 00:00:00 2001 From: wshallwshall Date: Sat, 1 Aug 2026 10:12:16 -0500 Subject: [PATCH] fix(deps): the hvac cap the comment described was never in the specifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The [vault] extra read `hvac>=2.3.0` while its own comment said "a bare `>=` would silently jump a major on re-lock, so keep the floor pinned to the 2.x series". A bare `>=` is exactly what it was, so the intent was documented and unenforced — the prose was a compensating control resting on a false premise. That matters more here than for a typical dep: hvac fronts the store DEK (ADR 0019 §3 Vault Transit envelope decryption), and CI never installs the [vault] extra, so a major arriving through a re-lock would reach a release without one test exercising it. `hvac>=2.3.0,<3`. hvac stays at 2.4.0, so this is a no-op for the resolution: `uv lock` moves one specifier line and all SIX exported locks re-export byte-identically (verified with the CI-pinned uv 0.12.0 — requirements.lock, constraints.lock, both docker/locks, both ci/locks). DEP-1 sees no churn. No Dependabot ignore entry to match it, deliberately: auto-merge already routes majors to manual review, and an ignore would suppress hvac's security track for no gain. --- pyproject.toml | 13 +++++++++---- uv.lock | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d37f34f2..08218fc4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -164,13 +164,18 @@ webauthn = ["webauthn>=3.0.0,<4"] # HashiCorp Vault KeyProvider (ADR 0019 §3, BACKLOG #196): envelope-decrypt the store DEK via Vault # Transit. `hvac` is the OFFICIAL HashiCorp Vault Python client (Apache-2.0), named in ADR 0019 §3's # provider table. Lazy-imported (store/keyprovider_vault.py), so installs that never select -# `[store].key_provider=vault` skip it and the base install still pulls ZERO Vault SDK. Floor >=2.3.0: -# the current 2.x line (Python 3.8+, requests-based); a bare `>=` would silently jump a major on re-lock, -# so keep the floor pinned to the 2.x series. Net-new transitives (dep-vet 2026-07-10): requests + urllib3 +# `[store].key_provider=vault` skip it and the base install still pulls ZERO Vault SDK. Bounded +# >=2.3.0,<3: the current 2.x line (Python 3.8+, requests-based). The cap is the half that was missing — +# the prose already said "a bare `>=` would silently jump a major on re-lock", which is exactly what +# `hvac>=2.3.0` was, so the intent was documented and unenforced. hvac fronts the store DEK (ADR 0019 +# §3), and CI never installs the [vault] extra, so a major arriving through a re-lock would reach a +# release without a single test exercising it. Deliberately NOT mirrored by a Dependabot ignore entry: +# auto-merge already routes majors to manual review, and an ignore would suppress hvac's security track +# for no gain. Net-new transitives (dep-vet 2026-07-10): requests + urllib3 # (both ubiquitous, mature; the lock resolves urllib3>=2.7.0 — CVE-2025-50181/50182 SSRF-redirect fixes) # plus charset-normalizer/idna/certifi. hvac ships NO type stubs — mypy-strict containment lives inside # store/keyprovider_vault.py (a targeted typed local), never a repo-wide ignore. -vault = ["hvac>=2.3.0"] +vault = ["hvac>=2.3.0,<3"] # The browser ops console ([api].serve_ui, ADR 0065) is a separately-versioned second wheel # (messagefoundry-webconsole, in packaging/messagefoundry-webconsole/) mounted same-origin in-process via # mount_ui. It is deliberately NOT declared as a [webconsole] extra yet: the wheel isn't published to an diff --git a/uv.lock b/uv.lock index 8949b977..d147baa4 100644 --- a/uv.lock +++ b/uv.lock @@ -1085,7 +1085,7 @@ requires-dist = [ { name = "hl7", specifier = ">=0.4.5" }, { name = "hl7apy", specifier = ">=1.3" }, { name = "httpx", specifier = ">=0.27" }, - { name = "hvac", marker = "extra == 'vault'", specifier = ">=2.3.0" }, + { name = "hvac", marker = "extra == 'vault'", specifier = ">=2.3.0,<3" }, { name = "ldap3", specifier = ">=2.9" }, { name = "lxml", marker = "extra == 'xml'", specifier = ">=6.0.0" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.10" },