Environment Variables
Environment variables in GitHub Agentic Workflows can be defined at multiple scopes, each serving a specific purpose in the workflow lifecycle. Variables defined at more specific scopes override those at more general scopes, following GitHub Actions conventions while adding AWF-specific contexts.
Environment Variable Scopes
Section titled “Environment Variable Scopes”GitHub Agentic Workflows supports environment variables in 13 distinct contexts:
| Scope | Syntax | Context | Typical Use |
|---|---|---|---|
| Workflow-level | env: | All jobs | Shared configuration |
| Job-level | jobs.<job_id>.env | All steps in job | Job-specific config |
| Step-level | steps[*].env | Single step | Step-specific config |
| Engine | engine.env | AI engine | Engine secrets, timeouts |
| Container | container.env | Container runtime | Container settings |
| Services | services.<id>.env | Service containers | Database credentials |
| Sandbox Agent | sandbox.agent.env | Sandbox runtime | Sandbox configuration |
| Sandbox MCP | sandbox.mcp.env | MCP gateway | MCP debugging |
| MCP Tools | tools.<name>.env | MCP server process | MCP server secrets |
| Safe Inputs | safe-inputs.<name>.env | Safe-input execution | Tool-specific tokens |
| Safe Outputs Global | safe-outputs.env | All safe-output jobs | Shared safe-output config |
| Safe Outputs Job | safe-outputs.jobs.<name>.env | Specific safe-output job | Job-specific config |
| GitHub Actions Step | githubActionsStep.env | Pre-defined steps | Step configuration |
Example Configurations
Section titled “Example Configurations”Workflow-level shared configuration:
---env: NODE_ENV: production API_ENDPOINT: https://api.example.com---Job-specific overrides:
---jobs: validation: env: VALIDATION_MODE: strict steps: - run: npm run build env: BUILD_ENV: production # Overrides job and workflow levels---AWF-specific contexts:
---# Engine configurationengine: id: copilot env: OPENAI_API_KEY: ${{ secrets.CUSTOM_KEY }}
# MCP server with secretstools: database: command: npx args: ["-y", "mcp-server-postgres"] env: DATABASE_URL: ${{ secrets.DATABASE_URL }}
# Safe outputs with custom PATsafe-outputs: create-issue: env: GITHUB_TOKEN: ${{ secrets.CUSTOM_PAT }}---Precedence Rules
Section titled “Precedence Rules”Environment variables follow a most-specific-wins model, consistent with GitHub Actions. Variables at more specific scopes completely override variables with the same name at less specific scopes.
General Precedence (Highest to Lowest)
Section titled “General Precedence (Highest to Lowest)”- Step-level (
steps[*].env,githubActionsStep.env) - Job-level (
jobs.<job_id>.env) - Workflow-level (
env:)
Safe Outputs Precedence
Section titled “Safe Outputs Precedence”- Job-specific (
safe-outputs.jobs.<job_name>.env) - Global (
safe-outputs.env) - Workflow-level (
env:)
Context-Specific Scopes
Section titled “Context-Specific Scopes”These scopes are independent and operate in different contexts: engine.env, container.env, services.<id>.env, sandbox.agent.env, sandbox.mcp.env, tools.<tool>.env, safe-inputs.<tool>.env.
Override Example
Section titled “Override Example”---env: API_KEY: default-key DEBUG: "false"
jobs: test: env: API_KEY: test-key # Overrides workflow-level EXTRA: "value" steps: - run: | # API_KEY = "test-key" (job-level override) # DEBUG = "false" (workflow-level inherited) # EXTRA = "value" (job-level)---Common Patterns
Section titled “Common Patterns”Shared configuration with job overrides:
---env: NODE_ENV: productionjobs: test: env: NODE_ENV: test # Override for testing---Safe outputs with custom PAT:
---safe-outputs: create-issue: env: GITHUB_TOKEN: ${{ secrets.CUSTOM_PAT }}---Engine and MCP configuration:
---engine: env: OPENAI_API_KEY: ${{ secrets.OPENAI_KEY }}
tools: database: command: npx args: ["-y", "mcp-server-postgres"] env: DATABASE_URL: ${{ secrets.DATABASE_URL }}---Best Practices
Section titled “Best Practices”Always use secrets for sensitive data:
# ✅ Correctenv: API_KEY: ${{ secrets.API_KEY }}
# ❌ Never hardcode secretsenv: API_KEY: "sk-1234567890abcdef"Define variables at the narrowest scope needed:
# ✅ Job-specific variablejobs: build: env: BUILD_MODE: productionUse consistent naming conventions:
SCREAMING_SNAKE_CASEformat- Descriptive names:
API_KEYnotKEY - Service prefixes:
POSTGRES_PASSWORD,REDIS_PORT
GitHub Actions Integration
Section titled “GitHub Actions Integration”During compilation, AWF extracts environment variables from frontmatter, preserves GitHub Actions expressions (${{ ... }}), and renders them to the appropriate scope in .lock.yml files. Secret syntax is validated to ensure ${{ secrets.NAME }} format.
Generated lock file structure:
env: SHARED_VAR: value
jobs: agent: env: GH_AW_SAFE_OUTPUTS: /tmp/gh-aw/safeoutputs/outputs.jsonl CUSTOM_VAR: ${{ secrets.CUSTOM_SECRET }} steps: - name: Execute env: STEP_VAR: valueDebugging Environment Variables
Section titled “Debugging Environment Variables”View all available variables:
jobs: debug: steps: - run: env | sortTest precedence:
---env: TEST_VAR: workflowjobs: test: env: TEST_VAR: job steps: - run: echo "TEST_VAR is $TEST_VAR" # Outputs: "job"---Related Documentation
Section titled “Related Documentation”- Frontmatter Reference - Complete frontmatter configuration
- Safe Outputs - Safe output environment configuration
- Sandbox - Sandbox environment variables
- Tools - MCP tool configuration
- Safe Inputs - Safe input tool configuration
- GitHub Actions Environment Variables - GitHub Actions documentation