NodeRingsDocs

Authentication model

How OAuth, service accounts, and token refresh work in the nr CLI

The CLI authenticates to the NodeRings HTTP API with a Bearer token. There are two practical sources for that token.

Human sessions (OAuth)

nr auth login runs a browser-based OAuth flow with PKCE:

  1. CLI starts a local callback listener
  2. You approve the login in the browser
  3. CLI stores access + refresh tokens (keyring when available, otherwise a 0600 file)
  4. Near expiry, DoWithAutoRefresh-style API calls refresh once and retry

Use this on laptops and bastions (for example to create the first service account). It is a poor fit for agent VMs and unattended CI. Agent install uses a service-account token, not this flow.

Machine sessions (service accounts)

Service accounts are organization-scoped machine identities with RBAC roles and optional IP allowlists. Tokens are JWTs you mint once (nr sa token generate) and store in a secret manager.

The CLI treats NR_API_TOKEN as an opaque Bearer credential — it does not attempt OAuth refresh for service account JWTs. When the JWT expires, mint a new one and rotate the secret.

nr cluster register also requires --org-id (or NR_ORGANIZATION_ID). That value is only the X-Organization-ID header. It is not a credential: a missing token, a token for a different organization, or a role without agent permissions is still rejected.

Why least privilege matters

A token that can register agents can also delete them if DeleteAgent is granted. Bind a custom role to the exact Agent and Organization permissions you need (service accounts how-to).

Organization verification gate

Authentication success ≠ agent API authorization. Unverified provider organizations can sign in and still be blocked from creating agents until marketplace review completes.

Security properties worth knowing

  • Tokens in config/files use restrictive Unix modes (0600)
  • Interactive secret prompts do not echo
  • Proxmox instance files must not be group/world-readable
  • Proxmox URLs must be https:// — plaintext endpoints are rejected
  • JSON/API responses with secrets are not printed by default; token generate shows a JWT once

Related: Authenticate · Access control.