Skip to content

API tokens and scopes

An API token is a long-lived credential for your own systems: CI, cron, curl, an AI agent. It never expires and is revoked explicitly, and it carries only the scopes you tick when you create it. (Scopes beyond notifications: since v0.4.1.)

  1. In the Console, open Settings > API tokens (the same section also appears on the Notifications page) and click Create token.
  2. Name it after the system that will use it (ci, backup-cron, claude-code).
  3. Tick the scopes it needs.
  4. Copy the dak_… secret: it is shown exactly once.
Scope What it unlocks Typical holder
Read-only (read) list hosts, services, watchdogs, uptime and your account limits. No changes, and no secrets: from v0.14.11 a watchdog’s address and ping_url come back blank unless the token also has Manage watchdogs a dashboard, a status script
Manage hosts (hosts:manage) enroll new hosts (mint join tokens), remove hosts, run updates - always in your own account, even if your account is an admin one (from v0.14.11) a provisioning script, an AI agent
Manage services (services:manage) publish and unpublish exports, public ports, gateway ports, proxy ports, health checks, and custom domains (since v0.4.5), including pointing a hostname on a domain at an app (since v0.7.0), and managing who may open an app that requires a DedNets login (since v0.10.0) a deploy pipeline
Manage watchdogs (watchdogs:manage) create, edit, pause, resume and delete watchdogs a backup job that registers its own monitor
Manage uptime monitors (uptime:manage) create, edit, pause, resume and delete uptime monitors, and read their history (since v0.4.5) a deploy pipeline that watches the site it just shipped
Manage files (files:manage) share and stop sharing folders your hosts declare (since v0.8.0). It cannot create a folder, widen one past the host’s own limit, or read file content a script that opens a folder for a transfer
Signals (signals) report, list, resolve and retune signals (since v0.9.0). It cannot delete one, and it cannot mint a reporting URL the cron job that reports a condition
Signals reporting URLs (signals:sources) create, list and revoke reporting URLs (since v0.14.7) a provisioning script or an agent that sets up new machines
Notifications (notify) publish and read notification events. From v0.14.11 the topic listing comes back without each topic’s address: publishing uses the topic name, and the address is a URL anyone holding it can publish and subscribe with CI posting build results

Why reporting URLs are a scope of their own. A reporting URL is a credential: whoever holds it can report as that source. Signals lets something report a condition; Signals reporting URLs lets it hand out new credentials that report conditions. Those are different decisions, so they are different boxes, and ticking the first never implies the second. It is also the reason Read-only does not cover even listing them: the listing prints live URLs, and read-only is supposed to reveal no secrets.

Nothing is weakened by granting it: a reporting URL can only open and repeat a signal. It cannot list, resolve, retune or delete anything, so a token that can mint one still cannot use it to gain anything it did not already have.

  • A CI job that only posts build events: Notifications.
  • A provisioning script that installs a reporter on each new machine: Signals reporting URLs, and nothing else.
  • A status page or dashboard: Read-only.
  • An AI agent doing the whole onboarding journey: Read-only, Manage hosts, Manage services and Manage watchdogs.

A token can carry up to nine scopes.

  • Mint or revoke API tokens. That needs you, signed in.
  • Delete a signal. That needs you, signed in: closing a signal is reversible and a token may do it, but destroying its history is not. (Minting a reporting URL needed your login too until v0.14.7; it is now the signals:sources scope above.)
  • Change your password or account settings.
  • Manage another account, or reach another user’s resources - including when the account that minted it is an admin account. A token is a machine credential, not a person: it acts inside its owner’s namespace and nowhere else. (Until v0.14.11, a Manage hosts token minted by an admin could enroll a host into someone else’s account. It now answers 403.)
  • Read a folder’s contents. Opening a file transfer needs you, signed in as the account that owns the folder.
  • Collect a capability URL it could keep using after you revoke it: a watchdog ping URL, or a notification topic address. Those are blanked for the scopes that do not manage them, because revoking a token does not change a URL the token already copied somewhere.

This is why a leaked token cannot widen its own access.

Send the token as a bearer credential on every request:

Terminal window
curl -fsS -H "Authorization: Bearer dak_your_token_here" \
https://console.dednets.com/api/v1/topology

If the token lacks the scope for a route, the answer is a 403 that names the scopes which would have worked:

{"error":{"code":"scope_denied","message":"this API token's scope does not cover this endpoint (token scope: read; required, any of: watchdogs:manage)","status":403,"scopes_allowed":["watchdogs:manage"]}}

Scopes are fixed when the token is minted, so the fix is a new token with the extra scope.

dednetsctl login keeps the token in ~/.config/dednets/token (mode 0600) so every later command, and every MCP server your agent host starts, finds it. Pass it the ways that keep it out of your shell history and out of the process table, where any other user on the machine can read it (the - and @FILE forms are since v0.14.11):

Terminal window
pbpaste | dednetsctl login # or: cat token.txt | dednetsctl login
dednetsctl login -token - # the same, explicitly
dednetsctl login -token @/run/secrets/dednets # from a file

dednetsctl login -token dak_… still works for scripts, and warns when you run it at a terminal: a token written on the command line is visible in ps for as long as the command runs and is saved to your history file afterwards. dednetsctl setup -token takes the same three forms.

Your Console URL should be https://. Over plain http:// the token travels in the clear and the CLI says so on every run (since v0.14.11); a Console on 127.0.0.1 is exempt.

Revoke a token from the same API tokens section; revocation takes effect immediately. You can hold up to 20 tokens per account. Keep the secret in your secret manager, never in a repository. If a token leaks, revoke it and mint a replacement.