Connect clients
Point the Dreadnode TUI, CLI, and SDK at a self-hosted deployment — profiles, environment variables, flags, and which one wins.
Every Dreadnode client defaults to the hosted platform at https://app.dreadnode.io. Pointing one
at your own deployment means supplying two things: a server URL and an API key. This page
is the canonical explanation of how they are supplied and which source wins — the TUI, CLI, and
SDK all resolve them identically.
Each user does this once, on their own machine.
Three ways to set a server
Section titled “Three ways to set a server”| Way | Persists | Use it for |
|---|---|---|
| Saved profile | Yes, in ~/.dreadnode/ | Anyone working against the deployment day to day |
| Environment variables | No, only the shell | CI, containers, disposable shells |
| Per-invocation flags | No | One-off commands, and automation that must not touch ~/.dreadnode/ |
A saved profile
Section titled “A saved profile”The normal path. Log in once, naming the profile so it does not collide with a hosted-platform login:
dn login --server https://dreadnode.acme.internal --profile acme-prodThat opens the browser device-code flow and saves the resulting key. To skip the browser — for a machine account, or when the browser cannot reach the deployment — pass an existing API key instead:
dn login --server https://dreadnode.acme.internal --profile acme-prod dn_key_abc123The TUI, CLI, and SDK all read the same saved profiles, so one login covers all three.
Environment variables
Section titled “Environment variables”A shell that exports these behaves like a disposable profile, and never writes to ~/.dreadnode/:
| Variable | Meaning |
|---|---|
DREADNODE_SERVER | Platform API URL |
DREADNODE_API_KEY | Platform API key |
DREADNODE_ORGANIZATION | Default organization |
DREADNODE_WORKSPACE | Default workspace |
DREADNODE_PROJECT | Default project |
export DREADNODE_SERVER=https://dreadnode.acme.internalexport DREADNODE_API_KEY=dn_key_...export DREADNODE_ORGANIZATION=acmeexport DREADNODE_WORKSPACE=maindn evaluation listPer-invocation flags
Section titled “Per-invocation flags”--server with --api-key bypasses saved profiles entirely. This is the right shape for CI,
where parallel jobs would otherwise race on profile writes:
dn task sync ./tasks \ --server https://dreadnode.acme.internal \ --api-key "$DREADNODE_API_KEY" \ --organization acmeWhich one wins
Section titled “Which one wins”Resolution is the same for every client:
Explicit flag → environment variable → saved profile → built-in default.
The built-in server default is the hosted platform. A machine with no
configuration resolves app.dreadnode.io, but platform commands still fail
locally until an API key is available.
Operational commands reject three explicit-flag combinations rather than silently resolving them:
| Combination | Error |
|---|---|
--profile with --server | --profile and --server are mutually exclusive |
--profile with --api-key | --profile and --api-key are mutually exclusive |
--api-key without --server | --api-key requires --server |
The reasoning is the same in all three: a profile already carries a URL and a key, so pairing it
with either would leave which value applies ambiguous. dn login is the
exception: combining --server with --profile names the profile where that
server login will be saved.
What to put in the URL
Section titled “What to put in the URL”Give the root URL of your deployment — the same host users open in a browser:
https://dreadnode.acme.internalClients append the API path themselves. URLs ending in /api or /api/v1 are
also accepted and normalized.
The scheme must match the deployment’s own scheme setting. A deployment configured for HTTPS does not behave correctly when addressed over HTTP, and the failure surfaces as redirect or cookie errors rather than a clear message.
Running more than one deployment
Section titled “Running more than one deployment”Profiles are how you keep a hosted account and an on-prem deployment side by side:
dn login --profile saas # hosteddn login --server https://dreadnode.acme.internal --profile acme # on-prem
dn evaluation list --profile acmeInside the TUI, /profile opens the saved-profile picker and /login switches deployments.
Before anything consequential, confirm which one you are pointed at:
dn whoamiIt prints the active profile, user, org, workspace, project, and server URL. Add --json for
scripting.
--server is not --runtime-server
Section titled “--server is not --runtime-server”Two different things, and the names invite confusion:
| Flag | Points at |
|---|---|
--server | The platform API — your Dreadnode deployment |
--runtime-server | An already-running local agent runtime started by dn serve |
Self-hosting changes --server. It has no bearing on --runtime-server, which stays local to the
operator’s machine unless you deliberately share a runtime.
Internal DNS and air-gapped networks
Section titled “Internal DNS and air-gapped networks”The device-code login flow completes in a browser, and that browser must reach the same platform URL the CLI is using. On a laptop with VPN or split-horizon DNS this is usually fine.
When it is not — a jump host, a headless CI runner, or a network where the browser and the shell
resolve different things — skip the flow and pass a machine API key to dn login, or use
--server with --api-key per invocation. Create scoped machine keys rather than sharing an
interactive user’s key.
When it does not connect
Section titled “When it does not connect”| Symptom | Cause |
|---|---|
| Certificate verification failure | The client does not trust your CA — see Trust an internal certificate |
| Connection refused or timeout | DNS resolves elsewhere, or the host is not reachable from this network |
| Redirect loops, or cookies not sticking | Scheme mismatch — a client using HTTP against an HTTPS deployment, or the reverse |
401 Unauthorized | The key is wrong, revoked, or belongs to a different deployment |
| Commands reach the wrong platform | A DREADNODE_SERVER in the shell is overriding the profile — check dn whoami |
--profile and --server are mutually exclusive | Pass one or the other; the profile already carries a URL |