On this page
Shared .env files do not scale
Every new tool means another key, and the easy path is to paste it into a file and pass the file around. After a few clients you cannot say who has which key, rotating one means chasing every copy, and an agent working in that folder can read all of them.
I use Infisical to manage which people and projects can reach which keys. It is a secrets manager: keys live in one place, grouped by project and environment, and each person or machine gets access only to what it needs. Any secrets manager with per-project access and a command runner works for this method.
Each person or agent has its own identity. That identity is allowed into specific client projects and environments, and nothing else. When work runs, the keys are loaded into that one command and disappear when it ends. Paid calls still pass through the campaign budget check, which is a separate control.
- Identityone per person or agent
- Project and environmentonly what the work needs
- One commandkeys loaded, then gone
- Budget checkseparate, on paid calls
Six steps on one page
- Inventory. List every service you hold a key for, which client it serves, and who owns it.
- One identity each. Every person gets their own login. Every agent or server gets its own machine identity. If two things share a login you cannot tell them apart later.
- Grant the minimum. Put keys in a project per client (or per internal system) and split by environment. Give each identity only the projects and environments its work needs.
- Load for one command. Run the work with keys injected for that command, for example
infisical run -- <your command>, instead of writing them into a file. - Revoke and rotate on change. When someone leaves a client or the team, remove their access the same day and rotate any key they could read.
- Make paid use attributable. You should be able to say who ran a paid job, for which client and which campaign.
A worked example
A made-up agency with one client, ACME, and two internal systems. The people, codes and dates are invented.
| Role | Client code | Service | Environment | Allowed | Owner | Review |
|---|---|---|---|---|---|---|
| Owner | All | All | prod, dev | Read and change keys | Owner | Quarterly |
| Campaign operator | ACME | Sending, enrichment | prod | Run campaigns | Owner | 2027-01-15 |
| Copy agent (machine) | ACME | Model API | prod | Load key for one run | Campaign operator | 2027-01-15 |
| Contractor | ACME | Enrichment | dev | Test lookups only | Campaign operator | End of contract |
The contractor never sees production keys, and the copy agent never sees the sending or enrichment keys. When the contract ends, one change removes the access and the enrichment key gets rotated.
Close the side doors
Controls only work if there is no easier path around them. Old .env files with direct provider keys let anyone skip the workflow, so find them and delete them once the keys live in one place. Check what a provider's own limits actually do: some stop spending, most only send an email.
Some tools only read keys from a .env file in their folder, and most secrets tools can write one for them. Treat any file like that as readable by every person and every agent with access to the folder, and write it only for the tools that need it.
Get the blank access map
Source notes
This guide describes how I manage key access across my own agency work. Infisical is a third-party product; check its current plans and features on its own site. The access map is invented. The Legion course covers the setup we run in more depth for members; nothing here depends on it.
Run your agency on agents you can check
Get one useful GTM email a week. Then join the community on Skool.
Get the newsletter