Skip to main content

VAULT PROVIDER

A vault provider is a TypeScript module that implements secret storage and retrieval for a custom backend. The file lives in extensions/vaults/ and exports a vault object that swamp loads at runtime.

For vault configuration and usage (creating vaults, storing secrets, CEL integration), see the Vaults reference.

Export Shape

import { z } from "npm:zod@4";

export const vault = {
  type: "@mycollective/my-vault",
  name: "My Vault",
  description: "Store secrets in my backend",
  configSchema: z.object({
    region: z.string().describe("Backend region"),
  }),
  createProvider(
    name: string,
    config: Record<string, unknown>,
  ): VaultProvider {
    // validate config, return provider instance
  },
};

Fields

Field Type Description
type string Unique identifier in @collective/name format. Reserved collectives: swamp, si.
name string Human-readable display name.
description string Short description shown in swamp vault type search.
configSchema z.ZodTypeAny Zod schema that validates the config object passed at vault creation time.
createProvider (name: string, config: Record<string, unknown>) => VaultProvider Factory that returns a provider instance. name is the vault's user-assigned name.

VaultProvider Interface

The object returned by createProvider must implement four methods.

Method Signature Description
get (secretKey: string) => Promise<string> Retrieve a secret value by key. Throw if the key does not exist.
put (secretKey: string, secretValue: string) => Promise<void> Store a secret value, creating or overwriting the key.
list () => Promise<string[]> List all secret key names. Values are never returned.
getName () => string Return the vault's user-assigned name.

Minimal Example

import { z } from "npm:zod@4";

interface VaultProvider {
  get(secretKey: string): Promise<string>;
  put(secretKey: string, secretValue: string): Promise<void>;
  list(): Promise<string[]>;
  getName(): string;
}

const configSchema = z.object({
  endpoint: z.string().url().describe("Backend API endpoint"),
  token: z.string().describe("Authentication token"),
});

export const vault = {
  type: "@mycollective/kv-vault",
  name: "KV Vault",
  description: "Store secrets in a key-value API",
  configSchema,

  createProvider(
    name: string,
    config: Record<string, unknown>,
  ): VaultProvider {
    const { endpoint, token } = configSchema.parse(config);
    const headers = { Authorization: `Bearer ${token}` };

    return {
      async get(secretKey: string): Promise<string> {
        const res = await fetch(`${endpoint}/secrets/${secretKey}`, {
          headers,
        });
        if (!res.ok) throw new Error(`Secret "${secretKey}" not found`);
        const data = await res.json();
        return data.value;
      },

      async put(secretKey: string, secretValue: string): Promise<void> {
        await fetch(`${endpoint}/secrets/${secretKey}`, {
          method: "PUT",
          headers: { ...headers, "Content-Type": "application/json" },
          body: JSON.stringify({ value: secretValue }),
        });
      },

      async list(): Promise<string[]> {
        const res = await fetch(`${endpoint}/secrets`, { headers });
        const data = await res.json();
        return data.keys;
      },

      getName(): string {
        return name;
      },
    };
  },
};

Packaging

Declare the vault in your extension's manifest:

vaults:
  - kv_vault.ts

The file path is relative to the extensions/vaults/ directory within the extension root.