Skip to content

Roadmap

Same discipline as fabric-emulator: each phase independently useful, real-SDK e2e-verified, ≥90% coverage floor in CI from the first commit.

The core value: an Azure SDK acquires a token from entra-emulator via the challenge flow and round-trips secrets.

  • Foundations: clock, config (KV_* env + flags), store (vault, secret, secret_version, deleted_secret), self-signed TLS (*.vault.azure.net), Host-routed vault resolution + default seeded vault.
  • Auth: challenge 401 advertising the entra authority; RS256 validation against entra JWKS (issuer, vault audience, clock-based expiry). Reuses the validator pattern from fabric-emulator’s internal/auth.
  • Secrets: set/get/get-version/patch/list/list-versions (paged), new-version-per-PUT, enabled gating, informational nbf/exp, backup/restore.
  • Soft delete: delete → deleted state with scheduledPurgeDate on the clock; recover; purge; name-reuse conflict while deleted.
  • /_emulator clock + faults (incl. 429 throttling injection).
  • Docker (distroless) + docker-compose with entra-emulator (challenge authority pre-wired; vault resource app seeded via entra’s admin API).
  • e2e (in-process entra, like fabric-emulator’s fixture): azsecrets + azidentity.ClientSecretCredential complete the challenge flow unmodified; managed-identity path via entra’s /msi/token (IDENTITY_ENDPOINT/IDENTITY_HEADER); forged wrong-audience / expired tokens rejected; clock-advance expires a live token.
  • Keys CRUD/versions/soft-delete; RSA + EC generation (software-protected).
  • sign/verify, encrypt/decrypt, wrap/unwrap with real Go crypto — output verifiable against the returned JWK.
  • Optional per-principal permission map (/_emulator/permissions) for authorization-denied paths.
  • e2e: azkeys SDK sign → local JWK verify; encrypt → decrypt round trip.
  • Certificates CRUD + policy; self-signed issuance; PFX/PEM import; linked key/secret materialization under the same name.
  • e2e: azcertificates SDK create-self-signed → fetch → TLS-use the cert.
  • fabric-emulator AKV-reference connections resolve against this emulator (its roadmap item, built on the fabric side): workspace identity → entra token → vault secret → connection, fully offline.
  • e2e: the secret-as-SP-credential chain — the canonical “SP secret lives in Key Vault” pattern across all three emulators (e2e/chain/run.py, in CI): a client-credentials call stores an SP secret in the vault, a managed-identity token (entra /msi/token, no credential in the workload) reads it back, that secret authenticates the SP to entra for a Fabric-audience token, and the token calls fabric-emulator. Three real processes; a wrong secret breaks the chain exactly where it would in Azure.
  • entra-emulator enhancement (shipped in entra v0.2.1): recognize https://vault.azure.net (+ Storage, ARM) as well-known Azure resources, so client-credentials/MSI resolve the vault audience without seeding a resource app.
  • Compose file with all three emulators (docker-compose.yml, full profile adds fabric).

P4 — SDK parity surface (shipped in v0.2.0)

Section titled “P4 — SDK parity surface (shipped in v0.2.0)”

Round out the secondary operations the Azure SDKs expose beyond core CRUD, so a test written against azkeys / azcertificates never hits an endpoint the emulator lacks. Measured against the reference james-gould emulator; we keep our real-auth and real-crypto posture throughout. With these, the emulator reaches full parity on the SDK-observable surface.

  • Keys: import a caller-supplied JWK (PUT /keys/{name}, real RSA/EC material — a subsequent sign/verify round-trips), update-latest (PATCH /keys/{name}), backup/restore, and rotation policy get/set.
  • GetRandomBytes (POST /rng).
  • Certificates: backup/restore, update attributes/policy (PATCH /certificates/{name}), policy update (PATCH /certificates/{name}/policy), issuers (GET/PUT/PATCH/DELETE /certificates/issuers/{name} + list) and contacts (GET/PUT/DELETE /certificates/contacts).
  • Secure Key Release (POST /keys/{name}/{version}/release) — a genuine signed JWS carrying the released public JWK. No HSM attestation (there is no enclave to attest), so any enabled key is releasable; the call path and token shape are emulated.
  • Certificate CSR merge (POST /certificates/{name}/pending/merge) — a named issuer creates a pending operation with a real PKCS#10 CSR; you sign it with your own CA and merge the chain back, completing the async-issuance path fully offline. A live third-party CA remains the only certificate non-goal (the emulator never phones out).
  • CI: vet/build/test + 90% coverage floor + the three-emulator chain e2e.
  • Starlight docs site on GitHub Pages (/docs = source of truth), live at https://calvinchengx.github.io/azure-keyvault-emulator/.
  • GoReleaser: binaries + distroless Docker (GHCR) + Homebrew + winget. v0.1.0 shipped P0–P3; v0.2.0 adds the full P4 parity surface (import, backup/restore, rng, rotation policy, key release, issuers, contacts, certificate CSR merge) and the operator portal.
  • Svelte operator portal (v0.2.0) — dashboard, secrets/keys/certificates/deleted views, clock + fault-injection controls. Svelte 5, built to a committed portal/dist, embedded via go:embed, served at /_emulator/portal/, with a CI drift guard + Playwright mount smoke. Mirrors the family pattern.

Build the challenge handshake before any storage — it is this emulator’s reason to exist, every SDK call path runs through it, and it defines the integration contract with entra-emulator. Secrets storage is straightforward once auth is honest.