Authentication
A browser authenticates with a session cookie. Everything else — the CLI, the MCP server, CI — uses a personal access token.
Getting one
On your own machine, let the CLI do it:
Code
Either way the token is minted, named after the machine, and written to
~/.config/drop2run/config.json with mode 0600. You never see the string, which is the point: a
credential you never copy is one you cannot paste somewhere it should not be. See CLI.
In a chat, let the MCP server do it: its login tool runs the same browser sign-in and writes the
same file, and login_code is the same code flow as --device. Nothing is installed and no token is
pasted — ask for a publish and the sign-in happens on the way. See MCP server.
By hand, for CI — where nothing can open a browser or approve anything:
- Sign in at dropto.run
- Open Account → Access tokens
- Name it after where it will live:
ci,deploy-runner
That one is shown once. The server stores a SHA-256 hash and the first twelve characters, so nothing — not this site, not support, not the database — can show it again. Lose it and the answer is to revoke it and make another.
Both routes produce the same kind of token with the same powers. The difference is only who typed it.
Using one
Code
Tokens look like d2r_ followed by 43 base62 characters. The prefix is fixed so a secret scanner can
recognise one in a leaked file, and the body avoids -, +, / and = so nothing that pastes it —
a shell, a URL, a YAML file — breaks it in half.
The CLI and the MCP server read a token from DROP2RUN_TOKEN, or from
~/.config/drop2run/config.json:
Code
The environment wins. Both tools use the same file and the same precedence, so signing in once covers both.
What a token cannot do
It cannot create or revoke tokens. Both need a browser session — including through the CLI and the
MCP server: login, login --device and the login_code tool all end at a page you approve while
signed in, which is exactly what makes them allowed to produce one. A model calling login cannot mint
itself anything; it can only ask you to approve a sign-in.
This is the one restriction worth understanding rather than working around. Without it, a leaked token is
not a leaked credential — it is a permanent one: whoever takes it mints a second, and revoking the first
achieves nothing, because the replacement is a token you never made and will not recognise in your list.
gh and vercel draw the same line.
It cannot reach the admin console. /api/admin requires a cookie session and an internal account.
Tokens and two-factor sign-in
A token is not a sign-in, so it never asks for a code. Turning two-factor on does not end the tokens you already have — revoke them from Account → Access tokens if that is what you wanted.
Getting one does go through a sign-in. login, login --device and login_code all end at a page you
approve in the browser, and signing in there asks for your code like any other sign-in. If a team you
belong to requires two-factor, approving is refused until you turn it on:
Code
When an owner starts requiring it, members' existing tokens keep working — a CI job does not break at the moment the rule changes. The confirmation the owner sees before turning it on says how many tokens are held by members who do not have two-factor yet.
When one stops working
A rejected token gets 401 with invalid_token, not 403:
Code
The difference matters to a script. 401 means the credential is the problem — revoked, expired, or the
account can no longer publish. 403 means the credential is fine and the request is not allowed: the
site belongs to somebody else, or the plan does not include what was asked for.
Which of those four applies is not reported. To whoever holds the token they are one answer — stop using it — and saying which would tell somebody holding a stolen one whether the account had noticed.
Knowing which tokens are still in use
Every authenticated request stamps last_used_at, at most once every five minutes. The account page shows
it, and it is the only thing that tells a token still in use from one worth revoking.
That column is the whole compensation for tokens being long-lived. They do not expire on their own unless you give them an expiry, which is the trade: convenient for CI, and a leak lasts until somebody notices.