drift Docs
Start
What is Drift?
The tour, if you are new here.
Use cases
Whether Drift does your thing.
Getting started
Nothing to deployed, in one command.
Architecture
How a slice is put together.
What it costs
The free grant, four unit prices, two rules.
Build
Canvas
Static sites, same origin as your API.
Tools
Operate
Auth
Route gates, API keys and your account.
Security
Boundaries, sandboxing and hardening.
Troubleshooting
Error codes
What went wrong, and what to do about it.
Legal
Acceptable use
What a slice may not be used for.
Data processing
The DPA, and every sub-processor.

Secrets

drift.Backbone.Secret: encrypted configuration, read at invocation time.

Signatures

Go
Get(name string) (string, error)   ·   Set(name, value string) error   ·   Delete(name string) error
Previous(name string) (string, error)   // the value this name held before its LAST replacement

A function reads; it does not write

The subprocess starts with a cleared environment and never holds the slice's internal token, so Set and Delete answer 401 from inside a function. Secrets are provisioned out of band, with drift backbone secret set, or the Driftfile.

Read secrets through the SDK, not the environment.

Secret.Get resolves the value whichever way the runtime delivered it. Reading os.environ directly works only on the per-invocation subprocess path. Python and Node functions served by the slice's persistent language server get their secrets in the request envelope instead, and the env var is absent.

A function only receives the secrets it names on its own Driftfile entry (secrets: [STRIPE_KEY]). The runner fetches each on every call, so changing a value takes effect on the next request with no redeploy. Adding a name to the list is the part that needs one.

Previous is for verifying, not presenting

A credential your function only ever sends needs nothing here: Get the current value and move on. Previous is for one your function checks against, and the case it exists for is a webhook signing secret. The moment you rotate one with drift backbone secret set, the sender you share it with is still signing with the old value until they notice, and a handler that only recognises the new one rejects every one of those as forged.

Go
sig := req.Headers["X-Signature"]
current, _ := drift.Backbone.Secret.Get("WEBHOOK")
if !verify(sig, current) {
    if prev, _ := drift.Backbone.Secret.Previous("WEBHOOK"); prev != "" && verify(sig, prev) {
        // still inside the grace window
    }
}

The replaced value stays readable for 24 hours after the rotation that replaced it, then Previous answers "" the same as it does for a secret that was never rotated or never existed. Those three cases share one answer on purpose: whichever it is, the caller's branch is "verify against the current value only." Two things do not open a window at all: setting a secret to the same value it already held, since that is not a rotation, and setting one for the first time, since there is nothing before it. Deleting a secret closes any open window immediately, so a leaked credential you remove stops verifying rather than staying valid for the rest of the day. The CLI mirrors this at drift backbone secret previous KEY, which reports whether the window is open without ever printing the value itself.

Previous always answers "" under drift atomic run.

It reads only the rotation window the runner injects into a deployed subprocess; there is nothing to fall back to locally, unlike Get. Test a verification flow that uses it against a deployed slice.