Skip to content

feat: move AWS, Azure, and 1Password vault providers to extensions#736

Merged
stack72 merged 2 commits intomainfrom
stack72/move-vault-providers-to-extensions
Mar 17, 2026
Merged

feat: move AWS, Azure, and 1Password vault providers to extensions#736
stack72 merged 2 commits intomainfrom
stack72/move-vault-providers-to-extensions

Conversation

@stack72
Copy link
Copy Markdown
Contributor

@stack72 stack72 commented Mar 17, 2026

Closes #665

Summary

Moves the aws-sm, azure-kv, and 1password vault providers from built-in types to extension vaults published at swamp.club. After this change, only local_encryption (and mock for testing) remain as built-in vault types. The three cloud/external vault providers are now independently versioned extensions that auto-resolve from the registry on first use.

What changed

Removed from core:

  • Deleted aws_vault_provider.ts, azure_kv_vault_provider.ts, onepassword_vault_provider.ts and their test files (-1,545 lines)
  • Removed aws-sm, azure-kv, 1password from BUILT_IN_VAULT_TYPES in vault_types.ts — only local_encryption remains
  • Removed their switch cases from VaultService.registerVault()
  • Removed @aws-sdk/client-secrets-manager, @azure/identity, @azure/keyvault-secrets from deno.json dependencies

Migration path via RENAMED_VAULT_TYPES:

  • aws / aws-sm@swamp/aws-sm
  • azure / azure-kv@swamp/azure-kv
  • 1password@swamp/1password

When VaultService.fromRepository() loads an existing vault config with an old type name, it remaps to the @swamp/* extension type and auto-resolves it from the registry (installed by PR #725's auto-resolution infrastructure).

vault create simplified:

  • Removed --region, --vault-url, --op-vault, --op-account flags
  • All extension vault types now use --config <json> for provider configuration
  • resolveProviderConfig() only handles local_encryption now

ensureDefaultVaults() is now a no-op:

  • Previously auto-created an AWS vault when AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_REGION were set
  • This behavior is removed since AWS is now an extension

Error messages updated:

  • "No vaults configured" error now suggests swamp extension pull @swamp/aws-sm instead of setting AWS env vars

Published extensions

The three vault providers have been published to swamp.club as:

  • @swamp/1password@2026.03.17.1 — shells out to op CLI, no npm SDK deps
  • @swamp/aws-sm@2026.03.17.1 — uses @aws-sdk/client-secrets-manager@3.1010.0
  • @swamp/azure-kv@2026.03.17.1 — uses @azure/identity@4.13.0 + @azure/keyvault-secrets@4.10.0

Source lives at https://github.com/systeminit/swamp-extensions

User impact

Existing users with vault configs on disk

No action required. Existing .swamp/vault/*.yaml files with type: aws-sm, type: azure-kv, or type: 1password continue to work. On first use, swamp will:

  1. Log a deprecation warning about the old type name
  2. Remap it to the @swamp/* extension type
  3. Auto-resolve and install the extension from the registry
  4. Load the vault and proceed normally

Creating new vaults

The CLI syntax changes from dedicated flags to --config <json>:

# Before
swamp vault create aws-sm my-vault --region us-east-1
swamp vault create azure-kv my-vault --vault-url https://myvault.vault.azure.net/
swamp vault create 1password my-vault --op-vault Engineering

# After
swamp vault create @swamp/aws-sm my-vault --config '{"region":"us-east-1"}'
swamp vault create @swamp/azure-kv my-vault --config '{"vault_url":"https://myvault.vault.azure.net/"}'
swamp vault create @swamp/1password my-vault --config '{"op_vault":"Engineering"}'

Offline users

Users without registry access can manually install extensions by placing the .ts source files in extensions/vaults/.

Binary size

The compiled binary no longer includes the AWS SDK, Azure SDK, or 1Password provider code. These dependencies are now bundled into the extensions at publish time.

Known issues

Verification

  • deno check — passes
  • deno lint — passes
  • deno fmt — passes
  • deno run test — 3138 passed, 0 failed
  • deno run compile — binary compiled successfully
  • Manual testing: auto-resolution verified for all three extensions (1password fails at op CLI check, aws-sm fails at credential check — both expected)

🤖 Generated with Claude Code

stack72 and others added 2 commits March 17, 2026 19:24
Move the aws-sm, azure-kv, and 1password vault providers from built-in
types to extension vaults, installable via swamp extension pull or
auto-resolved from the registry on first use.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vault create now auto-resolves @-prefixed vault types from the registry,
matching the behavior of model commands. This allows users to run
swamp vault create @swamp/aws-sm my-vault --config '{"region":"us-east-1"}'
without manually installing the extension first.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adversarial Review

I systematically traced code paths, examined edge cases, and stress-tested the error handling. The code is well-structured and handles the migration cleanly.

Critical / High

None found. The migration logic is sound, error handling is appropriate, and no security issues are introduced.

Medium

  1. UX gap in vault_create.ts:127-132: When a user provides a deprecated type name like aws-sm, the error message is:

    Unknown vault type: aws-sm. Available types: local_encryption. Use 'swamp vault type search' to see available types.
    

    This doesn't mention that aws-sm has been renamed to @swamp/aws-sm. Contrast with registerVault in vault_service.ts:149-155 which calls suggestVaultType() and helpfully says "The type 'aws-sm' has been renamed to '@swamp/aws-sm'". Since vault_create validates the type before calling registerVault, users hit the less helpful error first.

    Breaking example: swamp vault create aws-sm my-vault --config '{"region":"us-east-1"}' gives a confusing error instead of a migration hint.

    Suggested fix: Call suggestVaultType() in the vault_create error path, or auto-remap old type names before validation (similar to fromRepository).

  2. Extension vaults require --config even when empty (vault_create.ts:154-159): If an extension vault type has no required configuration, users still must pass --config '{}'. This is awkward but not broken.

Low

  1. Theoretical: resolveProviderConfig default case (vault_create.ts:52-53): Returns {} for unknown built-in types. Currently fine since only local_encryption and mock are built-in, but future built-in types would silently get empty config. Mock vaults already work with {} per tests.

  2. fromRepository silently swallows non-"Unsupported vault type" errors at debug level (vault_service.ts:103-105): If config schema validation fails inside registerVault for a reason other than unsupported type, the error is logged at debug level and the vault is skipped without user-visible warning. This is intentional (fallback behavior) but could mask real config errors.

Verdict

PASS — No blocking issues. The medium UX gap (missing rename hint in vault_create) is a polish issue that doesn't affect correctness. The migration path is documented in the PR body, breaking changes are intentional, and the code handles edge cases appropriately.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR cleanly moves AWS, Azure, and 1Password vault providers to extensions, reducing core dependencies while maintaining backward compatibility.

No blocking issues found.

Code Quality ✓

  • TypeScript strict mode compliance - the only any usage (AnyOptions) is properly annotated with deno-lint-ignore
  • Named exports used consistently
  • AGPLv3 headers present in all modified files
  • Clean separation of concerns

DDD Compliance ✓

  • VaultService remains a proper Domain Service (stateless operations)
  • Repository pattern used appropriately (YamlVaultConfigRepository)
  • Clean encapsulation of migration logic in RENAMED_VAULT_TYPES
  • assertVaultProvider() provides good runtime validation for extension providers

Migration Path ✓

  • RENAMED_VAULT_TYPES maps old names (aws, aws-sm, azure, azure-kv, 1password) to new extension names
  • fromRepository() auto-remaps and logs deprecation warnings
  • Error messages updated to guide users to install extensions

Test Coverage ✓

  • vault_service_test.ts: Tests error handling, renamed type suggestions, mock vault, auto-remapping behavior
  • vault_types_test.ts: Verifies only local_encryption remains as built-in
  • vault_expression_test.ts: Updated for new error message format

Suggestions (non-blocking)

  • vault_create.ts has no dedicated unit tests for the command itself - this is a pre-existing gap, not introduced by this PR

LGTM - well-executed migration with proper backward compatibility.

@stack72 stack72 merged commit d7a919c into main Mar 17, 2026
6 checks passed
@stack72 stack72 deleted the stack72/move-vault-providers-to-extensions branch March 17, 2026 19:32
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.

Move AWS, Azure, and 1Password vault providers to extensions

1 participant