Skip to content

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.

WayPersistsUse it for
Saved profileYes, in ~/.dreadnode/Anyone working against the deployment day to day
Environment variablesNo, only the shellCI, containers, disposable shells
Per-invocation flagsNoOne-off commands, and automation that must not touch ~/.dreadnode/

The normal path. Log in once, naming the profile so it does not collide with a hosted-platform login:

Terminal window
dn login --server https://dreadnode.acme.internal --profile acme-prod

That 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:

Terminal window
dn login --server https://dreadnode.acme.internal --profile acme-prod dn_key_abc123

The TUI, CLI, and SDK all read the same saved profiles, so one login covers all three.

A shell that exports these behaves like a disposable profile, and never writes to ~/.dreadnode/:

VariableMeaning
DREADNODE_SERVERPlatform API URL
DREADNODE_API_KEYPlatform API key
DREADNODE_ORGANIZATIONDefault organization
DREADNODE_WORKSPACEDefault workspace
DREADNODE_PROJECTDefault project
Terminal window
export DREADNODE_SERVER=https://dreadnode.acme.internal
export DREADNODE_API_KEY=dn_key_...
export DREADNODE_ORGANIZATION=acme
export DREADNODE_WORKSPACE=main
dn evaluation list

--server with --api-key bypasses saved profiles entirely. This is the right shape for CI, where parallel jobs would otherwise race on profile writes:

Terminal window
dn task sync ./tasks \
--server https://dreadnode.acme.internal \
--api-key "$DREADNODE_API_KEY" \
--organization acme

The SDK and CLI carry a network context on each API connection. It selects which server-configured storage endpoint appears in download URLs and workspace storage credentials; it does not change permissions or the API server URL.

  • public (default): use the browser-facing storage endpoint.
  • cluster: use the internal storage endpoint. Choose this only when the client can resolve and reach that endpoint.
Terminal window
export DREADNODE_NETWORK=cluster

In Python, an explicit connection setting overrides the environment:

import dreadnode as dn
dn.configure(network="cluster")

The setting is fixed when the API client is constructed. It is not saved in login profiles. Browsers default to public. The API does not infer storage reachability from Host or forwarded headers. Raw API clients send X-Dreadnode-Network: cluster or X-Dreadnode-Network: public; other values are rejected by storage download endpoints. Clients cannot supply arbitrary storage hosts.

OpenSandbox provisioning sets cluster before startup. Remote sandbox deployments can override that default using SANDBOX_NETWORK. A request authenticated with a sandbox’s own API key that carries no network header is routed by that same setting, so tools inside a sandbox that do not send the header (curl, older SDK pins) still receive storage URLs the sandbox can reach. An explicit header always wins. Async exports and reports are signed when retrieved, so clients on different networks can download the same completed job without changing each other’s URLs.

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:

CombinationError
--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.

Give the root URL of your deployment — the same host users open in a browser:

https://dreadnode.acme.internal

Clients 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.

Profiles are how you keep a hosted account and an on-prem deployment side by side:

Terminal window
dn login --profile saas # hosted
dn login --server https://dreadnode.acme.internal --profile acme # on-prem
dn evaluation list --profile acme

Inside the TUI, /profile opens the saved-profile picker and /login switches deployments.

Before anything consequential, confirm which one you are pointed at:

Terminal window
dn whoami

It prints the active profile, user, org, workspace, project, and server URL. Add --json for scripting.

Two different things, and the names invite confusion:

FlagPoints at
--serverThe platform API — your Dreadnode deployment
--runtime-serverAn 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.

On a disconnected network, install the client from the deployment before pointing it anywhere — the published install command reaches two public hosts and cannot complete. See Installing the CLI and SDK.

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.

SymptomCause
Certificate verification failureThe client does not trust your CA — see Trust an internal certificate
Connection refused or timeoutDNS resolves elsewhere, or the host is not reachable from this network
Redirect loops, or cookies not stickingScheme mismatch — a client using HTTP against an HTTPS deployment, or the reverse
401 UnauthorizedThe key is wrong, revoked, or belongs to a different deployment
Commands reach the wrong platformA DREADNODE_SERVER in the shell is overriding the profile — check dn whoami
--profile and --server are mutually exclusivePass one or the other; the profile already carries a URL