feat(backend-azure): v0.3 Phase 2 — Azure Key Vault backend#45
Merged
TechAlchemistX merged 2 commits intomainfrom Apr 19, 2026
Merged
feat(backend-azure): v0.3 Phase 2 — Azure Key Vault backend#45TechAlchemistX merged 2 commits intomainfrom
TechAlchemistX merged 2 commits intomainfrom
Conversation
Second v0.3 backend: `secretenv-backend-azure` wraps the `az` CLI. Strict-mode mocks from day one — 36 tests. Near-mirror of the Phase 1 gcp pattern with three Azure-specific additions. - **Vault URL regex** at factory time covers all four sovereign clouds (.vault.azure.net|.vault.azure.cn|.vault.usgovcloudapi.net| .vault.microsoftazure.de) with anchored `/?$` to block path traversal (`https://foo.vault.azure.net/evil/../etc` rejected) + hyphen-edge vault-name rejection. Regex discipline was the explicit call-out in the spec — `url::Url::parse` accepts traversal shapes. - **URI shape:** `azure-<instance>:///<secret-name>[#version=<32-hex>]`. Canonical `#version=<id>` accepts 32-char lowercase hex OR `latest`; `latest` normalizes to omitting the `--version` flag (Azure CLI does NOT treat `latest` as a keyword here). - **CV-1 + encoding lock:** `set` uses `--file /dev/stdin --encoding utf-8`. The `--encoding utf-8` flag is load-bearing — the default `base64` would interpret stdin as b64-encoded and corrupt stored secrets. Dedicated drift-catch test (`set_drift_catch_rejects_missing_encoding_utf8`) declares the buggy argv form so a regression dropping the flag fails the mock. - **`--value`-leak POSITIVE drift-catch:** declared argv carries the BUGGY `--value <secret>` form. Post-fix code emits `--file /dev/stdin` instead — diverges, exit 97. Guards against future refactors "optimizing small values onto argv" (which would break CV-1). - **Cert-bound-secret detection:** `kid != null` in the `az keyvault secret show` JSON response surfaces a distinct error — v0.3 targets text secrets only. - **`check()`:** Level 1 (`az --version`, multi-line stripped) + Level 2 (`az account show --output json`, JSON parsed) via `tokio::join!`. Identity `user=<name> tenant=<id> subscription=<name> vault=<short>`. - **Soft-delete documented.** `delete` is soft (Azure default); we do NOT chain `secret purge`. Asymmetric with aws-secrets (--force-delete-without-recovery) and gcp (full delete) — platform reality. - **CLI surface:** `secretenv setup` gains `--azure-vault-url` + `--azure-tenant` + `--azure-subscription`. `backend_type_from_scheme` accepts `azure(-*)`. `serialize_registry` adds azure to the JSON arm. `setup_rejects_unknown_scheme` now uses `totally-made-up://` — all in-spec schemes now route. - Brings `regex = "1"` into the workspace as a new dep (first user). - Workspace tests 398 → 435 (+37: 36 crate + 1 setup). Gates: fmt ✅ clippy (-D warnings) ✅ test ✅ deny ✅ audit ✅. Spec: kb/wiki/backends/azure.md. Build-log: kb/wiki/build-log.md §v0.3 Phase 2. Ships as part of the aggregate `v0.3.0` release alongside gcp (Phase 1, merged as #44). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-launch licensing change. v0.1 and v0.2.0 shipped under MIT (v0.2.0 is the only release currently published on crates.io / Homebrew / GH Releases). v0.3.0 and all subsequent releases ship under GNU Affero General Public License v3.0 (AGPL-3.0-only). The published MIT releases remain available under their original terms. Rationale: v0.3.0 finalizes the big-3-cloud-providers story (AWS + GCP + Azure) and the install base at the time of this change is effectively zero (zero crates.io downloads for v0.2.0 in the last 7 days; no HN launch yet). AGPLv3 closes the SaaS-wrapping loophole — §13 requires source availability to network users of modified versions — while preserving user freedom for direct installs. Paired with a Contributor License Agreement (license grant, NOT copyright assignment) to enable dual-licensing if commercial terms are ever needed. Changes: - LICENSE: full AGPLv3 text (GNU canonical, fetched via `gh api /licenses/agpl-3.0`). - Cargo.toml `[workspace.package] license`: "MIT" → "AGPL-3.0-only". Every crate inherits via `license.workspace = true`; no per-crate edit needed. - deny.toml: added "AGPL-3.0-only" to the licenses.allow list so `cargo deny check` accepts the workspace's own crates. The broader third-party allowlist (MIT / Apache-2.0 / BSD / ISC / Unicode / CC0 / Zlib / MPL-2.0) is unchanged — copy-left-strong upstreams (GPL-family) still require explicit review before adoption. - README: license badge MIT → AGPL v3; expanded License section explains the switch + the §13 SaaS-source-availability requirement + links to CLA. - CLA.md (new): the Individual Contributor License Agreement. Grants the project a perpetual, worldwide, non-exclusive, royalty-free copyright + patent license AND the right to relicense the Contribution under any terms (enables dual-licensing). Explicitly NOT a copyright assignment — contributors retain ownership. Signing via `git commit --signoff` on every commit + adding name to AUTHORS.md on first contribution. Corporate contributors contact the maintainer for a Corporate CLA. - AUTHORS.md (new): ledger of CLA-signed contributors. Seeded with the project maintainer. - CONTRIBUTING.md: new §License-and-CLA section documenting the signing mechanism + disambiguating `-s` (sign-off = CLA) from `-S` (cryptographic signature = commit-signing). Both are required. - CHANGELOG.md: flagged as a pre-launch breaking change per the policy in the session memory (install base zero + CHANGELOG documents the exception honestly). Gates: fmt ✅ clippy ✅ test ✅ (435/435) deny ✅ audit ✅. Ships on PR #45 (v0.3 Phase 2 / Azure) as part of the aggregate v0.3.0 release gate. Signed-off-by: Mandeep Patel <mandeep@techalchemist.io> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: TechAlchemistX <mandeep@techalchemist.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two changes bundled on this PR: (1) v0.3 Phase 2 Azure Key Vault backend, (2) licensing switch MIT → AGPL-3.0-only + CLA.
Phase 2 — Azure Key Vault backend
secretenv-backend-azurewrapsaz keyvault secret show/set/delete+az account show. Strict-mode mocks from day one (36 crate tests + 1 setup test = +37 workspace, 398 → 435)./?$to block path traversal + hyphen-edge rejection. Chose regex overurl::Url::parse(latter accepts/evil/../etc).#version=<32-hex>directive;latestnormalizes to omitting the flag.--file /dev/stdin --encoding utf-8.--encoding utf-8is load-bearing (defaultbase64corrupts). Dedicated drift-catch test locks both the flag presence and a positive--value-leak lock.kid != null) surfaces a distinct error.tokio::join!(version + account) —az account showreturns identity in a single response.regex = "1"into the workspace (first user).License switch — MIT → AGPL-3.0-only + CLA
Pre-launch change while install base is still effectively zero.
LICENSE: full AGPLv3 text (GNU canonical).Cargo.tomlworkspacelicense = "AGPL-3.0-only". All crates inherit.deny.tomlallowlist gains"AGPL-3.0-only"so cargo-deny accepts the workspace's own crates.README.mdbadge + License section rewritten; explains §13 SaaS-source-availability + MIT-era disclosure.CLA.md(new): Individual CLA — license grant (NOT copyright assignment) + right to relicense (for dual-licensing).AUTHORS.md(new): CLA-signed contributor ledger.CONTRIBUTING.md: new §License-and-CLA section; disambiguates-s(signoff / CLA) vs-S(cryptographic signature / commit-signing). Both required.CHANGELOG.mdflags the change under the pre-launch breaking-change policy.Specs:
kb/wiki/backends/azure.md,kb/wiki/backends/gcp.md(Phase 1, merged #44).Test plan
cargo fmt --checkcargo clippy --workspace --all-targets --all-features -- -D warningscargo test --workspace— 435/435cargo deny checkcargo audit🤖 Generated with Claude Code