← Back to blog

API Key Management for AI Agents: Stop Hardcoding Secrets

Let me describe a setup I've seen at least a dozen times. An OpenClaw agent running on a server somewhere. A `.env` file with 15 API keys in it. Every skill reads from `process.env`. The file was last rotated never. Half the keys belong to a developer who left the company six months ago.

If this sounds familiar, you're not alone and you're not even doing it wrong by industry norms. But you are doing it wrong by any reasonable security standard, and the risks are different for AI agents than for regular applications.

## Why hardcoding breaks differently for agents

In a traditional web app, hardcoded API keys are bad because of credential exposure: someone finds the key in a git repo or a log file. The risk is well understood. For AI agents, the problem is worse in two specific ways.

**Skills are third-party code running with your credentials.** When you install an OpenClaw skill from the marketplace, you're running someone else's code on your agent. If your API keys live in environment variables, every skill has access to every key. A compromised email summarizer skill can read your Stripe API key. It shouldn't be able to, but `process.env` doesn't have access control.

This isn't theoretical. The Moltbook incident in late 2025 involved skills that exfiltrated environment variables. The skills looked legitimate, passed basic code review, and quietly sent API keys to an external server on first run.

**Agents are persistent and autonomous.** A web app serves a request and forgets. An agent maintains state across long conversations and tasks. If an API key ends up in the agent's conversation history (because a skill logged the full request headers, or an error message included the auth token), that key is now in memory. It persists across subsequent interactions. Other skills can potentially access it. If conversation history gets exported or backed up, the key goes with it.

## Why environment variables aren't enough

Environment variables are a step up from inline hardcoding, but they have real limitations for agents:

**No per-skill access control.** `process.env.GITHUB_TOKEN` is available to every skill running on your agent. You can't say "only the GitForge skill should access this."

**No rotation without restarts.** Change an env var and you need to restart the agent process to pick up the new value. For agents running long tasks, that means interrupting work in progress.

**No audit trail.** When something goes wrong, you can't tell which skill accessed which key at what time. Environment variables are read silently.

**No expiry tracking.** Some API keys expire. Some should be rotated regularly. Env vars are static strings with no metadata. You won't know a key expired until something breaks.

## What proper key management looks like

For AI agents, key management needs to solve four problems that environment variables don't.

### Scoped access

Each skill should only access the credentials it needs. Your calendar skill gets the Google Calendar API key. Your payment skill gets the Stripe key. Neither can see the other's credentials.

ClawCoil implements this through the skill manifest. When you write a skill, you declare which credentials it needs:

```yaml secrets: - name: GITHUB_TOKEN description: GitHub API access for repo operations required: true - name: SLACK_WEBHOOK description: Slack webhook for notifications required: false ```

At runtime, the skill can only access these declared secrets through `ctx.secrets.get('GITHUB_TOKEN')`. It cannot read other secrets, environment variables, or the filesystem. The sandbox enforces this at the runtime level, not just by convention.

### Automatic rotation

API keys should be rotated regularly. For high-privilege keys (payment processors, cloud providers), monthly rotation is reasonable. For lower-risk keys, quarterly.

Manual rotation means logging into each service, generating a new key, updating your config, and restarting your agent. Nobody does this consistently. I've audited agent setups where the oldest API key was 18 months old and belonged to a former team member's personal account.

ClawCoil supports automated rotation for services that offer programmatic key management. You set a rotation schedule per credential, and ClawCoil handles the rest: generate new key, verify it works, swap the old one out, retire the old key. Zero downtime, no manual steps.

For services that don't support programmatic rotation (and there are many), ClawCoil tracks key age and sends you reminders when rotation is due. Not as good as automatic, but better than hoping someone remembers.

### Encrypted storage

API keys at rest should be encrypted. Not "stored in a file with restrictive permissions" encrypted. Actually encrypted with a proper key management scheme.

ClawCoil stores credentials encrypted with AES-256. The encryption key is derived from your agent's identity certificate. Keys are decrypted only in memory, only when a skill requests them, and only if that skill is authorized. The decrypted value never hits disk, never appears in logs, and never enters the agent's conversation history.

### Access logging

Every credential access is logged: which skill, which credential, when, and the result (success, denied, or not found). This log is readable by the agent owner but not by skills.

When you see a skill accessing a credential it shouldn't need, or a spike in credential requests at unusual hours, those are signals worth investigating. Without logging, you're flying blind.

## Migration path

If you're currently using environment variables (no judgment, we all start there), here's how to migrate without breaking everything:

**Step 1: Inventory.** List every API key your agent uses. Check `.env` files, Docker compose files, deployment configs, and skill configurations. You'll probably find more keys than you expected.

**Step 2: Categorize by risk.** Payment and cloud provider keys are high risk. Notification webhook URLs are lower risk. Prioritize migrating high-risk keys first.

**Step 3: Import into ClawCoil.** For each key, run:

```bash openclaw coil import --name STRIPE_API_KEY --value sk_live_xxx --rotate monthly ```

This encrypts and stores the key, sets a rotation schedule, and makes it available to authorized skills.

**Step 4: Update skill manifests.** Add `secrets` declarations to each skill that needs credentials. Remove `process.env` calls and replace with `ctx.secrets.get()`.

**Step 5: Remove the old keys.** Delete the `.env` file or remove the API key entries. Don't leave the old keys around as "backup." That defeats the purpose.

The migration takes a few hours for a typical setup. The payoff is not having to worry about whether a marketplace skill is siphoning your Stripe key.

## The minimum viable approach

If ClawCoil feels like overkill for your setup, here's the bare minimum that's still meaningfully better than environment variables:

1. Don't store API keys in `.env` files that skills can read. Use a separate encrypted store (even a password manager with CLI access). 2. Rotate keys when team members leave. This one is free and it's the most commonly skipped. 3. Use separate API keys for each service integration, not one master key per provider. When a key is compromised, you revoke one integration, not all of them. 4. Monitor API usage dashboards for anomalies. Most providers show usage graphs. Spikes you didn't cause are a red flag.

Security isn't binary. Every step up from "API keys in plain text" reduces your risk surface. Start where you are and improve incrementally.

Related posts

Why OAuth Is Broken for AI Agents (and How to Fix It)OAuth for AI Agents: A Complete Implementation GuideSecure Agent Credentials: A Security Engineer's GuideManaging OAuth Tokens Across Multiple OpenClaw SkillsWhy OAuth Breaks When AI Agents Use It (and How to Fix It)