Skip to content

feat(azure): add Key Vault explorer#147

Open
thomhurst wants to merge 2 commits into
floci-io:mainfrom
thomhurst:agent/azure-key-vault
Open

feat(azure): add Key Vault explorer#147
thomhurst wants to merge 2 commits into
floci-io:mainfrom
thomhurst:agent/azure-key-vault

Conversation

@thomhurst

@thomhurst thomhurst commented Jul 18, 2026

Copy link
Copy Markdown

Summary

  • add the generic secrets service schema and Azure Key Vault adapter
  • expose Key Vault in the Azure Cloud Explorer with password-masked secret input
  • normalize secret metadata without exposing values and document remaining lifecycle gaps
  • add adapter and generic route coverage

Validation

  • pnpm lint
  • pnpm type-check
  • pnpm dlx bun test (168 passed)
  • pnpm build
  • Playwright CLI: create, list, inspect, and soft-delete against Floci-AZ on localhost:4577; 0 console errors

Closes #95

image

Wire Key Vault secret CRUD through the generic secrets service contract.

Closes floci-io#95
@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown

Greptile Summary

This PR wires Azure Key Vault into the generic schema-driven Cloud Explorer following the canonical AGENTS.md pattern — schema, adapter, registration, nav entry, and frontend type extensions. It also resolves two previously flagged issues: the x-ms-version Blob Storage header no longer leaks into Key Vault requests (via the new includeStorageApiVersion opt-out), and list pagination is now fully handled with a while (nextLink) loop.

  • AzureKeyVaultAdapter covers list (paginated), get, create (with name/value validation), and soft-delete via the Key Vault 7.4 data-plane API; secret values are stripped from all normalized responses.
  • secretsSchema.ts adds the create-form fields (secretName with regex validation, secretValue as password type, contentType), column definitions, and a per-cloud secretsSchemaFor() factory used by CloudProxyService.
  • Frontend changes add the KeyRound-icon nav entry (Azure-only), type="password" rendering in DynamicFormRenderer, and the 'secret' / 'secrets' / 'password' type extensions across the shared type files.

Confidence Score: 5/5

Safe to merge — the adapter follows the established schema-driven pattern and both previously flagged gaps (header leak and truncated pagination) are resolved.

The two previously open issues are cleanly addressed: the x-ms-version header is now opt-out via includeStorageApiVersion: false, and the list operation fetches all pages before returning. The adapter, schema, and frontend additions are all narrow and follow the AGENTS.md canonical pattern. Test coverage is solid (pagination, value masking, name validation, create/delete contracts, missing-secret normalization).

No files require special attention.

Important Files Changed

Filename Overview
packages/api/src/adapter-azure/AzureKeyVaultAdapter.ts New adapter implementing full CRUD for Azure Key Vault via the generic SPI; includes pagination loop with nextLink handling, secret value masking, and URL-based ID parsing.
packages/api/src/adapter-azure/AzureKeyVaultAdapter.test.ts Comprehensive test suite covering list with two-page pagination, get with value masking, create, delete, null normalization, name validation, and schema introspection.
packages/api/src/azure.ts Adds includeStorageApiVersion opt-out flag to AzureRestRuntimeClient.fetch so Key Vault calls no longer carry the Blob Storage x-ms-version header.
packages/api/src/cloud-spi/secretsSchema.ts New secrets schema with secretName (text+pattern), secretValue (password), and contentType fields; exposes create/list/delete/inspect actions and provides a secretsSchemaFor factory.
packages/api/src/service/CloudProxyService.ts Adds secrets service entry (with per-cloud label) to listServices() and wires secretsSchemaFor() into the schema fallback chain.
packages/frontend/src/components/DynamicFormRenderer.tsx Adds type="password" rendering for password-typed schema fields so secretValue is masked in the create form.
packages/frontend/src/components/Layout.tsx Registers KeyRound icon and 'secrets' nav item, gated to cloud === 'azure' in the sidebar visibility check.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser as Browser (React :4500)
    participant API as Hono API (:4501)
    participant CPS as CloudProxyService
    participant Adapter as AzureKeyVaultAdapter
    participant Emulator as Floci-AZ (:4577)

    Browser->>API: GET /api/clouds/azure/services/secrets/schema
    API->>CPS: schema('azure','secrets')
    CPS->>Adapter: schema()
    Adapter-->>Browser: azureSecretsSchema (fields, actions, columns)

    Browser->>API: GET /api/clouds/azure/services/secrets
    API->>CPS: list('azure','secrets', query)
    CPS->>Adapter: "list({search})"
    loop Paginate nextLink
        Adapter->>Emulator: "GET /{account}-keyvault/secrets?api-version=7.4"
        Emulator-->>Adapter: "{value:[...], nextLink}"
    end
    Adapter-->>Browser: CloudResource[] (values stripped)

    Browser->>API: POST /api/clouds/azure/services/secrets
    API->>CPS: create('azure','secrets', input)
    CPS->>Adapter: "create({secretName, secretValue, contentType})"
    Adapter->>Emulator: "PUT /{account}-keyvault/secrets/{name}?api-version=7.4"
    Emulator-->>Browser: CloudResource (value stripped)

    Browser->>API: "DELETE /api/clouds/azure/services/secrets/{id}"
    API->>CPS: delete('azure','secrets', id)
    CPS->>Adapter: delete(id)
    Adapter->>Emulator: "DELETE /{account}-keyvault/secrets/{id}?api-version=7.4"
    Emulator-->>Browser: 204 No Content
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Browser as Browser (React :4500)
    participant API as Hono API (:4501)
    participant CPS as CloudProxyService
    participant Adapter as AzureKeyVaultAdapter
    participant Emulator as Floci-AZ (:4577)

    Browser->>API: GET /api/clouds/azure/services/secrets/schema
    API->>CPS: schema('azure','secrets')
    CPS->>Adapter: schema()
    Adapter-->>Browser: azureSecretsSchema (fields, actions, columns)

    Browser->>API: GET /api/clouds/azure/services/secrets
    API->>CPS: list('azure','secrets', query)
    CPS->>Adapter: "list({search})"
    loop Paginate nextLink
        Adapter->>Emulator: "GET /{account}-keyvault/secrets?api-version=7.4"
        Emulator-->>Adapter: "{value:[...], nextLink}"
    end
    Adapter-->>Browser: CloudResource[] (values stripped)

    Browser->>API: POST /api/clouds/azure/services/secrets
    API->>CPS: create('azure','secrets', input)
    CPS->>Adapter: "create({secretName, secretValue, contentType})"
    Adapter->>Emulator: "PUT /{account}-keyvault/secrets/{name}?api-version=7.4"
    Emulator-->>Browser: CloudResource (value stripped)

    Browser->>API: "DELETE /api/clouds/azure/services/secrets/{id}"
    API->>CPS: delete('azure','secrets', id)
    CPS->>Adapter: delete(id)
    Adapter->>Emulator: "DELETE /{account}-keyvault/secrets/{id}?api-version=7.4"
    Emulator-->>Browser: 204 No Content
Loading

Reviews (2): Last reviewed commit: "fix(azure): correct Key Vault requests" | Re-trigger Greptile

Comment thread packages/api/src/adapter-azure/AzureKeyVaultAdapter.ts
Follow continuation links so list results are complete. Omit the Blob Storage API version header from Key Vault calls.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(azure): Key Vault in Cloud Explorer

1 participant