Skip to content

Guides

Environments

Store environment variables and secret files once, encrypted, and have VMYard install them in machines, with immutable versions and controlled upgrades.

On this page

An environment is a named set of environment variables and secret files that belongs to your organization. VMYard encrypts it at rest and installs it in machines: when a machine is created, and again when you upgrade the machine to a newer version. An organization can have up to 50 environments.

Create an environment

sh
curl -X POST "$VMYARD_API_URL/v1/environments" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "staging",
    "vars": {"DATABASE_URL": "postgres://app@db.internal/app", "LOG_LEVEL": "info"},
    "files": [{"path": "secrets/service-account.json", "contents": "{\"type\": \"service_account\"}"}]
  }'
FieldMeaning
name1–63 lowercase letters, digits, and -, starting with a letter; unique in the organization. Defaults to base.
varsVariable names to values.
filesSecret files: {path, contents, encoding}, with encoding text (default) or base64.
is_defaultMake it the organization's default. The first environment becomes the default unless you send false.
safe_for_third_partiesA label for environments whose contents may be shared. VMYard stores and returns it but doesn't enforce it yet; for machines shared with third parties, create them with no_env.

The answer is 201 with the new environment. A taken name is 409 environment_name_taken; a 51st environment is 409 environment_limit_reached.

Rules for variables and files

Everything is checked before anything is stored; problems come back as 422 with field_errors.

  • Variable names match ^[A-Za-z_][A-Za-z0-9_]{0,127}$. Values are at most 32 KiB, without NUL.
  • File paths are relative to /work, for example secrets/token.txt. A path can't start with / (not even /work/…), can't have a component starting with ~, can't have empty, ., or .. components or control characters, can't be longer than 1024 bytes, and can't be under the reserved .vmyard directory. Files are at most 256 KiB.
  • A version holds at most 128 variables, 32 files, and 1 MiB of values and contents in total.

Change variables and files

Each change writes a new version. These routes answer 200 with the environment.

sh
# Set or replace a variable
curl -X PUT "$VMYARD_API_URL/v1/environments/$ENV_ID/vars/LOG_LEVEL" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" -d '{"value": "debug"}'

# Remove a variable (404 variable_not_found if it isn't there)
curl -X DELETE "$VMYARD_API_URL/v1/environments/$ENV_ID/vars/LOG_LEVEL" \
  -H "Authorization: Bearer $VMYARD_API_KEY"

# Set or replace a secret file
curl -X PUT "$VMYARD_API_URL/v1/environments/$ENV_ID/files" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"path": "secrets/token.txt", "contents": "s3cr3t\n"}'

# Remove a secret file (404 file_not_found if it isn't there)
curl -X DELETE "$VMYARD_API_URL/v1/environments/$ENV_ID/files" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" -d '{"path": "secrets/token.txt"}'

PATCH /v1/environments/{id} changes only name, is_default, and safe_for_third_parties; that is metadata and doesn't create a version. Setting is_default: false on the default leaves the organization without one.

DELETE /v1/environments/{id} (204) removes the environment and frees its name. Machines keep the version they already have. Deleting the default leaves the organization without one.

Versions

Versions are numbered 1, 2, 3, … and never change once written. current_version on the environment is the newest. GET /v1/environments/{id}/versions lists them newest first, with variable names, file paths and sizes, and a change summary such as {"action": "set_variable", "name": "API_TOKEN", "size": 40}. Values are never included.

Use an environment in a machine

When you create a machine, choose its environment in the create body:

FieldEffect
environment_id or environment (the name)Use that environment.
neitherUse the organization's default environment, if there is one.
no_env: trueNo environment at all, not even the default.

Combining them, or naming an environment that doesn't exist, is 422 unknown_environment. The machine is pinned to the version that was current when it was created; later changes to the environment don't reach it until you upgrade it.

The machine's environment field shows where it stands:

json
{
  "environment_id": "2a7d4c1e-8b3f-4f6a-9c5d-0e1f2a3b4c5d",
  "version_id": "4d2b9c1e-7a3f-4e58-b1c6-2f9d8e7a6b50",
  "version": 3,
  "applied_version_id": "4d2b9c1e-7a3f-4e58-b1c6-2f9d8e7a6b50",
  "status": "applied",
  "error_code": null,
  "operation_id": "6f1c2d3e-4b5a-4c7d-8e9f-0a1b2c3d4e5f"
}

status is pending until the apply operation succeeds, then applied, or failed with an error_code.

What gets installed

VMYard installs the environment with an apply_environment operation that runs once the machine is first ready, before any setup script:

  • Variables go to /work/.vmyard/environment as export NAME='value' lines, quoted so that sourcing the file never evaluates a value. Login shells load it through /etc/profile.d/vmyard-environment.sh.
  • Commands, background commands, and the setup script on a machine with an environment run with the variables loaded.
  • Each secret file is written to /work/<path> with mode 0600 (directories 0700), created before any content is written. Files from the previous version that the new version no longer has are removed.

Values travel only inside the encrypted version and the file uploads; they never appear in operation requests, operation results, audit records, or logs.

On a machine with an environment, the setup script can be at most 65,424 bytes, because the wrapper that loads the variables counts toward the command-size limit.

If the apply fails, the machine keeps running, environment.status becomes failed, and VMYard emits operation.failed. A setup script waiting on that apply fails with setup_prerequisite_failed. Apply error codes include environment_prepare_failed, environment_decrypt_failed, environment_keys_unavailable, and environment_prerequisite_failed (the create itself failed).

Upgrade machines to the current version

sh
curl -X POST "$VMYARD_API_URL/v1/environments/$ENV_ID/upgrade" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" -d '{}'

POST /v1/environments/{id}/upgrade applies the current version to every running machine that was created with this environment, or only to the machine_ids you list (at most 100). It answers 202 with one apply_environment operation per upgraded machine and a skipped list with a reason for the rest:

  • already_current: the machine already has the current version.
  • not_running: start the machine, then upgrade again.

Repeating the same request replays the same operations, so retries are safe. If a machine's version changed while the request was being made, the answer is 409 environment_upgrade_conflict; retry it. Listing a machine that wasn't created with this environment is 422.

Reveal values

sh
curl -X POST "$VMYARD_API_URL/v1/environments/$ENV_ID/reveal" \
  -H "Authorization: Bearer $VMYARD_API_KEY" \
  -H "Content-Type: application/json" -d '{}'

Reveal returns the variable values and file contents of the current version, or of version_id. File contents always come back base64-encoded so the exact bytes survive. Every reveal is recorded with who did it, the version, and the variable names and file paths (never the values).

Who can do what

ActionWho
List and read environments and versions (names, variable names, file paths and sizes)Any member; any API key preset.
Create, change, delete, set or remove variables and files, revealOwner or Admin; an API key needs full_access and a creator who is still an Owner or Admin.
Upgrade machinesOwner, Admin, or Operator; an API key needs at least use_existing.

Encryption at rest

Each version's values and files are encrypted with AES-256-GCM under a fresh random 256-bit data key. That data key is itself encrypted (wrapped) under a key-encryption key that the VMYard deployment holds outside the database. The encryption is bound to the organization, environment, and version, so ciphertext copied elsewhere doesn't decrypt. Environment names, variable names, file paths, and sizes are stored unencrypted so they can be listed. Operators can rotate the key-encryption key without re-encrypting the data.