VM0VM0
Core Concept

Environment Variables

Configure variables and secrets for VM0 agents

This guide explains how to configure environment variables for your agents using vm0.yaml and manage them via CLI.

Overview

VM0 provides two types of environment values:

TypeSyntaxPurposeStorage
Variables${{ vars.NAME }}Non-sensitive configurationPlatform (plaintext)
Secrets${{ secrets.NAME }}Sensitive data (API keys, passwords)Platform (encrypted)

Both types support two storage modes:

  • Platform Storage (recommended): Store once with CLI, automatically loaded on every run
  • Runtime Override: Pass at runtime with --vars or --secrets flags

Using Variables in vm0.yaml

Reference variables in your configuration using the template syntax:

vm0.yaml
version: "1.0"

agents:
  my-agent:
    framework: claude-code
    environment: 
      # Secrets for sensitive data
      ANTHROPIC_AUTH_TOKEN: "${{ secrets.ANTHROPIC_API_KEY }}"
      DATABASE_PASSWORD: "${{ secrets.DB_PASSWORD }}"

      # Variables for configuration
      ENVIRONMENT: "${{ vars.ENV_NAME }}"
      DEBUG_MODE: "${{ vars.DEBUG }}"

Store values once and use them across all agent runs.

Managing Secrets

# Store a secret
vm0 secret set MY_API_KEY sk-xxx

# With optional description
vm0 secret set MY_API_KEY sk-xxx -d "OpenAI API key for production"

# List all secrets (values are hidden)
vm0 secret list

# Delete a secret
vm0 secret delete MY_API_KEY

Managing Variables

# Store a variable
vm0 variable set ENV_NAME production

# With optional description
vm0 variable set ENV_NAME production -d "Current environment"

# List all variables
vm0 variable list

# Delete a variable
vm0 variable delete ENV_NAME

Naming Rules

Names must use uppercase letters, numbers, and underscores only:

  • MY_API_KEY
  • GITHUB_TOKEN
  • AWS_ACCESS_KEY_ID

Names like my-api-key or myApiKey are not allowed.

Runtime Override

Pass values at runtime to override or supplement stored values.

CLI Flags

# Pass secrets
vm0 run my-agent "your prompt" --secrets API_KEY=sk-xxx --secrets DB_PASSWORD=mypassword

# Pass variables
vm0 run my-agent "your prompt" --vars ENV_NAME=production --vars DEBUG=true

# Combine both
vm0 run my-agent "your prompt" \
  --secrets API_KEY=sk-xxx \
  --vars ENV_NAME=production

Environment File

Load values from a file using --env-file:

vm0 run my-agent "your prompt" --env-file .env

Create a .env file with your values:

.env
API_KEY=sk-xxx
DB_PASSWORD=mypassword
ENV_NAME=production

Environment files are not automatically loaded. You must explicitly specify the file path with --env-file.

Value Resolution Priority

When the same value is defined in multiple places, VM0 uses this priority order:

  1. CLI flags (--vars, --secrets) - highest priority
  2. Platform-stored values - medium priority
  3. --env-file values - lowest priority

Example:

# Platform has: vm0 secret set API_KEY stored-value
# .env file contains: API_KEY=from-env-file

# CLI value wins over everything
vm0 run my-agent "prompt" --secrets API_KEY=from-cli --env-file .env
# Result: API_KEY = "from-cli"

# Without CLI flag, Platform-stored value wins
vm0 run my-agent "prompt" --env-file .env
# Result: API_KEY = "stored-value"

# Without Platform-stored value, --env-file is used
vm0 run my-agent "prompt" --env-file .env
# Result: API_KEY = "from-env-file"

Best Practices

Use Platform Storage for Reusable Secrets

For API keys you use repeatedly across multiple runs:

# Set once
vm0 secret set ANTHROPIC_API_KEY sk-xxx

Then use in any agent:

vm0.yaml
environment:
  ANTHROPIC_AUTH_TOKEN: "${{ secrets.ANTHROPIC_API_KEY }}"

Use Runtime Override for CI/CD

For values that change per-run or come from CI/CD systems:

vm0 run my-agent "prompt" --secrets API_KEY=$CI_API_KEY

Keep Secrets Out of Version Control

Never commit secret values to your repository:

# Add .env to .gitignore
echo ".env" >> .gitignore

Use Descriptive Names

Choose clear, descriptive names for your values:

vm0.yaml
# Good
environment:
  ANTHROPIC_AUTH_TOKEN: "${{ secrets.ANTHROPIC_API_KEY }}"

# Avoid
environment:
  ANTHROPIC_AUTH_TOKEN: "${{ secrets.KEY }}"

Organize your configuration logically:

vm0.yaml
environment:
  # Model Provider Configuration
  ANTHROPIC_BASE_URL: "${{ vars.MODEL_PROVIDER_BASE_URL }}"
  ANTHROPIC_AUTH_TOKEN: "${{ secrets.MODEL_PROVIDER_API_KEY }}"

  # Database Configuration
  DATABASE_URL: "${{ secrets.DATABASE_URL }}"

  # Application Settings
  LOG_LEVEL: "${{ vars.LOG_LEVEL }}"