Secrets & Environment
Jobs, Services, VMs, and Deployments accept ordinary environment variables and named secret bundles. Use environment values for non-sensitive, workload-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
In Python, pass the environment dictionary to client.submit():
from anycloud import Client
with Client() as client:
job = client.submit(
"ghcr.io/acme/train:latest",
credential_name="my-aws",
gpu="h100",
env={"MODE": "eval", "RUN_NAME": "baseline"},
)
print(job.id)
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
Python can create or overwrite a bundle through SecretsApi:
import os
from anycloud import Client
from anycloud.api.secrets_api import SecretsApi
from anycloud.models.save_secret_body import SaveSecretBody
with Client() as client:
SecretsApi(client.api_client).save_secret_sync(
"hugging-face",
client.sdk_version,
SaveSecretBody(values={"HF_TOKEN": os.environ["HF_TOKEN"]}),
)
This example reads HF_TOKEN from your local environment and saves the bundle;
it does not inject it into a workload until you reference its name on submission.
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 import Client
with Client() as client:
job = client.submit(
"ghcr.io/acme/train:latest",
credential_name="my-aws",
gpu="h100",
secrets=["hugging-face", "tracking"],
)
print(job.id)
Create both bundles above before submitting this Job. The same named Secrets
work with Services started through the JSON API or CLI, with anycloud vm, and
with Deployments.
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. A Deployment's containers read the current bundle whenever they start; see Deployment Secrets.
Deletion is blocked while a non-terminal workload or a Deployment that isn't
deleted yet references the Secret.
--force bypasses that safeguard, but the next VM start for a workload that
still references the missing name will fail.
anycloud secrets delete hugging-face --force
Git access from workloads
Anycloud doesn't pass your sign-in token into workloads. A workload that runs
git clone, git fetch, git pull, or gh against a private repository needs
a GitHub token that you give it through a Secret.
-
Create a fine-grained personal access token. Set Resource owner to the organization that owns the repositories, select only the repositories your workloads use, and grant Contents: Read-only (read and write only if they push). Set an expiration. If your organization requires approval for fine-grained tokens, an owner approves it once. For a quick trial,
gh auth tokenworks too, but it's broader and tied to you. -
Store it as a Secret named
github:anycloud secrets new github GITHUB_TOKEN=github_pat_xxxxxxxxxxxx
# or, with the GitHub CLI:
anycloud secrets new github GITHUB_TOKEN="$(gh auth token)" -
Add
--secret githubwhen you submit:anycloud job ghcr.io/acme/train:latest --secret githubInside the container,
GITHUB_TOKENholds the token. A credential helper or aninsteadOfrewrite such asgit config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"lets Git use it.
To rotate, save the new token under the same name. New Jobs, resubmissions,
and spot replacements pick it up; run anycloud service upgrade for a running
Service.
anycloud secrets new github GITHUB_TOKEN=github_pat_rotated
If Git reports Authentication failed or Repository not found, the workload
is missing --secret github, or the token doesn't cover that repository.
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 are 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 workload state or provisioning; workload startup resolves the
current values again to catch deletion or rotation between the request and
container start.
A Deployment's resolved values live in a Kubernetes Secret in its node pool's namespace on the cluster, which the container reads at start. Anyone who can read Secrets in that namespace or open a shell in the Pod can read them.
Anycloud uses your sign-in token only to pull private GHCR images and to publish Service hostnames. Workload containers don't receive it.
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 keep values out of plaintext local storage and out
of Anycloud API responses such as list and status, but anyone who can open a
shell in the workload can read them. On a hosted API that includes every
admitted member, through anycloud exec or anycloud ssh, including a
GITHUB_TOKEN you supply through a Secret. Secrets are not a defense against a
VM-root attacker.
See secrets reference for exact command syntax.