From the team behind aidrop.it — one workspace to build, host, and keep changing your code.

The app works locally because there is a .env file next to it. Then it needs to run somewhere else, and the question nobody enjoys arrives: how does the API key get there?

The wrong answers are all convenient. Commit the file "just for now". Paste the key into the Dockerfile. Send it in a chat so a colleague can deploy. Each takes a minute and each creates a copy you can no longer count.

A credential's real problem is not storage. It is copies — how many exist, who holds them, and whether you could revoke one without breaking everything.

A secret in the image is a secret in every copy of the image

Build a key into an image and it is in every layer, every registry that pulls it, every cache on every node that ran it, and every local copy anyone made while debugging. Deleting the running container removes none of that.

The same is true of anything committed. Git keeps history; removing a key in a later commit leaves it in the earlier one, and any clone taken in between is permanent. The only honest response to a committed credential is to rotate it, not to delete it.

So the property worth designing for is simple: the credential should arrive at the process, at the moment it runs, and live nowhere else. Injected at deploy, not baked at build.

Rotation is the test, not encryption

Teams reach for a vault and feel finished. The better check is a question: if this key leaked today, how long until it is useless?

If the answer is "we would have to find every place it was pasted", the storage was never the weak part. If it is "change it in one place and redeploy", the design is right — whatever the storage happens to be.

That is also why a value visible in a build log, a CI variable printed on error, or a crash report shipped to a third party matters more than where the canonical copy sits. A secret is only as private as its most careless copy.

What to do before the first public deploy

  • Nothing sensitive in the repository, ever — including sample files. A .env.example should carry names, never values.
  • Inject at deploy, not at build. The image should be safe to publish. If it is not, the credential is in the wrong place.
  • One name, one purpose. A key shared between the mailer and the exporter cannot be rotated without breaking both, so it never gets rotated. A project value should reach only the services that declare its name.
  • Write down who owns each one. A credential nobody owns is one nobody will rotate, and one nobody will turn off when the person who created it leaves.
  • Assume the log is public. Never print a value on the error path — that is where they escape most often.

This is the same reasoning that decides who can open an internal tool: the default should be closed, and opening it should be something a person did on purpose rather than something that happened by omission.

Agents make this sharper, not different

An agent handed broad credentials inherits every over-permission at once, and does so quickly. That is not a reason to withhold access — it is a reason to scope it, and to keep the values out of anything that gets recorded, which is the same argument as governing what an agent may write.

Anything passed through a tool call ends up in a transcript. A key in model context is a key in a log, and a key in a log is not a secret. Agents should be given names — which variable to read — and never values.

FAQ

Is a .env file on a server acceptable? It is workable if it is not in the repository, not in the image, and readable only by the process. What makes it risky is that it is easy to copy and nobody notices when someone does.

Do I need a dedicated secrets manager? Not to start. You need one place to change a value and a deploy that picks it up. Reach for a manager when you have more services than you can rotate by hand.

What if a key is already committed? Rotate it. Rewriting history does not reach the clones, and assuming nobody fetched is a guess about strangers.

How should an AI agent get credentials it needs? It should not hold them. On aidrop.it a value is injected into the running application at deploy, and no read ever answers one back: an agent can set a value, but it works from the variable name, because anything passed back through a tool call is recorded.

Are environment variables secure? They are ordinary process state — readable by anything in the container and often by crash reporters. Good enough for most applications; not a vault, and never the place for something you cannot rotate.


Cover: https://unsplash.com/photos/Uf-c4u1usFQ by Tim Evans on Unsplash. Alt text: A wall of numbered metal safe deposit boxes in a bank vault.

Before the next deploy

Get it running from the session you are already in

Connect your coding agent over MCP and ask it to deploy. aidrop builds the repository and runs it on a public address; when a build or the app fails, the log says why, and your agent fixes it and builds again.