Stop Committing .env Files. AI Is Reading Your Repo Now.

A practical guide to using justfile + Infisical for developer workflows that don't leak secrets.


Every developer has done it. You clone a repo, copy .env.example to .env, fill in your secrets, and get to work. Maybe you've even accidentally committed that .env file once. GitHub helpfully reminds you that you just published your database credentials to the world.

But here's the thing most teams haven't caught up with yet: your codebase is no longer just read by humans and CI pipelines.

AI coding assistants — Claude Code, GitHub Copilot, Cursor, Cody — now read your entire repository as context. Every file. Every config. Every .env.local that "shouldn't be there but works fine for now."

The new threat model

When you use an AI coding tool, it typically ingests:

  • Your entire project structure
  • Configuration files
  • Environment files if they exist in the repo
  • Docker compose files with hardcoded credentials
  • Any file that isn't in .gitignore — and sometimes even those

This isn't a vulnerability in the AI tools. It's the whole point: they need context to help you code. But if your secrets live in your repo as plain text files, they become part of that context. They get sent to APIs. They appear in autocomplete suggestions. They end up in log files.

The .env file was designed for a world where only your local machine read your code. That world is gone.

What we do instead: justfile + Infisical

We use a combination of just (a modern command runner) and Infisical (an open-source secrets manager) to keep secrets out of the repository entirely.

Here's what a typical justfile looks like:

init:
    infisical run -- docker compose up -d

serve:
    infisical run -- cargo run

test:
    infisical run -- cargo test

migrate:
    infisical run -- npx prisma migrate dev

Notice infisical run -- before every command that needs environment variables. That prefix pulls secrets from Infisical's vault, injects them as environment variables for that process only, and never writes them to disk.

No .env file. No secrets in the repo. No secrets in your shell history. No secrets for AI tools to accidentally ingest.

Why justfile over Makefile or npm scripts?

just is a command runner, not a build system. The distinction matters:

1. It does one thing well. No implicit rules, no dependency graphs, no tab-vs-space wars. You write commands. You run them.

2. It works with any language. Your monorepo has Python, TypeScript, Go, and a docs site? just doesn't care. It runs shell commands.

3. The syntax is readable. Compare:

# Makefile: Is this a build target or a command? Who knows.
serve:
	infisical run -- npm run dev
.PHONY: serve
# justfile: It's a command. Obviously.
serve:
    infisical run -- npm run dev

4. It lists available commands. Running just --list gives you a summary of every task. New team member? They run just --list and immediately know what's available.

5. It supports arguments and defaults. Need to run migrations against different databases?

migrate env="development":
    infisical run --env={{env}} -- npx prisma migrate deploy

Now just migrate targets development, and just migrate staging targets staging. Try doing that cleanly in a Makefile.

Why Infisical (or any secrets manager) over .env files?

The .env pattern has three fundamental problems:

Problem 1: .env files multiply

It starts with one .env. Then you need .env.local, .env.development, .env.production, .env.test, .env.staging. Then someone adds .env.example that's always out of date. Then someone adds secrets.json for a different service.

With Infisical, you have one source of truth with environments (dev, staging, prod) built in. You switch environments, not files.

Problem 2: .env files are unshareable

New developer joins the team. "Hey, can someone send me the .env file?" Now your secrets are in Slack DMs, email threads, and shared Google Docs. Each copy is a potential leak.

With Infisical, new developers run infisical login, select their project, and they're ready. Secrets are scoped by role — the intern doesn't get production database credentials.

Problem 3: .env files have no audit trail

Who changed the API key? When? Why? With .env files, you'll never know. Someone overwrites it, someone copies the wrong value, and three hours later you're debugging a production issue because staging credentials ended up in prod.

Infisical provides version history, access logs, and change tracking for every secret.

The AI angle is real, not hypothetical

Consider what happens with a typical AI-assisted workflow:

  1. Developer has .env with DB_URL=mongodb://root:p4ssw0rd@prod-server:27017/
  2. Developer asks Claude Code: "Help me debug the database connection"
  3. The AI reads the project context, including .env
  4. The secret is now in the API request to the AI provider

With infisical run --, that .env file doesn't exist. The AI sees a clean justfile with infisical run -- prefixes. It understands the pattern. It can help you debug without ever seeing your actual credentials.

Your secrets stay where they belong: in the vault, not in context windows.

Setting it up: 15 lines to a secure workflow

1. Install just and Infisical

# macOS
brew install just infisical/get-cli/infisical

# Linux
curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash
curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo bash
sudo apt-get install infisical

2. Login and initialize

infisical login
infisical init    # Links your repo to an Infisical project

3. Create your justfile

# Start all services
init:
    infisical run -- docker compose up -d

# Run your app
serve:
    infisical run -- npm run dev

# Run tests
test:
    infisical run -- npm test

# Run with a specific environment
serve-staging:
    infisical run --env=staging -- npm run dev

4. Add .env to .gitignore (if you haven't already)

.env
**/*.env
secrets.json

That's it. From now on, just serve handles everything.

The team workflow

Here's what the daily workflow looks like:

  • Morning: just init to start services, just serve to run the app. No copying files, no asking teammates for secrets.
  • New feature needs a new secret: Add it in Infisical's dashboard. Team gets it automatically next time they run any just command.
  • New team member: infisical login, just serve. Done.
  • AI pair programming: Ask Claude Code anything. It sees your justfile, understands the pattern, and helps you without ever accessing your secrets.

Common objections

"But Infisical adds a network dependency." True. If Infisical is down, infisical run fails. For CI/CD, you can use Infisical's service tokens with caching. For local dev, the CLI caches secrets locally (encrypted). It's not a hard dependency for offline work.

"My team is small, .env files are fine." Today. But when you add your first AI coding tool — and you will — your threat surface changes overnight. Setting this up takes less time than recovering from a leaked secret.

"Can I use something other than Infisical?" Absolutely. The pattern works with any secrets manager:

# Infisical
serve:
    infisical run -- npm run dev

# Doppler
serve:
    doppler run -- npm run dev

# 1Password CLI
serve:
    op run -- npm run dev

# AWS Secrets Manager (via chamber)
serve:
    chamber exec production -- npm run dev

The tool doesn't matter. The pattern does: secrets injected at runtime, never stored in files.

The bottom line

The combination of justfile + a secrets manager gives you:

  • Zero secrets in your repo for AI tools (or anyone else) to find
  • One command to run anything: just serve, just test, just deploy
  • Consistent environments across the team without manual file copying
  • Audit trails for who accessed which secrets and when
  • Language-agnostic task running that works for any project in your monorepo

Your .env file was a good idea in 2015. In 2025, with AI reading every file in your project, it's a liability. Replace it with a pattern that was built for how we actually work now.