Skip to content

AVP

v0.4.0 Breaking

This release includes 2 breaking changes for platform teams planning a safe upgrade.

✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

agentic-ai vaultwarden

Affected surfaces

auth rbac deps

Summary

AI summary

Updates names, docs/adapter-architecture.md, and Config across a mixed release.

Full changelog

First public release.

The adapter refactor (originally proposed for v0.3.0 in docs/adapter-architecture.md) is bundled with composite secrets and shipped together as v0.4.0.

Added

  • Composite secret bindings (inject.template + compose:). Bindings can now assemble a credential from 1-4 atomic BWS values at fetch time, instead of requiring the operator to pre-concatenate values in BWS (which made single-key rotation silently stale). Templates use Jinja2 syntax evaluated through ImmutableSandboxedEnvironment with a strict filter/function whitelist (b64encode, b64decode, sha256, urlencode, hmac_sha256, hmac_sha512). An AST-level deny-by-default validator at config-load rejects every Jinja2 construct outside the small set the proxy supports, class-walk escapes, control flow, attribute traversal, subscript, arithmetic are all structurally impossible. See bindings.example.yaml for a Jira / Atlassian Cloud example and docs/architecture.md §4.2 for the reference table and architectural sketch.
  • CachingSecretsClient.composite_fetch(names): atomically fetches multiple secrets under a single generation snapshot; empty BWS values raise BackendUnavailableError (never compose partial credentials); flush during assembly raises _StaleAfterFlushError so the caller restarts.
  • Same-UUID heuristic: when two distinctly-named compose entries resolve to the same value (suggesting an operator typo pointing both names at one BWS secret), the addon logs a one-shot WARNING to its own logger. The warning never includes the actual secret value.
  • jinja2 >= 3.1 is now a declared direct dependency (previously transitive via mitmproxy).
  • SecretsBackend protocol + adapter architecture. bindings.yaml uses a discriminated backend: {type: bws, config: {...}} block. agent_vault_proxy.backends.bws.BitwardenBackend is the reference implementation; new backends (1Password Service Accounts, HashiCorp Vault, Doppler, etc.) plug in by registering a type discriminator. agent_vault_proxy.caching.CachingSecretsClient provides generic TTL+jitter+LRU+singleflight caching on top of any backend. Protocol design in docs/adapter-architecture.md.
  • mypy in CI + pre-commit. Strict-ish config (warn_return_any, warn_unused_ignores, no_implicit_optional, check_untyped_defs); third-party libs without stubs (mitmproxy, bitwarden_sdk, yaml) explicitly silenced.
  • Ruff C90 cyclomatic-complexity gate (max-complexity = 10). Three pre-existing functions carry # noqa: C901 with one-line provenance justifications.
  • Hash-pinned dev dependencies. requirements-dev.lock is now hash-pinned alongside requirements.lock. New helper scripts: scripts/check-lockfile-hashes.py (zero-dep structural check - every pinned package must carry a --hash=sha256: continuation) and scripts/check-lockfile-drift.sh (re-runs uv pip compile with the 7-day cooldown and diffs against committed). Both wired into pre-commit; the CI verify-lockfile job runs the same hash check before the drift diff.

Changed

  • Config: InjectSpec.format is now Optional[str] and a peer of the new InjectSpec.template: Optional[str]. Exactly one of the two must be set per binding (validator-enforced). Existing inject.format bindings continue to work unchanged.
  • Addon: request handlers now capture (config, client, audit) at handler entry, preventing a mid-request configure() reload from producing a torn state (Silas F3).
  • Dependency advances captured by the 7-day-cooldown regen: bitwarden-sdk 2.0.0 → 2.1.0, certifi 2026.4.22 → 2026.5.20, click 8.4.0 → 8.4.1, ruff 0.15.13 → 0.15.14.
  • Security CI stack refactored to drop GitHub Advanced Security dependency. CodeQL (Python SAST) replaced with Bandit + Semgrep (community rulesets: p/security-audit + p/python + p/secrets). Gitleaks (which required a paid license for org-owned repos as of Aug 2022) replaced with TruffleHog (AGPL-3, free for everyone). OSV-Scanner switched from the action wrapper to direct binary install (the wrapper passes scan-args as a single positional arg, breaking multi-flag invocation). All security jobs now gate the merge via job-fail instead of SARIF-upload to the Security tab, workflows portable to any git host, no GHAS settings to babysit. The same three Docker-based scanners (TruffleHog, OSV-Scanner, Semgrep) also run in pre-commit so most commits hit the same gates locally before push.

Removed

  • agent_vault_proxy.bws module (the BwsClient facade) and the top-level bws: config block deprecation shim in config.py. v0.4.0 is the first public release; there are no public v0.2.0 users to migrate. New bindings.yaml files must use the backend: {type: bws, config: {...}} form (shown in bindings.example.yaml).
  • CodeQL job from .github/workflows/security.yml (replaced by Bandit + Semgrep: see above).
  • Gitleaks pre-commit hook + CI job (replaced by TruffleHog - see above).

Breaking Changes

  • Removed `agent_vault_proxy.bws` module and top‑level `bws:` config block; new configs must use `backend: {type: bws, ...}`.
  • `InjectSpec.format` is now `Optional[str]` and must be set alongside the new `InjectSpec.template`; exactly one of the two fields must be present per binding.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track AVP

Get notified when new releases ship.

Sign up free

Related context

Beta — feedback welcome: [email protected]