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.tsThe file path is relative to the extensions/vaults/ directory within the
extension root.