Skip to main content
A secret needs a name, a value (the real credential), and a way to authenticate — either a provider shortcut or a custom auth config. The value is encrypted on the platform and never returned by the API.

Provider shortcuts

The fastest path. A shortcut sets the auth scheme and allowed hosts for a known service, so you supply only a name and value:
import { Secret } from "@superserve/sdk"

const secret = await Secret.create({
  name: "openai-prod",
  value: process.env.OPENAI_API_KEY!,
  provider: "openai",
})

console.log(secret.hosts)  // ["api.openai.com"]
Built-in providers span LLM APIs, dev tools, and SaaS, and the list grows over time. Provider.list() returns the full current set — names, hosts, and token shape:
import { Provider } from "@superserve/sdk"

const providers = await Provider.list()
for (const p of providers) {
  console.log(p.name, p.hosts)  // "anthropic" ["api.anthropic.com"]
}

Custom secrets

When there’s no shortcut, define the auth yourself with auth and hosts. auth and provider are mutually exclusive — pick one. The auth.type controls how the credential is attached to outbound requests:
typeAttaches as
bearerAuthorization: Bearer <value>
api-keya named header — <header>: <prefix><value>
basicHTTP Basic, <username>:<value>
customarbitrary header templates referencing {{ value }}
// One host, key sent in the Authorization header.
await Secret.create({
  name: "linear-key",
  value: "lin_api_...",
  hosts: ["api.linear.app"],
  auth: { type: "api-key", header: "Authorization" },
})

Per-host auth

A single secret can authenticate differently per host — useful when one credential works across, say, a REST API and a git endpoint:
await Secret.create({
  name: "github-token",
  value: "ghp_...",
  hosts: ["api.github.com", "github.com"],
  auth: {
    perHost: [
      { hosts: ["api.github.com"], type: "bearer" },
      { hosts: ["github.com"], type: "basic", username: "x-access-token" },
    ],
  },
})
hosts accepts wildcards (*.example.com), but not a whole top-level domain like *.com. A wildcard matches subdomains, not the domain itself — list both example.com and *.example.com if you need each.

Rotation

Replace a secret’s value without recreating it. Bound sandboxes keep their environment variable; the new value is used on subsequent requests — no redeploy, no restart.
const secret = await Secret.get("openai-prod")
await secret.rotate(newKey)

List and delete

const secrets = await Secret.list()

await Secret.deleteByName("openai-prod")
// or, from an instance:
await secret.delete()
Deleting a secret takes effect immediately, everywhere it’s bound — any sandbox still using it starts failing at once. The environment variable stays, but its stand-in token no longer works. If you only want to change the value, rotate instead.

Next steps

Bind to a sandbox

Attach the secret to an environment variable so code in the sandbox can use it.