TIL: direnv for Project-Specific Secrets

Auto-loading environment variables without global pollution
TIL
shell
devops
Author

Dan O’Leary

Published

November 9, 2025

The Problem

I needed an ADMIN_TOKEN available in my terminal for production monitoring commands. I didn’t want to:

  • Export it inline before each command (clumsy, exposes secrets in LLM chat histories)
  • Write wrapper scripts/aliases that set it (adds complexity)
  • Set it globally in ~/.zshrc (always loaded, pollutes environment)
  • Store it in .env (unused until explicitly loaded by an application or script)

I wanted project-specific secrets that auto-load when I enter the directory and disappear when I leave. That’s direnv.

What is direnv?

direnv auto-loads and unloads environment variables based on your current directory. It’s the standard solution for project-specific configuration like API keys and tokens.

Setup

# macOS
brew install direnv
# Add to ~/.zshrc (one-time)
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc
source ~/.zshrc

My Workflow

  1. Create .envrc in project root:
cd my-project
# Note: this puts the secret in shell history - use an editor for real credentials
echo 'export ADMIN_TOKEN="my_super_secure_token"' > .envrc
  1. Allow direnv to load it:
direnv allow
  1. Use the variable:
curl -H "X-Admin-Token: $ADMIN_TOKEN" https://api.example.com
./scripts/preflight_check.sh  # ADMIN_TOKEN automatically available
  1. Leave directory - variable disappears:
cd ~
echo $ADMIN_TOKEN  # (empty)

direnv won’t auto-run untrusted .envrc files - you must explicitly direnv allow each one after reviewing its contents.

Warning

Always add .envrc and .env to .gitignore - never commit secrets.

Common Use Cases

# .envrc
# API keys and tokens
export OPENAI_API_KEY="sk-definitely_not_my_real_key"
# Database credentials
export DATABASE_URL="postgresql://admin:my_super_secure_password@localhost/mydb"
# App configuration
export FLASK_ENV="development"
Tip

For a stronger approach that eliminates plaintext secrets entirely, see 1Password CLI for Developer Secrets - op read slots right into .envrc files.

Resources