Skip to main content
A bucket is the credential container an SDK, MCP server, or workspace service points at. Services declare what is enabled; buckets hold what a running app actually uses. Secrets are resolved server-side by the Engine at dispatch time. They never appear in a config file, a plan receipt, or a generated package.

Pick a bucket before you write to one

A listed bucket is one you can see, not necessarily one you may use. Choose a visible candidate, run the action you intended, and let the permission check decide. If it is denied, stop and report it — do not create a fallback bucket. Create one only when you actually need isolation:
A buckets: block in workspace.yaml configures an existing bucket. It cannot create one. If no bucket of that name exists, apply fails with “bucket not found” rather than creating it. bucket create is the only way.

Store a secret

Values are rejected in argv so they cannot survive in shell history or a process listing. Pipe them instead.
Multi-field schemes are still one value, joined with ;:
There is no --username, --password, --cert, or --key flag, and these are not two separate secrets set in two calls. Or prompt for each field:
secret set is an upsert with no apply step. It takes effect on the next request. Re-running it with a new value is how you rotate a credential — there is no versioning and no grace period, so the old value is simply gone.

Flags

secret set

--expires-at is advisory only. Listings flag an expired secret; nothing auto-rotates and nothing blocks requests when it passes. If a service declares more than one scheme, a bare set only auto-picks when there is exactly one. When two schemes share a type, --auth-name is required — the CLI fails an ambiguous selection rather than taking the first.

secret list

Secret values are never read back — metadata only.

Store a non-secret value

Some providers need a non-secret piece of configuration, like a tenant ID that appears in the host name. value set takes five positional arguments, and only the third comes from a fixed set:
The env namespace here is the bucket’s own value store — it does not read an operating-system environment variable.

Inject a bucket value into a request

An SDK or MCP service can pull those values into the outgoing request at dispatch time, so a tenant ID or account prefix never has to be hardcoded per environment. Usually you will not write these by hand — sdk init and mcp init generate them for whichever server-template variables your selected operations declare, leaving you to supply the value.
References always resolve against that app’s own bucket: — there is no way to name a different bucket here, unlike a kind: webhook secret. An ordinary injection value may also mix a tag with surrounding text, such as "Bearer ${bucket.secrets.API_KEY}". location: server_variable is stricter than the rest. Its value must be a complete ${bucket.env.KEY} or ${bucket.values.KEY} reference — never a literal, never interpolated, never a secret — because host routing has to stay non-secret and reviewable. Plan checks name against the service and operation server templates and rejects an undeclared one.

Which value wins

An omitted mode canonicalizes to force.
A host template must keep a fixed registrable anchor such as .sendbird.com. Whole-host or public-suffix-only forms like https://{host} or https://{tenant}.com fail closed — the Engine validates the resolved value and the final HTTPS URL before dispatch.

Inspect a bucket

Permissions

Connect a user's account

Static credentials cover one identity. OAuth covers one per end user.