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

The tool works. It is on a URL. You paste the link in a channel so two colleagues can try it.

Nobody asked the next question, and it is the one that matters: who else can open that link? Not who will — who can. If the answer is "anyone who has it", you have published an internal tool to the internet and told yourself you shared it with two people.

A link is not an access control. It is a secret that spreads by design.

An unlisted URL is a password everybody forwards

Unguessable addresses feel private because nothing links to them. That intuition fails quickly. The link goes into a chat that is later exported, a ticket, a screenshot, a browser's sync, a bookmark on a personal laptop, an AI assistant's history.

None of that is a breach. It is ordinary use, and every one of those copies is permanent access with no way to revoke it short of changing the URL — which breaks it for everyone at once.

The practical test is simple: if someone left the company tomorrow, what would you have to do to cut off their access? If the answer involves rotating a URL rather than removing a person, there is no access control here.

Internal tools hold more than you remember putting there

The first version reads one table. By the third week it exports a report, calls an internal API with a service key, and caches a payload from a system somebody else owns.

Each addition is reasonable and none triggers a review, because there is no gate to trigger one. Meanwhile the tool has quietly become a way to read production data without touching production — which is exactly what an attacker wants and exactly what an auditor will ask about.

This is the deployment gap continuing past launch. The build was cheap and fast; the operational decisions did not disappear, they were deferred. Access is the one most often deferred indefinitely.

Default closed, open on purpose

The workable pattern is not complicated, and it is much easier to apply at the start than to retrofit.

  • Make the default state private, enforced by identity. Reachable by named people, not by whoever holds a string. Removing a person then removes their access everywhere at once.
  • Make publishing a separate, deliberate act. If going public is a decision somebody takes rather than a state that happens by omission, the question gets asked at least once — and it is the one moment a host can judge what is being published, which is a better place for that check than signup. The same applies to putting your own domain in front of it: a name is not proved by existing in DNS but by requests for it actually arriving, and until that is proved the name should serve nothing.
  • Record who owns it. An internal tool with no owner is a tool nobody will turn off when it should be, and nobody will patch when it must be.
  • Keep the secrets out of the artefact. A key in the container is a key in every copy of it. Values injected at deploy can be rotated; values baked in cannot — where a credential actually lives is the whole of that argument.

The same reasoning applies to what an agent may reach on your behalf. An agent given broad credentials inherits every mistake in scope at once — the write path is the part worth governing carefully, because that is where a small over-permission becomes a durable one.

Not "is this sensitive?" — almost nobody answers that accurately about their own work in progress. Ask instead: if this URL appeared in a public paste tomorrow, what would I have to do?

If the answer is "nothing, it asks for a login" then the tool is shared. If it is "panic", it was published, and it was published the moment the link left your hands.

FAQ

Isn't a long random URL basically secure? Against guessing, yes. Against forwarding, screenshots, exports and browser history, not at all — and those are how links actually travel.

We are five people. Is this over-engineering? The five-person version is the cheap version: identity-based access from the start, and one named owner. It costs an afternoon now and a migration later.

What about tools an AI agent built and deployed? Same rules, more urgency. Speed of creation raises the number of live surfaces, and each one is a door somebody has to decide about.

How do I make private the default? Use a platform where a deployment is reachable only by project members until publishing is reviewed — the shape aidrop.it uses — so the closed state is what happens when nobody makes a decision.

Does this apply to a demo nobody uses? A forgotten tool is the worst case: still live, still credentialed, and nobody left who understands it.


Cover: https://unsplash.com/photos/G8EdTmFZ138 by Igor Saikin on Unsplash. Alt text: A dim office corridor ending in glass double doors, with a lit room visible through them.

Your own domain

Point a name you own at a project that is already running

Claim the hostname, create one record, press verify. The proof is a request rather than a DNS lookup, so a proxy in front of your DNS changes nothing — and the name serves nothing at all until it is proved.