Concepts

Authentication

How Div knows it's really you — claim tokens for first deploys, personal access tokens for everything after.

Authentication

Div doesn't make you sign up before deploying. The flow is intentionally backwards from most tools out there: you ship first, then you claim. We think it's a much friendlier way to start.

#Claim tokens

When you run div deploy for the very first time:

  1. The CLI asks for your email.
  2. The server creates an unverified user (so the email is reserved) and a locked project, then returns a 48-character random claim token.
  3. The CLI saves that token to ~/.config/div/auth.json, keyed by slug.
  4. Every file upload includes the token in an Authorization: ClaimToken <token> header.
  5. The server emails you a one-time signed verification URL.

Until you click the verification link, the project is locked:

  • The website isn't public — <slug>.div.so returns 404 to anyone who isn't holding the claim token in a session.
  • Only the CLI session (which has the saved claim token on disk) can write to it.
  • Only your email can claim it (the verification URL is signed with the project ID and tied to your address).

When you click the link:

  • Your email is verified.
  • locked_at, claim_token, and claim_email are cleared on the server.
  • is_public flips to true.
  • You're redirected to the live URL.

#What this means in practice

Situation What works
You just deployed and haven't clicked the link yet div deploy from the same machine + same folder updates the website without prompting.
You clicked the link A personal access token (PAT) is now saved on the machine you originally deployed from — div deploy, div projects, etc. all work without prompts.
You deployed from machine A, now you're on machine B Run div login on machine B once. Subsequent commands work.
You verified a year ago and forgot The website is yours forever. Run div login to get a fresh CLI session whenever you need it.

#Where credentials live

Claim tokens get tucked away at:

~/.config/div/auth.json

The file is created with mode 0600 (owner read/write only) and looks like:

{
  "projects": {
    "mysite-a4f9d2": {
      "claimToken": "...",
      "savedAt": "2026-04-25T12:34:56.789Z"
    }
  }
}

The path is platform-appropriate (macOS, Linux, Windows) — the CLI uses env-paths to pick the right location. To see where it actually lives on your machine, you can dig it out of the dirname of div config path.

You're free to delete this file at any time to log out locally. Since claim tokens become invalid the moment a project is verified, deleting the file before verification means you'll need to run div login before pushing updates again. Deleting it after verification is harmless if you're comfortable signing in again later.

#Why we designed it this way

A few nice things fell out of designing it this way:

  • Zero friction for first deploys. You don't have to sign up, pick a password, set up 2FA, or solve a captcha just to see your website live.
  • Email proves it's you. The verification step ensures the email on record is real.
  • Slug squatting is bounded. Locked projects get swept after 7 days if nobody verifies them, so a typo or abandoned attempt doesn't permanently burn a slug.
  • No long-lived credentials in a checked-in file. The CLI's saved tokens never get committed to git (div.json doesn't carry them). Even if you commit your whole project folder, your auth lives elsewhere.

#Personal access tokens (after verification)

Once you've verified a project — either by clicking the link from your first deploy or by running div login — a personal access token (PAT) lands in the user block of auth.json:

{
  "user": {
    "email": "you@example.com",
    "apiToken": "1|<random-40-char-string>",
    "verifiedAt": "2026-05-24T18:32:01.123Z"
  },
  "projects": { ... }
}

From then on, every CLI request that needs an account (div deploy updates, div projects, div whoami) sends the token as Authorization: Bearer ***. The token is scoped to the cli:deploy ability — it can mint projects, write files, and list yours, but nothing else.

PATs don't expire on a timer. They die when:

  • You run div logout on this machine.
  • An admin revokes them server-side.
  • The local Laravel DB is reset out from under you (only relevant in dev — see the "Your session has expired" entry in Troubleshooting).

When a token dies, the next div deploy / div projects call returns a friendly "session expired" message and (for div projects) auto-clears the dead token from auth.json. Re-run div login to get a fresh one.

#See also