define* resources (env() / secret() / workspaceEnv()) and for the CLI
itself (CARGO_* variables). This page covers both, and how to deploy the same
code to more than one workspace.
env(), secret() and workspaceEnv()
Three helpers, each with one behaviour. The first two read your local
environment; the third reads nothing locally and points at the workspace’s own
environment variables:
connectors/hubspot.ts
How each behaves
env("NAME")readsprocess.env.NAMEwhen the file is imported and inlines the value into the spec. If the variable is unset it returns a visible${NAME}placeholder so the gap surfaces incargo-ai project plan.secret("NAME")returns a deferred reference (EncryptionRef). At apply time the project readsprocess.env.NAME, wraps it in Cargo’s encryption envelope, and sends it to the API. The deploy fails if the variable is not set locally — it does not fall back to the workspace catalog, so a credential’s behaviour never depends on what the deploying machine happened to have exported. Because the reference — not the value — enters the spec, rotating a secret doesn’t register as drift, and a plaindeploywon’t push the new value (nothing in the hash changed). Re-apply the resource to roll a rotated secret: make any other change, or runcargo-ai project deploy --refresh.workspaceEnv("KEY")returns a deferred pointer (WorkspaceEnvRef). At apply time it becomes a reference to the workspace variable namedKEY; the value stays server-side and never reaches the deploying machine. It is read again on every use, so rotating it needs no re-apply at all — see rotating a value.cargo-ai project planfails if the workspace holds no such variable.
Where each is accepted
The distinction is load-bearing, and the generated types enforce it:workspaceEnv() is deliberately a type error on a resource’s own env, because
those runtimes already receive every workspace variable by inheritance — a
pointer there could only restate a variable the resource can read anyway. Config
is different: a connector’s credential is a single field, so pointing it at the
catalog is the only way to make it rotate without a redeploy.
See State & drift for how the content hash drives
what a deploy considers changed.
Workspace environment variables
A workspace holds its own set of environment variables, managed under Settings → Environment (or withcargo-ai workspaceManagement envVar).
Store a value once there instead of setting it on every worker, app and agent
that needs it. Secrets are encrypted at rest and their values are never
returned by the API.
Every worker, app and agent in the workspace picks them up automatically — you
do not declare them on the resource:
An app bundle is served to the browser, which is why a secret is never put in
one. Give an app its public configuration under a
VITE_ key and keep the
credential it must not expose on a worker instead.
A variable set on the resource itself wins over the workspace variable with
the same key, so a single worker can override one value without a copy of the
rest. That is also what secret("NAME") does at deploy time: the value your
shell exports is sent as that resource’s own value for this apply, and the
catalog is left untouched.
Rotating a value
A resource never holds a copy of a workspace variable — it inherits it, or holds aworkspaceEnv() pointer, resolved each time the value is needed. Rotating the
value under Settings → Environment therefore reaches everything that reads
it, with no redeploy. When it takes effect depends only on when the resource next
reads it:
Workers and apps bake their environment into a build artifact, so those two need
a redeploy. Nothing else does.
A
workspaceEnv() pointer is checked at plan time, so a cargo-ai project deploy
naming a variable the workspace does not hold fails before it creates
anything. That check needs the API; an offline plan skips it.CLI environment variables
Thecargo-ai CLI (and therefore cargo-ai project) reads three environment
variables. They take precedence over the saved credentials file
(~/.config/cargo-ai/credentials.json):
In CI or an AI coding agent, set these instead of running
cargo-ai login:
whoami reports the source as environment when a CARGO_API_TOKEN is set,
or credentials-file when it’s reading the saved login.
Promoting code to a second workspace
The same project code can deploy to multiple workspaces (e.g. staging → production). Two things change per workspace; the code does not:- Which workspace you target — set
CARGO_WORKSPACE_UUID(or log in to that workspace), socargo-ai project deployresolves the right target. - The secret values — either export each environment’s
secret()values before deploying, or write the code withworkspaceEnv("KEY")and store the value once in each workspace’s environment variables. The second is usually what you want for promotion: each workspace holds its own value under the same key, so pointing the same code at production is nothing beyond selecting the workspace.

