Guide
API Key Security in a Python Multi-Agent Framework
One script, several providers, one .env file: that is how a multi-agent setup usually starts, and it is why one leaked file can hand over every key you own at once.
API key security in a Python multi-agent framework such as CrewAI or AG2 comes down to three habits the frameworks do not enforce for you. First, give each provider its own environment variable rather than one shared value: ANTHROPIC_API_KEY for Claude, GEMINI_API_KEY or GOOGLE_API_KEY for Gemini, and a separate, narrowly scoped GitHub token if an agent needs repository access. Second, load those variables with something like python-dotenv for local development, or the keyring library to pull them from the macOS Keychain or another OS credential store instead of a plaintext .env file. Third, treat a GitHub token for an agent the same way you would a model key: a fine-grained personal access token scoped to one repository, not a classic token that reaches everything you own. None of the popular frameworks ship a vault. CrewAI's own setup guide has you put keys in a .env file; AG2 reads the same standard environment variables any Python process would. The security is a layer you add, not a feature you turn on.
Why this is harder in a multi-agent script than a single one
A script that calls one model provider has one key to protect. A multi-agent framework routinely calls several: one agent might use Claude for reasoning, another Gemini for a cheaper classification step, and a third might need a GitHub token to open a pull request. All three commonly end up in the same .env file, loaded into the same process, readable by every agent and every tool call in that run.
That concentration is the real risk, more than any flaw in a specific framework. CrewAI, AG2 and LangGraph all run as ordinary Python, so whatever process-level access the script has, every agent object inside it has too. A prompt-injection attack or a buggy tool call that exfiltrates environment variables does not need to find three separate keys; it finds one process holding all of them.
- A single multi-agent process often holds keys for several providers at once.
- None of the agents inside it are isolated from each other's credentials by default.
- One leaked environment is a leak of everything that process could reach.
Claude and Gemini keys are not interchangeable to secure
An Anthropic API key is created in the Claude Console, under Account Settings, where you choose the key's type and set an expiration at creation time. Keys can be scoped to a workspace, and Anthropic's workspaces exist specifically so you can separate environments, such as a development crew from a production one, and control spend per use case.
A Gemini key is created in Google AI Studio instead, and every key is tied to a specific Google Cloud project rather than a console-level workspace concept. The standard environment variable is GEMINI_API_KEY, though GOOGLE_API_KEY also works and takes precedence if both are set. Google's own documentation is explicit that production use should move the key into Google Cloud Secret Manager rather than relying on an environment variable alone.
The practical point is that "use an environment variable" is not a single recipe across providers. Anthropic's isolation unit is the workspace; Google's is the Cloud project. Set up your multi-agent script so each provider's key lives in the separation model that provider actually offers, instead of flattening both into one undifferentiated .env file.
- Anthropic: key created in the Claude Console, scoped by workspace, with an expiration you set.
- Google: key created in AI Studio, tied to a Cloud project, GEMINI_API_KEY as the standard variable.
- Use each provider's own isolation unit (workspace, or project) rather than one flat .env file.
Loading keys the Python way, not the copy-paste way
python-dotenv is the common first step: it reads KEY=value pairs from a .env file and loads them into os.environ with a single load_dotenv() call, so your code never contains a literal key. That is better than hardcoding, but the key is still sitting in a plaintext file on disk, which an agent with file-read access, or a backup, or a misconfigured .gitignore can expose.
The keyring library goes a step further by storing the value in your operating system's own credential store, the macOS Keychain, the Freedesktop Secret Service or KWallet on Linux, or Windows Credential Locker, instead of a file. A script calls keyring.get_password() to retrieve a value at runtime, and there is nothing on disk to find. It is open source and supports third-party backends for services like Bitwarden and 1Password if you want the value to come from one of those instead of the plain OS store.
Pick based on how disciplined your .gitignore already is. If you are not confident every secret file is excluded from version control, keyring removes the file entirely rather than trusting you to keep excluding it correctly.
- python-dotenv: simple, but the secret still lives in a plaintext file.
- keyring: stores the value in the OS credential store; nothing sits on disk to leak.
- keyring supports third-party backends, including Bitwarden and 1Password, if you want the value sourced from there.
What CrewAI and AG2 actually do with your keys
CrewAI has no built-in vault. Its own documentation tells you to add the required keys to a .env file before running a crew, the same pattern as any small script, and it supports Claude, Gemini and other providers alongside its OpenAI default through that same mechanism.
AG2 reads standard, provider-named environment variables, such as OPENAI_API_KEY, ANTHROPIC_API_KEY or GEMINI_API_KEY, rather than the older OAI_CONFIG_LIST file some AutoGen tutorials still reference. You install the provider you need as an extra, for example ag2[anthropic], and the framework picks up the matching environment variable automatically. Neither framework encrypts a key at rest or limits which of its own agents can read one; both assume you have handled that separately.
- CrewAI: keys go in a .env file by its own setup instructions, no built-in vault.
- AG2: standard per-provider environment variables, no legacy config file required.
- Neither framework restricts which of its agents can read a given key.
When a key ends up on GitHub
A multi-agent script that runs in CI, or that gives one agent the ability to open a pull request, eventually needs its keys available to GitHub Actions. The model provider keys go into the repository's encrypted Actions secrets, never into the workflow file itself. For the GitHub side of that same agent's access, use a fine-grained personal access token instead of a classic one: a fine-grained token is limited to the specific repositories and specific permissions you grant it, while a classic token reaches every repository you can access under your account.
If the agent's job is narrow, such as opening pull requests in one repository, a fine-grained token scoped to just that repository and just the pull-request permission limits what a leaked token can do. The deeper walkthrough of wiring CrewAI through GitHub Actions secrets specifically lives on this site's companion guide; this page is about the keys themselves, not that one pairing.
- Model provider keys: GitHub Actions secrets, never hardcoded in the workflow file.
- GitHub access for the agent itself: a fine-grained PAT scoped to one repository and the permissions it actually needs.
- A classic PAT reaches everything your account can access, which is too broad for most agent tasks.
A rotation and scoping checklist
Treat every key a multi-agent script holds as something that will eventually need to be rotated, and make that cheap in advance rather than expensive after a leak.
The checklist below works across providers because it is about structure, not any one vendor's console.
- One key per provider per environment: a development Claude key should not be the same key production uses.
- Scope each key to the narrowest unit the provider offers, a workspace or a project, not your whole account.
- Load keys with python-dotenv locally, keyring where you can, and GitHub Actions secrets in CI; never commit any of them.
- Use a fine-grained PAT for any agent that touches GitHub, scoped to one repository.
- Rotate a key immediately if it was ever in a file an agent with broad read access could open.
Where Forkbench's Vault fits
Forkbench does not run CrewAI or AG2 scripts as an orchestration layer; it runs coding agent CLIs, such as Claude Code or Codex, in terminals on a Mac. If you are running a multi-agent Python script from one of those terminals, Forkbench's Vault can hold the keys that script's environment needs: it stores them in the macOS Keychain and releases a value to a command by name, so the key does not sit in a .env file or appear in the terminal's saved transcript.
The same limit applies here as everywhere else. Once a key reaches the Python process, Forkbench has no visibility into what that process does with it; the Vault's job is keeping the key out of a readable file before the process starts, not policing what happens after.
- Forkbench's Vault can supply the environment variables a multi-agent script needs, sourced from the Keychain.
- The value is not written to a .env file or shown in the transcript.
- Once the Python process has the key, what it does with it is outside the Vault's reach.
Related: Vault management for multi-agent systems on GitHub, Setting up a private multi-agent framework from scratch, Forkbench vs. Keyway, Why an AI agent's credentials need a lifecycle, Download Forkbench
Frequently asked
Should every agent in a multi-agent framework have its own API key?
Where the provider allows it, yes, or at least its own scoped workspace or project. Anthropic lets you separate keys by workspace and Google by Cloud project; use that instead of one key shared across every agent in the script.
Is a Claude API key handled differently than a Gemini API key?
Yes. A Claude key is created in the Claude Console and scoped to a workspace with an expiration you set. A Gemini key is created in Google AI Studio and tied to a Google Cloud project. They use different environment variables and different isolation units, so one .env pattern does not fit both.
Does CrewAI have a built-in vault for API keys?
No. CrewAI's own setup documentation has you add keys to a .env file, the same as any small Python script. Any vaulting or secret-store behavior has to be added separately.
Can I use GitHub Actions secrets for a multi-agent script's provider keys?
Yes, that is the standard place for them in CI. For the GitHub access the agent itself needs, such as opening a pull request, use a separate, fine-grained personal access token scoped to one repository rather than reusing a broad classic token.