Skip to content

feat: Adding Azure Key Vault keys and cryptography - #287

Open
parthcodes wants to merge 6 commits into
floci-io:mainfrom
parthcodes:feat/keyvault-enhancements
Open

feat: Adding Azure Key Vault keys and cryptography#287
parthcodes wants to merge 6 commits into
floci-io:mainfrom
parthcodes:feat/keyvault-enhancements

Conversation

@parthcodes

@parthcodes parthcodes commented Sep 8, 2026

Copy link
Copy Markdown

Summary

Adds Azure Key Vault keys and cryptography to floci-az (as requested in #194 ), plus a Managed HSM flavor, and fixes the self-signed TLS certificate so strict X.509 validators (e.g. Rust's rustls-platform-verifier) can trust floci-az's HTTPS endpoint.

Two parts:

  1. feat(keyvault) — key CRUD (RSA/EC/oct, including -HSM variants), versions, soft-delete/recover/purge, backup/restore, key rotation + rotation policy, encrypt/decrypt/sign/verify/wrap/unwrap (RSA-OAEP, RSA-OAEP-256, RSA1_5, AES-GCM; RS*/PS*/ES*), and /rng. The same data plane is served under the /{account}-managedhsm/ suffix, with ARM Microsoft.KeyVault/managedHSMs CRUD.
  2. fix(tls) — the self-signed HTTPS certificate was a single, CA-flagged certificate presented in the leaf/end-entity position, which strict path validators reject (CaUsedAsEndEntity). floci-az now generates a proper CA → leaf chain and serves the CA at GET /_floci/tls-cert as the trust anchor. This also closes a SAN gap by adding *.managedhsm.azure.net.

Type of change

  • Bug fix (fix:)
  • New feature (feat:)
  • Breaking change (feat!: or fix!:)
  • Docs / chore

Azure Compatibility

  • Keys / crypto / Managed HSM verified with the Azure SDKs for Java (azure-security-keyvault-keys + cryptography), Python (azure-keyvault-keys ≥ 4.7.0), JavaScript (@azure/keyvault-keys ^4.9.0), and the az keyvault key CLI (crypto ops, rotation policy, soft-delete lifecycle). Wire protocol follows the Key Vault REST API (api-version=7.4); intentional deviations are documented in docs/services/key-vault.md.
  • TLS fix — previous behavior: a CA-flagged cert was presented as the server leaf, so strict validators (rustls) failed the handshake. New behavior: a CA-signed, non-CA leaf chain; verified end-to-end with openssl verify and openssl s_client -verify_hostname returning Verify return code: 0 against the CA served at /_floci/tls-cert.

Checklist

  • ./mvnw test passes locally
  • New or updated integration test added
  • Commit messages follow Conventional Commits

@greptile-apps

greptile-apps Bot commented Sep 8, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds Azure Key Vault key management and cryptographic operations, Managed HSM routing and ARM resources, and a proper CA-to-leaf TLS certificate chain. Since the previous review, the Node compatibility client was corrected to use an Azure-shaped key identifier and rewrite cryptography requests onto the emulator route.

  • Supports RSA, EC, and symmetric keys, including versions, soft deletion, backup, restoration, and rotation policies.
  • Adds encrypt/decrypt, sign/verify, wrap/unwrap, and random-number operations.
  • Isolates Key Vault and Managed HSM state.
  • Prevents symmetric key material from appearing in API responses.
  • Enforces AES-GCM algorithm and key-size consistency.
  • Bounds native smoke-test readiness and cleans up the runner.
  • Adds Java, Node, Python, Azure CLI, unit, routing, ARM, and TLS compatibility coverage.

Confidence Score: 5/5

The PR appears safe to merge; no actionable new issue remains, and all previous findings are manually resolved and addressed in the current code.

The changes since the previous review correctly route Node CryptographyClient requests through the emulator. Current code also withholds symmetric key material, isolates Managed HSM state, rejects recreation of soft-deleted names, validates GCM key sizes, and bounds and cleans up the native smoke test. All previous threads were manually resolved without explanation.

Important Files Changed

Filename Overview
src/main/java/io/floci/az/services/keyvault/KeyVaultKeys.java Implements key CRUD, versioning, lifecycle, backup and restore, rotation policies, and flavor-scoped Key Vault and Managed HSM storage.
src/main/java/io/floci/az/services/keyvault/KeyVaultCrypto.java Implements RSA, EC, and AES cryptography while withholding private and symmetric key material from responses and validating GCM key sizes.
src/main/java/io/floci/az/services/keyvault/KeyVaultHandler.java Adds Key Vault keys, cryptography, RNG, and Managed HSM data-plane dispatch.
src/main/java/io/floci/az/core/AzureRoutingFilter.java Extends routing to recognize the new Key Vault and Managed HSM endpoint forms.
src/main/java/io/floci/az/core/tls/CertificateGenerator.java Replaces the CA-as-leaf certificate with a CA-signed server certificate and appropriate SAN coverage.
compatibility-tests/sdk-test-node/tests/keyvault-keys.test.ts Uses an Azure-shaped key identifier and a per-call policy to redirect Node cryptography requests to the emulator.
Makefile Adds a bounded native-image cryptography smoke gate with runner cleanup.

Reviews (4): Last reviewed commit: "fix(keyvault): build host-based crypto k..." | Re-trigger Greptile

Comment thread src/main/java/io/floci/az/services/keyvault/KeyVaultCrypto.java Outdated
Comment thread src/main/java/io/floci/az/services/keyvault/KeyVaultKeys.java Outdated
Comment thread src/main/java/io/floci/az/services/keyvault/KeyVaultKeys.java Outdated
Comment thread src/main/java/io/floci/az/services/keyvault/KeyVaultCrypto.java
Comment thread Makefile Outdated
@hectorvent

Copy link
Copy Markdown
Contributor

Thank you for this, and sorry about the conflict: merging #228 changed AzureRoutingFilter, the same method your account suffix hardening edits. That one file is the only conflict, everything else auto merges.

(blocking) Your CI has run now, and RSA-OAEP-256 fails in the Python, Node and az CLI suites. Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding") without an OAEPParameterSpec gives digest SHA-256 with MGF1 SHA-1 under SunJCE (reproduced on Java 25: MD: SHA-256, MGF: MGF1SHA-1). Clients use MGF1 SHA-256 (rsa_encryption.py#L67) and encrypt locally, so only the decrypt reaches floci-az and the padding check fails. An explicit new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT) fixes it.

Worth saying: the Java suite is green because the Java SDK has no local OAEP-256 path (RsaOaep.java#L64 is SHA-1 only), so both halves of that round trip go through the emulator and agree. Easy thing to be caught by.

The rebase and that padding change unblock this.

…ility

- Never expose symmetric (oct) key material in key responses; it stays
  server-side for AES-GCM crypto (Get Key REST API parity).
- Scope key storage per flavor so {account}-keyvault and
  {account}-managedhsm keys no longer share state.
- Return 409 Conflict when recreating a soft-deleted key name.
- Reject AES-GCM operations when the key size does not match the
  algorithm (400 BadParameter).
- Accept PATCH /keys/{name} (empty version) for az keyvault key
  set-attributes instead of 405.
- Bound the smoke-native-crypto readiness wait and always clean up the
  native runner.

- Repair crypto compatibility tests across Java/Python/Node: build
  host-based key identifiers (the only shape the SDK parsers accept) and
  rewrite requests onto the path-based emulator route; assert symmetric
  key material is absent; fix TypeScript null-safety and the GCM decrypt
  parameter shape; replace the non-existent assert_not_empty BATS helper.
SunJCE's OAEPWithSHA-256AndMGF1Padding defaults MGF to SHA-1 without an
explicit OAEPParameterSpec, so decrypt rejected ciphertext from SDKs that
encrypt locally with MGF1 SHA-256. Pass an explicit OAEPParameterSpec for
both OAEP variants.
Decrypt ciphertext produced by an independent JDK encryptor using an
explicit OAEPParameterSpec (SHA-256 + MGF1 SHA-256), the convention the
Python/Node/az SDKs use when encrypting locally.
@parthcodes
parthcodes force-pushed the feat/keyvault-enhancements branch from 579df06 to 017270f Compare September 9, 2026 00:43
@hectorvent hectorvent added arm Azure Resource Manager (ARM) documentation Improvements or additions to documentation feature keyvault Azure Key Vault labels Sep 9, 2026
@parthcodes

parthcodes commented Sep 10, 2026

Copy link
Copy Markdown
Author

@hectorvent
Both items are addressed:

  1. RSA-OAEP-256 now uses an explicit OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT) for encrypt/decrypt (wrap/unwrap share that path), plus an interop test that encrypts with MGF1 SHA-256 and decrypts through floci-az.

  2. Rebased onto the AzureRoutingFilter changes from earlier PR feat: add Azure Container Apps support #228, so that conflict is gone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arm Azure Resource Manager (ARM) documentation Improvements or additions to documentation feature keyvault Azure Key Vault waiting-contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants