API Tokens
How NetStacks uses API tokens: the local agent's single Bearer auth token, and the 'API Token' vault credential type for third-party sources like NetBox.
Overview
The term "API token" means two different things in NetStacks, and it is worth keeping them separate:
- The agent auth token — a single bearer token that the local NetStacks agent requires on every call to its localhost HTTP API. This is an internal authentication mechanism between the NetStacks desktop app (or a remote deployment) and its bundled agent process. You rarely touch it directly.
- The "API Token" credential type — a kind of secret you can store in the vault, used to hold third-party API tokens such as a NetBox or LibreNMS token so NetStacks can authenticate to those external systems on your behalf.
NetStacks does not expose a token-management UI with creatable, expiring, or individually revocable platform tokens. The agent uses one auth token per running session, and external tokens are stored as ordinary vault credentials. This page documents exactly what exists.
The Agent Auth Token
The NetStacks agent serves its REST API on a localhost-only listener (bound to 127.0.0.1) over TLS, on an ephemeral port chosen at startup. Every request to that API — except the health check — must carry a valid bearer token in the Authorization header.
The token is a 256-bit value, hex-encoded (64 hex characters). It is obtained in one of two ways:
- Provided by the parent app. When the desktop app launches the agent as a sidecar, it generates the token and passes it to the agent through the
NETSTACKS_AUTH_TOKENenvironment variable. The agent accepts the value if it is at least 32 characters long. - Generated by the agent. If no usable
NETSTACKS_AUTH_TOKENis supplied (for example, in a remote deployment), the agent generates a fresh random 256-bit token and prints it to stdout asNETSTACKS_AUTH_TOKEN=<hex>so the launcher can capture it from the session.
# Example of what the agent prints on stdout when it self-generates a token
NETSTACKS_AUTH_TOKEN=3f9c1a7e0b54d2986af31c0d77e5b2148c690fa3de1b4476a2e8c5d019f3ab7cAfter reading the token, the agent removes NETSTACKS_AUTH_TOKEN from its own environment so that child processes it spawns (scripts, PTY commands, and so on) do not inherit the secret.
How the Auth Token Works
Bearer authentication on every route
An auth middleware runs in front of the API. It reads the Authorization header, requires it to begin with Bearer , and compares the remaining token to the session token held in memory. Missing or non-matching tokens get a 401 Unauthorized JSON response of the form {"error": "unauthorized"}.
Constant-time comparison
The token comparison is constant-time (it does not short-circuit on the first differing byte), which avoids leaking information about the token through timing.
The health endpoint is exempt
Exactly one route is exempt from authentication: GET /api/health. The exemption is an exact-path match, so parameterized routes that merely end in the string health are not exempt — they still require the token. The health endpoint returns the plain-text body ok.
No expiration, no revocation list, no rate limiting
The auth token is valid for the lifetime of the agent process. There is no per-token expiration date, no revocation list, and no built-in API rate limiter. Restarting the agent rotates the token: the old one stops working and a new one takes its place. Because the API is bound to localhost over TLS, the token is not exposed on the network.
Calling the Local API
If you need to call the agent API directly, send the token as a bearer token. The base URL is https://127.0.0.1:<port>, where the port is the ephemeral port the agent bound at startup. The TLS certificate is a locally generated cert for 127.0.0.1, so a generic HTTP client will need to trust it (or skip verification for local debugging).
Health check (no token required)
# Health endpoint is the only route exempt from auth.
# Replace 54321 with the agent's actual ephemeral port.
curl -k https://127.0.0.1:54321/api/health
# -> okAuthenticated request
# Every other route requires the bearer token.
export NETSTACKS_AUTH_TOKEN=3f9c1a7e0b54d2986af31c0d77e5b2148c6...
export AGENT_PORT=54321
curl -k https://127.0.0.1:${AGENT_PORT}/api/info \
-H "Authorization: Bearer ${NETSTACKS_AUTH_TOKEN}"The middleware only accepts headers that start with the literal prefix Bearer (capital B, single trailing space). A missing prefix, a lowercase bearer, or stray whitespace around the token will produce a 401 Unauthorized.
Python example
import os
import requests
PORT = os.environ["AGENT_PORT"]
TOKEN = os.environ["NETSTACKS_AUTH_TOKEN"]
BASE = f"https://127.0.0.1:{PORT}"
headers = {"Authorization": f"Bearer {TOKEN}"}
# verify=False is only for local debugging against the self-signed localhost cert.
resp = requests.get(f"{BASE}/api/health", verify=False)
print(resp.text) # "ok"
resp = requests.get(f"{BASE}/api/info", headers=headers, verify=False)
print(resp.status_code) # 401 if the token is missing or wrongThe "API Token" Credential Type
Separately from the agent auth token, the vault supports an API Token credential type for storing the API tokens of external systems. The credential types NetStacks can store are:
ssh_password— SSH passwordssh_key— SSH private keyapi_token— an API token for a third-party servicesnmp_community— SNMP community stringgeneric_secret— any other secret value
A common use of api_token is integration with inventory and monitoring sources. For example, NetStacks authenticates to NetBox by sending the stored token in an Authorization: Token header (not Bearer). LibreNMS instead expects the token in an X-Auth-Token header:
# How NetStacks authenticates to a NetBox source using a stored token.
curl https://netbox.example.net/api/dcim/devices/ \
-H "Authorization: Token ${NETBOX_API_TOKEN}" \
-H "Accept: application/json"
# How NetStacks authenticates to a LibreNMS source using a stored token.
curl https://librenms.example.net/api/v0/devices \
-H "X-Auth-Token: ${LIBRENMS_API_TOKEN}"API Token credentials are managed in the vault alongside SSH and SNMP secrets, so they benefit from the same encryption at rest. See the related links below for how the vault stores secrets and how to wire up a NetBox source.
Questions & Answers
- Q: Does NetStacks have a dashboard to create and revoke API tokens?
- A: No. There is no platform token manager with creatable, expiring, or individually revocable tokens. The agent uses a single bearer token per running session, and external service tokens are stored as ordinary vault credentials of the
api_tokentype. - Q: Where does the agent auth token come from?
- A: From the
NETSTACKS_AUTH_TOKENenvironment variable supplied by the parent app (sidecar mode), or, if none is provided, the agent generates a random 256-bit hex token at startup and prints it to stdout for the launcher to capture. - Q: What is the auth header format for the local agent API?
- A:
Authorization: Bearer <token>— the header must start with the exact prefixBearerfollowed by the 64-character hex token. - Q: Which endpoints require the token?
- A: All of them except
GET /api/health, which is exempt by exact-path match and returns the bodyok. Every other route returns401 Unauthorizedwithout a valid token. - Q: Does the auth token expire?
- A: There is no expiration date. The token is valid for the lifetime of the agent process. Restarting the agent effectively rotates it — the previous token stops working.
- Q: Is there API rate limiting on the agent?
- A: No built-in rate limiter ships with the local agent API. Authentication is the single gate, and the API is bound to
127.0.0.1over TLS. - Q: How do I store a NetBox or LibreNMS token?
- A: Store it as an
api_tokencredential in the vault. NetStacks sends a NetBox token in anAuthorization: Token <token>header, and a LibreNMS token in anX-Auth-Tokenheader.
Troubleshooting
401 Unauthorized from the agent API
- Confirm the header is exactly
Authorization: Bearer <token>with a capitalBand a single space before the token. - Make sure you are using the current token. The token rotates on every agent restart, so a value captured from a previous run will be rejected.
- Strip stray whitespace or newlines from the token — the comparison is exact.
- Remember that only
GET /api/healthis exempt. A route that merely ends inhealthstill needs the token.
# Quick check that the agent is up (no token needed):
curl -k -s -o /dev/null -w "%{http_code}\n" https://127.0.0.1:${AGENT_PORT}/api/health
# Expected: 200, body "ok"
# Check that your token is accepted on an authenticated route:
curl -k -s -o /dev/null -w "%{http_code}\n" https://127.0.0.1:${AGENT_PORT}/api/info \
-H "Authorization: Bearer ${NETSTACKS_AUTH_TOKEN}"
# 200 = good, 401 = bad/missing tokenTLS certificate errors against 127.0.0.1
The agent serves over TLS with a locally generated certificate for 127.0.0.1. A generic HTTP client will not trust it by default. For local debugging you can disable verification (-k in curl, verify=False in requests); in the NetStacks app the certificate is trusted automatically.
External source returns 403 with a stored API Token
If a NetBox or LibreNMS integration fails to authenticate, verify the stored api_token credential is current and that you are using the header the source expects — NetBox uses Authorization: Token, while LibreNMS uses X-Auth-Token. Regenerate the token in the source system and update the vault credential if needed.
Related Features
Learn more about credentials and integrations:
- Credential Vault — How secrets, including stored API tokens, are encrypted at rest
- SSH Passwords & Keys — The other credential types you can store alongside API tokens
- SNMP Communities — Storing SNMP community strings as vault credentials
- Personal Vaults — Personal versus shared credential scopes
- NetBox Integration — Using a stored API token to sync inventory from NetBox