Skip to main content

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 valuesSecrets
Visible in API responsesYesNever
Reusable by nameNoYes
RotationResubmit with new valuesUpdate 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​

anycloud job ghcr.io/acme/train:latest \
--gpu-type h100 \
--secret hugging-face \
--secret tracking

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.

  1. 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 token works too, but it's broader and tied to you.

  2. 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)"
  3. Add --secret github when you submit:

    anycloud job ghcr.io/acme/train:latest --secret github

    Inside the container, GITHUB_TOKEN holds the token. A credential helper or an insteadOf rewrite such as git 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.