Secrets & Environment
Jobs, Services, and VMs accept ordinary environment variables and named secret bundles. Use environment values for non-sensitive, deployment-specific configuration. Use Secrets for reusable API keys, tokens, and passwords whose values should not appear in API responses.
| Environment values | Secrets | |
|---|---|---|
| Visible in API responses | Yes | Never |
| Reusable by name | No | Yes |
| Rotation | Resubmit with new values | Update bundle, then resubmit |
Pass environment variables
# Explicit value
anycloud job ghcr.io/acme/train:latest -e MODE=eval
# Read a value from the current shell
anycloud job ghcr.io/acme/train:latest -e DATASET_TOKEN
# Load a file; explicit -e flags win
anycloud job ghcr.io/acme/train:latest \
--env-file .env \
-e MODE=eval
Python places the dictionary in DeploymentAdmissionInput.env:
request = DeploymentAdmissionInput.from_dict({
"image": "ghcr.io/acme/train:latest",
"cloudConfig": {},
"env": {"MODE": "eval", "RUN_NAME": "baseline"},
})
The CLI warns when a likely-sensitive key is passed through --env, but the
submission proceeds.
Create a Secret
Each Secret is a named bundle of one or more KEY=VALUE pairs:
anycloud secrets new hugging-face HF_TOKEN=hf_xxxxxxxxxxxx
anycloud secrets new tracking \
WANDB_API_KEY=xxxxx \
WANDB_ENTITY=my-team
The list command returns names and timestamps, never values:
anycloud secrets list
Inject Secrets
- CLI
- Python
anycloud job ghcr.io/acme/train:latest \
--gpu-type h100 \
--secret hugging-face \
--secret tracking
from anycloud.api.secrets_api import SecretsApi
from anycloud.models.save_secret_body import SaveSecretBody
SecretsApi(client).save_secret_sync(
"hugging-face",
sdk_version,
SaveSecretBody(values={"HF_TOKEN": "hf_xxxxxxxxxxxx"}),
)
Reference the saved names in DeploymentAdmissionInput.secrets. The same named
Secrets work with Services started through the JSON API or CLI and with
anycloud vm.
Precedence and rotation
An explicit environment value wins over a same-named key from a Secret. That supports a one-off override without editing the saved bundle.
Overwrite a bundle and resubmit to rotate it:
anycloud secrets new hugging-face HF_TOKEN=hf_rotated
anycloud resubmit <job-id>
Running containers retain the values injected when their VM started. New Jobs, resubmissions, and spot replacements read the current bundle.
Deletion is blocked while a non-terminal deployment references the Secret.
--force bypasses that safeguard, but the next VM start for a deployment that
still references the missing name will fail.
anycloud secrets delete hugging-face --force
Storage and threat model
Secret values are encrypted in the local Anycloud database with libsodium (XSalsa20-Poly1305). The API offers create, list, and delete operations but no operation that returns a value.
At workload startup, resolved Secret values and the authenticated GitHub token
are combined and sent over SSH channel stdin, so their contents never appear in
the remote command or its retry logs. They are written to
/run/anycloud-secrets/env with mode 0600 and supplied to Docker through
--env-file. VM hosts use their memory-backed /run. Fresh submissions,
resubmissions, and service upgrades preflight named Secret references before
changing deployment state or provisioning; workload startup resolves the
current values again to catch deletion or rotation between the request and
container start.
The authenticated GitHub token overrides a same-named value from a Secret
bundle. An explicit environment value remains the final override. Workload code
continues to receive the token as GITHUB_TOKEN.
Docker inlines environment values into the container's run configuration.
Anyone with root access on the VM can read them through docker inspect or a
process environment. Secrets protect values from plaintext local storage and
the Anycloud API response surface; they are not a defense against a VM-root
attacker.
See secrets reference for exact command syntax.