0Pricing
AI Agents · Lesson

Environment Variables for Agents

os.environ, os.getenv(), and why never hard-code secrets in source code.

Environment Variables for Agents is a free AI Agents lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the AI Agents learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Not Hard-Code API Keys?

Hard-coding API keys directly in source code is one of the most common and costly security mistakes. Keys committed to version control are visible to everyone who has access to the repository — including future contributors, CI systems, and anyone who finds the repo online.

The Git History Problem

Even if you delete a hard-coded key from your code later, it remains in your git history. Anyone who clones the repository and runs git log or git show can find it. Keys must never enter version control.

import os

os.environ['OPENAI_API_KEY'] = 'sk-proj-abc123def456'  # simulate deployment env

OPENAI_API_KEY = os.environ['OPENAI_API_KEY']
print('Key loaded from environment — never hard-coded')

os.environ[] vs os.getenv()

There are two ways to read environment variables. os.environ['KEY'] raises KeyError if the variable is missing — useful for required keys. os.getenv('KEY', default) returns a default value if missing — useful for optional settings.

import os

os.environ['OPENAI_API_KEY'] = 'sk-proj-demo-key'

try:
    openai_key = os.environ['OPENAI_API_KEY']
except KeyError:
    print('ERROR: OPENAI_API_KEY environment variable is not set!')
    raise

model = os.getenv('AGENT_MODEL', 'gpt-4o-mini')
timeout = float(os.getenv('AGENT_TIMEOUT', '30'))
log_level = os.getenv('LOG_LEVEL', 'INFO')
max_steps = int(os.getenv('AGENT_MAX_STEPS', '20'))

print(f'Model: {model}, Timeout: {timeout}s, Log: {log_level}')

Validating Required Environment Variables on Startup

A best practice is to check all required environment variables at startup and fail fast with a clear error message. This prevents hard-to-debug runtime failures deep inside an agent loop when a key is missing.

import os
import sys

REQUIRED_VARS = [
    'OPENAI_API_KEY',
    'SEARCH_API_KEY',
    'DATABASE_URL'
]

def check_required_env_vars():
    missing = [var for var in REQUIRED_VARS if not os.getenv(var)]
    if missing:
        print('FATAL: Missing required environment variables:')
        for var in missing:
            print(f'  - {var}')
        print('\nSet these in your .env file or shell environment.')
        sys.exit(1)
    print(f'All {len(REQUIRED_VARS)} required environment variables are set.')

# Call this at the very start of your agent:
# check_required_env_vars()

if __name__ == '__main__':
    for var in REQUIRED_VARS:
        os.environ.setdefault(var, 'demo-value')
    check_required_env_vars()

The 12-Factor App Principle

The 12-Factor App methodology defines best practices for modern software. Factor III: Store config in the environment. Everything that varies between deployments (development, staging, production) — API keys, URLs, feature flags — should come from environment variables, not code.

import os

os.environ['OPENAI_API_KEY'] = 'sk-proj-demo'
os.environ['SEARCH_API_KEY'] = 'tvly-demo'
os.environ['DATABASE_URL'] = 'postgresql://user:pass@localhost/agentdb'

config = {
    'openai_key': os.environ['OPENAI_API_KEY'],
    'search_key': os.environ['SEARCH_API_KEY'],
    'database_url': os.environ['DATABASE_URL'],
    'redis_url': os.getenv('REDIS_URL', 'redis://localhost:6379'),
    'enable_caching': os.getenv('ENABLE_CACHING', 'true') == 'true',
    'max_results': int(os.getenv('MAX_RESULTS', '10')),
    'log_level': os.getenv('LOG_LEVEL', 'INFO'),
    'env': os.getenv('ENV', 'development')
}

print('Config loaded from environment:', config['env'])

Setting Environment Variables in the Shell

Set environment variables in your terminal session with export (Mac/Linux) or set (Windows). These are available to any program run in that session.

# Mac/Linux (bash/zsh):
# export OPENAI_API_KEY='sk-proj-your-key-here'
# export AGENT_MODEL='gpt-4o-mini'
# python agent.py

# Windows (Command Prompt):
# set OPENAI_API_KEY=sk-proj-your-key-here
# python agent.py

# Windows (PowerShell):
# $env:OPENAI_API_KEY = 'sk-proj-your-key-here'
# python agent.py

# One-liner (temporary, only for this command):
# OPENAI_API_KEY='sk-proj-...' python agent.py

print('Shell exports set env vars for the current session only')

Listing Required Variables in Code Comments

Document which environment variables your agent requires directly in the source code. A new developer should be able to read the top of your agent file and know exactly what to configure.

# agent.py
#
# REQUIRED ENVIRONMENT VARIABLES:
#   OPENAI_API_KEY       OpenAI API key (get from platform.openai.com)
#   SEARCH_API_KEY       Tavily search API key (get from tavily.com)
#
# OPTIONAL ENVIRONMENT VARIABLES:
#   AGENT_MODEL          LLM model (default: gpt-4o-mini)
#   AGENT_MAX_STEPS      Max loop iterations (default: 20)
#   LOG_LEVEL            Logging verbosity: DEBUG|INFO|WARNING (default: INFO)
#   DATABASE_URL         PostgreSQL URL (default: none, disables memory storage)
#
# EXAMPLE SETUP:
#   cp .env.example .env
#   Edit .env with your keys
#   python agent.py --query 'Your question'

print('Document required variables at the top of each agent file')

Accessing Nested Configuration Safely

For agents with many configuration options, build a configuration class that reads and validates all environment variables in one place. This centralizes validation and makes the rest of your code cleaner.

import os

class AgentConfig:
    def __init__(self):
        self.openai_key = self._require('OPENAI_API_KEY')
        self.search_key = self._require('SEARCH_API_KEY')
        self.model = os.getenv('AGENT_MODEL', 'gpt-4o-mini')
        self.max_steps = int(os.getenv('AGENT_MAX_STEPS', '20'))
        self.log_level = os.getenv('LOG_LEVEL', 'INFO')
        self.env = os.getenv('ENV', 'development')

    def _require(self, key: str) -> str:
        value = os.getenv(key)
        if not value:
            raise EnvironmentError(
                f'Required environment variable {key} is not set. '
                f'See .env.example for setup instructions.'
            )
        return value

# config = AgentConfig()  # raises clear error if any key is missing
# client = openai.OpenAI(api_key=config.openai_key)

if __name__ == '__main__':
    os.environ.setdefault('OPENAI_API_KEY', 'sk-demo-1234')
    os.environ.setdefault('SEARCH_API_KEY', 'demo-search-key')
    config = AgentConfig()
    print(f'Model: {config.model}, max_steps: {config.max_steps}, env: {config.env}')

Masking Keys in Logs

Never log raw API keys. If you need to log configuration for debugging, mask all but the last 4 characters. This confirms the key is loaded without exposing it.

import os

def mask_key(key: str) -> str:
    if not key or len(key) < 8:
        return '****'
    return '*' * (len(key) - 4) + key[-4:]

def log_config_summary(config: dict):
    print('Agent configuration:')
    for name, value in config.items():
        if 'key' in name.lower() or 'secret' in name.lower() or 'token' in name.lower():
            print(f'  {name}: {mask_key(value)}')
        else:
            print(f'  {name}: {value}')

config = {
    'openai_key': os.getenv('OPENAI_API_KEY', ''),
    'model': 'gpt-4o-mini',
    'max_steps': '20'
}
log_config_summary(config)
# openai_key: ****abcd
# model: gpt-4o-mini

Environment Variables in Docker and CI

In Docker, pass environment variables with -e flags or a --env-file. In GitHub Actions, store them as Secrets and reference them in the workflow YAML. Never bake them into the Docker image.

# Docker run with env vars:
# docker run -e OPENAI_API_KEY='sk-...' -e AGENT_MODEL='gpt-4o-mini' myagent:latest

# Docker with an env file:
# docker run --env-file .env myagent:latest

# GitHub Actions workflow (secrets stored in repo settings):
# env:
#   OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
#   SEARCH_API_KEY: ${{ secrets.SEARCH_API_KEY }}

# docker-compose.yml:
# services:
#   agent:
#     image: myagent:latest
#     env_file:
#       - .env

print('Never bake secrets into Docker images — always inject at runtime')

What to Do When a Key Is Exposed

If you accidentally commit an API key to a public or shared repository, act immediately. Assume the key is compromised the moment it leaves your control — bots scan GitHub for keys within seconds of a commit.

# Immediate response if a key is exposed:
# 1. REVOKE the key immediately (provider dashboard)
#    OpenAI: platform.openai.com/api-keys -> Delete key
#    Anthropic: console.anthropic.com -> API Keys
# 2. Generate a new key
# 3. Update your .env file with the new key
# 4. Rotate in all environments (staging, prod)

# Remove from git history (does NOT guarantee removal from forks/clones):
# git filter-branch or git-filter-repo to rewrite history
# Force push to all branches

# Note: Rewriting git history cannot undo exposure
# if others have already cloned or forked the repo
print('Revoke immediately. Do not just remove from code — rotate the key.')

Knowledge Check: Environment Variables

Test your understanding of environment variables for agent secrets management.

Recap: Environment Variables for Agents

You now understand the correct approach to secrets management for agents:

  • Never hard-code API keys — they end up in git history forever
  • Use os.environ['KEY'] for required variables and os.getenv('KEY', default) for optional ones
  • Validate all required variables at startup with a clear error message
  • Document required variables in code comments and .env.example
  • Mask keys in logs — show only the last 4 characters
  • Inject secrets at runtime in Docker; use GitHub Secrets in CI
  • If a key is exposed: revoke first, then rotate everywhere

Frequently asked questions

Is the “Environment Variables for Agents” lesson free?

Yes — the full text of “Environment Variables for Agents” is free to read here on the web, and the AI Agents course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the AI Agents course, upgrade to CoddyKit PRO.

What will I learn in “Environment Variables for Agents”?

os.environ, os.getenv(), and why never hard-code secrets in source code. You practise AI Agents with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start AI Agents?

No prior experience is required. AI Agents on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Environment Variables for Agents” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this AI Agents lesson?

Yes. Every AI Agents lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Environment Variables for Agents
  2. .env Files and python-dotenv
  3. Secrets Rotation and Security
  4. Configuration Profiles for Dev and Prod
← Back to AI Agents