Skip to content

First login via OIDC

Nyxtrace has no local accounts. Every session comes from your OIDC provider, and the tenant a person can see is derived from that session — never from a URL, a cookie the browser chose, or a query parameter.

In your identity provider, create a confidential client for Nyxtrace:

Setting Value
Client type Confidential (client secret)
Redirect URI https://docs.example.invalid/api/auth/callback — your real host, that exact path
Scopes openid, profile, email, plus your groups claim
Grant Authorization code

Bind whatever access policy you want in front of it. Nyxtrace never sees a password and cannot weaken your provider’s policy.

Two kinds of group map onto Nyxtrace’s authorisation:

  • One administrator group, for people who may see administrative health detail.
  • One group per tenant, for people who may see that tenant’s data.

A person with no tenant group has no tenant and therefore sees nothing — that is the intended failure mode, not an error to work around. A person in several tenant groups picks one through a server-side session operation before any data route is used; they cannot hold two tenants at once.

Put the issuer, client ID, client secret, the public HTTPS URL of the interface and the group-to-role mapping into the generated web environment file (mode 0600, root-owned, under /etc/ndr). Then restart the web service.

Nothing OIDC-related belongs in a YAML file. If a secret is readable by group or others, the service refuses to start.

By default the web layer binds to loopback and is unreachable. Making it reachable takes two deliberate settings:

  • the bind address it should listen on, and
  • the list of source networks allowed to reach port 3001.

The appliance’s own firewall table then admits port 3001 from those networks and nothing else. Put your reverse proxy in front of that, terminate TLS there, and restrict the proxy’s own route to the networks that should reach the UI. The proxy’s egress addresses and the browser networks are two different lists, and Nyxtrace keeps them as two different settings for exactly that reason.

Open the interface. The root path redirects to the login page, the login page starts the OIDC flow, and your provider sends the browser back to the callback. After that you land on the overview.

What you should see, and what you should not

Section titled “What you should see, and what you should not”

On a freshly installed appliance the first session is deliberately sparse, and knowing what is normal saves an evening of debugging:

You should see devices appearing in the inventory within minutes of the first source being connected, the globe drawing arcs to external destinations once GeoIP databases are loaded, and the system view listing every configured source with a freshness figure.

You should see an empty incident list. During the learning phase the hourly analysis runs successfully and records its model results with score 0, marked as a learning baseline. An empty incident list with a green analysis timer is the correct state, not a broken one.

You should not see demo data. Synthetic data is explicitly labelled everywhere it appears and is refused outright by a production build — an ordinary binary cannot start a fixture. If you see a demo banner in production, you are running the wrong artifact.

You may see gaps, and they will be named. A source that has never delivered stays visible as unknown; one that stopped delivering becomes stale rather than disappearing. Facts age out; they are never deleted to make a dashboard look complete.

Role May
reader Read everything in their tenant
analyst Change incident status, patch device classification, decide proposals
responder Create and decide response proposals
admin See administrative health detail, including host-local messages

Both the web layer and the Go core check the role on every operation independently. A non-admin gets the same health response shape with host-local detail redacted, not a different, quietly reduced document.