direnv for Per-Directory Env Vars
direnv loads .envrc on cd.
Setup
direnv is a tool that automatically loads environment variables when entering a directory. Each project's environment becomes self-contained; the engineer's shell does not pollute across projects; the discipline is per-project environment management.
What setup looks like:
- .envrc in project root with export VAR=value.: Each project has a .envrc file. The file declares environment variables; the format is shell-script syntax; the file lives in the project root.
- direnv allow approves it.: direnv requires explicit approval before executing the .envrc. The first time the engineer enters the directory, they run direnv allow; the file is approved; future entries auto-load.
- Loads on cd.: When the engineer changes into the project directory, direnv loads the variables. Leaving the directory unloads them; the environment is scoped to the project.
- Plays well with shells.: direnv supports bash, zsh, fish, and others. The team's shell preferences do not constrain the tool; the integration is consistent.
- Per-project tooling versions.: Some teams use direnv to set tool versions (Python, Node, Go). Combined with version managers, the project's exact tooling environment is loaded automatically.
Setup is bounded. The first project takes a few minutes; subsequent projects are fast.
Safety
direnv has explicit safety. Each .envrc must be approved; cloned repos do not auto-execute their .envrc; the engineer's environment is protected from arbitrary code.
- Approval required per file.: direnv allow approves the specific .envrc file. The engineer reviews the file; understands what it does; explicitly accepts.
- Prevents arbitrary code execution from cloned repos.: Cloning a repo with a malicious .envrc does not produce execution. direnv refuses to run it; the engineer must approve; the security model is explicit.
- Re-approve on file change.: When the .envrc changes, the approval is invalidated. The engineer re-approves after reviewing the change; the discipline is sustained.
- Audit the .envrc.: Engineers should audit .envrc files before approval. What does it do? What variables does it set? Is anything suspicious? The audit is the security check.
- Don't store secrets in .envrc.: While convenient, storing actual secrets in .envrc is risky. The file is in git; secrets in git are visible to anyone with access. Use secret stores instead; reference the secret store from .envrc.
The safety model is the discipline. The team trusts direnv because it requires explicit approval.
Scope
The scope is per-project. Each project has its own variables; entering one project does not contaminate another; the discipline is clean.
- Per-project credentials.: Different projects can have different AWS profiles, GitHub tokens, database connection strings. Each project's .envrc sets its own; entering the project loads them.
- AWS_PROFILE.: A common pattern is AWS_PROFILE=project-prod in production-related projects, AWS_PROFILE=project-dev in development. The engineer's awscli automatically uses the right profile.
- Less leakage across projects.: Without direnv, environment variables persist in the shell. Switching between projects can confuse which variables are active. With direnv, the variables are scoped; the leakage is bounded.
- Cleaner shell.: The engineer's shell does not accumulate project-specific variables. The shell stays clean; variables come and go with directory changes; the environment is predictable.
- Document conventions.: The team's conventions for .envrc files are documented. New engineers learn what variables to expect; the discipline is consistent.
direnv for env vars is one of those engineering tooling disciplines that pays off in cleaner workflows. Nova AI Ops integrates with development tooling, surfaces patterns, and supports the team's per-project environment discipline.