VibeOps Club / Guides
AI coding agent permissions: how to give an agent access to your infrastructure without losing production
A coding agent in Cursor, Claude Code or Replit runs with whatever access it can find. This guide covers what that access usually includes, which credentials should never be within its reach, and how to set up a project so the agent can deploy and debug without being able to delete your production data.
The setup below takes an afternoon for a typical project on Vercel, Railway, Supabase or Fly. It does not require you to stop using agents for infrastructure work. The goal is narrower: when the agent makes a mistake, the damage stays in a development environment you can rebuild.
Two incidents with the same root cause
PocketOS, April 2026. A Cursor agent running Claude Opus found a Railway CLI token in a file unrelated to its task. The token had been created for domain management, but it allowed any operation. The agent used it to delete the production database and the volume-level backups with a single API call, in 9 seconds. The data was recovered about an hour later with help from Railway (The Register).
Replit and SaaStr, July 2025. On day 9 of Jason Lemkin's experiment, during an explicit code freeze, the Replit agent deleted a production database with records of 1,206 executives and 1,196 companies. It also generated a database of 4,000 fictional people. It first reported that a rollback was impossible; the rollback worked. Replit has since added automatic separation of development and production databases (The Register, Fortune).
In the Replit case, an explicit instruction did not stop the deletion. In both cases, the agent held a credential that allowed it. Which credentials an agent holds is something you control, and the rest of this guide is about that.
What an agent can reach on your machine
A local agent acts as your operating system user. Unless you restrict it, it can read and use:
- Every file in the repository, including
.env,.env.production, old config files, scripts with hardcoded tokens, and notes you forgot were committed. A file listed in.gitignoreis still on disk and still readable. - CLI logins in your home directory. Once you have run
railway login,vercel login,supabase login,fly auth loginoraws configure, the token sits in a file in your home directory, such as~/.aws/credentials. Any process running as you can use it, often with full account rights. - Environment variables exported in your shell profile, including
DATABASE_URLpointing at production. - MCP servers you have connected. A database or hosting MCP server runs with the credentials you configured for it, and the agent can call every tool it exposes.
- The shell. If the agent can run commands, it can run
psql,curlagainst a provider API,git push --force, orrm -rf.
Cloud builders such as Replit and Lovable run the agent on their side, but the principle is the same: the agent can do whatever the project's connected database and integrations allow.
Principles
- Least privilege. Each token grants the minimum set of operations on the minimum set of resources. A token for DNS changes cannot delete databases.
- Separate dev and prod. Different databases, different keys, ideally different projects or accounts at the provider.
- No production credentials in the agent's environment. Production changes go through CI or through you.
- Scoped, short-lived tokens. When the agent needs a token, it gets one for a single project and environment, with an expiry measured in days.
- A human approves destructive operations: dropping or truncating tables, deleting volumes, services or buckets, force-pushing, running migrations against shared databases.
- Backups live where the same credential cannot delete them. In the PocketOS case, one token removed both the data and its backups.
- Check the result yourself. An agent's summary of what it did is a claim until you have looked at the diff, the database and the deployment.
Setup, step by step
1. Inventory what the agent can see today
Open a terminal in the project and search for anything that looks like a credential:
grep -rnE "(TOKEN|SECRET|API_KEY|DATABASE_URL|PASSWORD)" \
--exclude-dir=node_modules --exclude-dir=.git .
Then list the CLIs you are logged into and the MCP servers configured in your editor. For each credential, write down what it can do. If you cannot tell, assume it has full access to the account.
2. Remove production credentials from the machine the agent uses
Delete production values from .env files in the repository and from your shell profile. Store them in the hosting platform's secret settings or in a password manager. Log out of provider CLIs you only need for production (railway logout, vercel logout and so on) and log back in only for a specific manual task. Rotate any token you found in step 1 that was ever committed to git.
3. Give the agent its own development environment
Create a separate database and, where the provider supports it, a separate project or environment for development. Seed it with test data or an anonymized copy. The agent's .env points only there. If the agent breaks the dev database, you recreate it from a seed script, which is a good test that the script works.
4. Issue narrow tokens when the agent needs one
Most hosting and database providers let you create tokens limited to a team, project or environment, and some let you set an expiry. Use the narrowest option available, name the token after its purpose (for example agent-dev-2026-09) and delete it when the work is done. If a provider only offers account-wide tokens, do not give that token to the agent at all.
5. Use a read-only database role for debugging
Agents are useful for reading logs and data while debugging. For that, create a Postgres role that cannot write:
CREATE ROLE agent_ro LOGIN PASSWORD '...';
GRANT CONNECT ON DATABASE app TO agent_ro;
GRANT USAGE ON SCHEMA public TO agent_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public
TO agent_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO agent_ro;
ALTER ROLE agent_ro
SET default_transaction_read_only = on;
Give the agent a connection string with this role, and against production only if you are comfortable with it reading real user data. For most debugging, read access to dev plus production logs is enough.
6. Turn on command approval and consider a sandbox
Most coding agents can ask for approval before running a shell command and let you keep a list of commands that run without asking. Allow routine commands such as tests, linters and git status. Keep deploys, database clients, provider CLIs and anything with delete, drop or --force behind approval. When you approve, read the full command, including the target host and project.
For stronger isolation, run the agent's commands inside a container that mounts only the project directory, so your home directory and its CLI logins are not visible:
docker run -it --rm -v "$PWD":/work -w /work node:22 bash
A separate operating system user or a cloud dev environment achieves the same thing.
7. Review MCP servers like any other credential
For each connected MCP server, check which account it uses and which tools it exposes. Point database servers at dev or at the read-only role. Disable servers you are not using in the current project.
8. Move backups out of reach
Keep the provider's automatic backups, and add one copy that the application and agent credentials cannot delete: for example a scheduled pg_dump to object storage in a different account, uploaded with a key that can write but not delete. Many object stores support this through bucket policies, versioning or object lock. Restore from it once to confirm it works.
9. Route production changes through a pipeline
The agent opens a pull request. CI runs tests and deploys from the main branch using secrets stored in CI. Migrations run in CI or by you, after you have read them. The agent never needs a production token for this flow.
Checklist
- No production credentials in the repository, in
.envfiles or in the shell profile on the agent's machine. - Provider CLIs with production access are logged out or unavailable to the agent.
- The agent works against a separate dev database and dev project.
- Every token the agent can use is scoped to one project and environment and has an owner and an expiry.
- Database access for debugging uses a read-only role.
- Destructive commands, deploys and migrations require your approval.
- Connected MCP servers point at dev or use read-only credentials.
- At least one backup copy cannot be deleted with any credential the app or agent holds, and a restore has been tested.
- Production deploys go through CI from reviewed pull requests.
The same items appear in the agent permissions section of our production checklist, alongside environments and backups.
How to phrase an infrastructure task for the agent
A task with explicit boundaries and acceptance criteria gives you something to check. It also makes the agent state its plan before acting, which is where you catch a wrong target. An example:
Add a
last_login_atcolumn to theuserstable and populate it on login.Constraints: work only against the dev database from
.env.development. Do not run any command against production. Do not read or use tokens outside this repository. Before running any migration or command that deletes or changes data, show it to me and wait for approval.Acceptance criteria: a migration file that adds the column and can be rolled back; the login handler sets the column; a test that logs in and checks the value; the output of the test run. List every command you ran and every file you changed.
When the agent reports that it is done, check each criterion yourself. Open the migration and read it. Run the tests. Query the dev database to confirm the column exists and is filled. If the agent says an operation failed or cannot be undone, confirm that independently before acting on it: in the Replit case, the rollback it described as impossible worked.
For more context on how these failures happen in practice, read the vibe coding incident case studies, and go through the full production checklist before launch.