Vault

View as Markdown

Secrets live in the vault encrypted, keyed by a name you choose - logins or standalone values. Spaces mount vault prefixes, so a runtime uses a secret by reference and your code never touches the plaintext.

Store a secret

A login secret holds a username, password, and optional TOTP:

1await bctrl.vault.upsert("clients/acme/login", {
2 type: "login",
3 username: "[email protected]",
4 password: process.env.ACME_PASSWORD!,
5 totpSecret: process.env.ACME_TOTP!,
6 origins: ["https://acme.com"],
7});

A value secret holds a single string:

1await bctrl.vault.upsert("clients/acme/api-token", {
2 type: "value",
3 value: process.env.ACME_TOKEN!,
4});

Read secrets

get returns metadata only; value returns the decrypted secret.

1const meta = await bctrl.vault.get("clients/acme/login");
2const secret = await bctrl.vault.value("clients/acme/login");
3
4const { data } = await bctrl.vault.list({ prefix: "clients/acme/" });

TOTP

Generate the current one-time code for a login secret that has a TOTP seed:

1const { code } = await bctrl.vault.totp("clients/acme/login");

Update and delete

1await bctrl.vault.update("clients/acme/login", { password: "new-password" });
2await bctrl.vault.delete("clients/acme/api-token");

Mount into a space

Allow prefixes on the space environment to give its runtimes access:

1await bctrl.spaces.environment.update(space.id, {
2 vault: { allow: ["clients/acme/"] },
3});

Next