This release includes 2 breaking changes for platform teams planning a safe upgrade.
Published 1mo
AI Agents & Assistants
✓ No known CVEs patched
✓ No known CVEs patched in this version
Topics
agentic-ai
vaultwarden
Affected surfaces
auth
rbac
deps
Summary
AI summaryUpdates 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 throughImmutableSandboxedEnvironmentwith 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. Seebindings.example.yamlfor a Jira / Atlassian Cloud example anddocs/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 raiseBackendUnavailableError(never compose partial credentials); flush during assembly raises_StaleAfterFlushErrorso 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.1is now a declared direct dependency (previously transitive via mitmproxy).SecretsBackendprotocol + adapter architecture.bindings.yamluses a discriminatedbackend: {type: bws, config: {...}}block.agent_vault_proxy.backends.bws.BitwardenBackendis the reference implementation; new backends (1Password Service Accounts, HashiCorp Vault, Doppler, etc.) plug in by registering atypediscriminator.agent_vault_proxy.caching.CachingSecretsClientprovides generic TTL+jitter+LRU+singleflight caching on top of any backend. Protocol design indocs/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: C901with one-line provenance justifications. - Hash-pinned dev dependencies.
requirements-dev.lockis now hash-pinned alongsiderequirements.lock. New helper scripts:scripts/check-lockfile-hashes.py(zero-dep structural check - every pinned package must carry a--hash=sha256:continuation) andscripts/check-lockfile-drift.sh(re-runsuv pip compilewith the 7-day cooldown and diffs against committed). Both wired into pre-commit; the CIverify-lockfilejob runs the same hash check before the drift diff.
Changed
- Config:
InjectSpec.formatis nowOptional[str]and a peer of the newInjectSpec.template: Optional[str]. Exactly one of the two must be set per binding (validator-enforced). Existinginject.formatbindings continue to work unchanged. - Addon: request handlers now capture
(config, client, audit)at handler entry, preventing a mid-requestconfigure()reload from producing a torn state (Silas F3). - Dependency advances captured by the 7-day-cooldown regen:
bitwarden-sdk2.0.0 → 2.1.0,certifi2026.4.22 → 2026.5.20,click8.4.0 → 8.4.1,ruff0.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 passesscan-argsas 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.bwsmodule (theBwsClientfacade) and the top-levelbws:config block deprecation shim inconfig.py. v0.4.0 is the first public release; there are no public v0.2.0 users to migrate. Newbindings.yamlfiles must use thebackend: {type: bws, config: {...}}form (shown inbindings.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
About AVP
All releases →Related context
Related tools
Beta — feedback welcome: [email protected]