Licensing in Topologix

Infrastructure & Networking

Every Topologix install — the cloud one included — registers with the central licensing portal and checks in every 15 minutes. The portal answers with signed licences: one for the install and one per organisation it hosts. Only the portal issues or extends a licence; the install verifies each signature with the portal keys built into it and enforces the licence’s expiry offline. When a licence runs out, admins are warned first; then configuration freezes while monitoring keeps running — collection, alerting, dashboards and incident work never stop. An unreachable portal is only ever a warning: nothing freezes while the signed licences are valid.

Requirements

  • Outbound HTTPS from the Topologix server to the licensing portal (the install calls out; nothing connects in). Offline or air-gapped licensing is not offered; a portal outage is a warning only — renewals simply wait for the next successful check-in.
  • A correct server clock (NTP). A clock more than 5 minutes off is corrected for check-ins automatically and shown as “instance clock is N min off” on Admin → Licensing.
  • A one-time registration code (TPX-XXXX-XXXX-XXXX) from Topologix — single use, it expires after 14 days.
  • A super admin account on the install to register it.

1 · Register the install

  1. Open Admin → LicensingSigned in as a super admin, open Admin → Licensing. The install already has its own identity (an instance id and a key pair created at first boot; the private key never leaves the server).
  2. Enter the codeCheck the portal URL, optionally name the install, paste the registration code and click Register. The install first asks the portal for its signing keys: if none of them is one this build trusts, registration stops with “This portal’s signing keys are not trusted by this build — wrong portal URL?” and nothing changes. Otherwise it publishes its organisations (id, name, email domain, created date, member count) and receives its signed licences.
  3. Check inFrom now on the install checks in every 15 minutes on its own (the first time 30 seconds after the server starts). Check in now does it at once — after the portal extended a licence, for example.

What the portal receives

Each check-in is a signed request (ed25519 over the exact body, a timestamp and a one-time nonce, so it cannot be replayed or altered).

Counts only

Per organisation and for the whole install, numbers — never the name of a host, VM, device, user, flow, integration or service, and never a configuration, a metric value, a log line or a credential.

CountWhat is counted (per organisation)
MembersActive members of the organisation (install-wide: every user).
Integrations by typeIntegrations that belong to the organisation, per type (e.g. snmp 3, vmware 1).
Flows · flow elementsFlows owned by its members, and the canvas elements on them (counted by the database, every flow, without reading the flows themselves).
Metric sourcesMetric sources on those flows.
ProxiesProxy agents shared with the organisation. Global proxies (run by the install for everyone) are counted install-wide only.
Nodes by kindDiscovered infrastructure — hosts, VMs, devices, Kubernetes nodes, pods, services — per kind.
Catalogue servicesDistinct services in the organisation’s catalogue.
  • Besides the counts: the server version, the uptime, the install’s public URL and the organisation ids and names.
  • Admin → Licensing shows the same counts next to each organisation, with the time they were last reported — nothing on the portal is hidden from the install’s own admin.
  • A check-in costs a fixed handful of database statements whatever the number of organisations (the [license] db-cost: heartbeat log line names them). If counting fails, the check-in still goes out with empty counts and a log line — licensing never depends on the counts.

Warnings, then the configuration freeze

Each organisation is judged by its own licence and the install’s — whichever is stricter wins. Personal accounts are judged by the install licence only.

The stages

Warnings come first, and only configuration is ever refused.

  • Warning — from 30 days before expiry (the licence carries the exact window): an amber banner and a chip in the top bar, and an email to the organisation’s owner and admins at 30, 7 and 1 days (install licences: to the super admins). Without SMTP configured the banner is the only notice.
  • Frozen — after the expiry date: a red banner “Configuration is frozen — monitoring continues” and one more email. Creating or changing flows, integrations, metric sources, monitors, alert rules, users, organisations and settings is refused (HTTP 423) until the portal extends the licence; the next check-in lifts the freeze by itself.
  • A frozen install keeps collecting, alerting, notifying and drawing every dashboard.

What keeps working while frozen

Every page and every read. Among the changes, only the operational ones:

  • signing in and out, password changes;
  • everything proxy agents send (results, NetFlow, SNMP traps, OTLP relay) and OTLP ingest straight to the server;
  • acknowledging alerts and alert events, snoozing hardware findings, maintenance windows and alert suppressions;
  • change records (the Changes API included);
  • searches and analyses that are sent as a form: alert explanations, NetFlow queries, name resolution, knowledge search, AI trace / log analysis and the flow bot’s diagnosis;
  • inbound workflow webhooks, health and status probes, browser security reports;
  • Admin → Licensing itself, so a super admin can always register, check in or fix the portal URL.

What freezes — and what only warns

Configuration freezes for exactly four reasons; everything else is a warning.

SituationGraceThen
A signed licence has expiredwarnings from 30 days before (the licence carries the window)frozen until the portal extends it
The portal sent a signed revocation for the licence—frozen (“the licence was revoked”)
The registration failed: the portal answered “instance revoked” 3 times over at least 24 hours, “instance suspended”, or reports an identity conflictone answer never revokes; a suspension lifts by itselffrozen; a revoked or suspended install keeps checking in every hour and is registered again at the first successful check-in
No licence: a new install not registered yet30 days from install (a Reset identity restarts it)frozen until it is registered
No licence: an organisation without one, or a licence that ran out after the portal stopped listing it14 days from the organisation’s creation, the registration or the moment the licence was lost — whichever is latestfrozen until the portal issues one
The portal cannot be reached (outage, firewall, DNS, TLS, 5xx, a WAF page)an amber banner from 2 days before the licence’s grace (7 days by default) runs out; the super admins get an email at 7 and at 30 daysa warning only — monitoring and configuration continue while the licence is valid
The portal’s answer is not one of its verdicts (unknown instance, bad signature, any other 401 / 403, an HTML error page)—a warning only (shown as a transport error), never counted toward revocation
  • Licences are accepted monotonically: a check-in can replace a licence only with one that supersedes it, a later-expiring one, or a signed revocation. A licence the portal stops listing is kept until its own expiry (“kept until <date>” on Admin → Licensing), so an empty or partial answer from the portal never removes a valid licence.
  • Each licence is verified on its own: a licence signed with a key this build does not know is skipped and that scope keeps the licence it already holds.
  • Clocks may disagree by up to 5 minutes at every boundary without consequence. Beyond that the portal refuses the request time; the install reads the portal’s clock from its answer, retries with the difference, and shows “instance clock is N min behind/ahead of the licensing portal’s” until the server’s time is fixed.
  • A database restored onto a second host is a second install with the same identity: the portal reports a conflict and the copy freezes. Reset identity on Admin → Licensing gives it a new id and key pair (and a fresh 30-day install grace); register it with a new code.

The portal’s signing keys

Every build trusts two portal keys: the active key the portal signs with, and a standby key held offline. If the active key ever has to be replaced, the portal switches to the standby and re-issues every licence — installs already running accept them without an update. Admin → Licensing lists the keys this build trusts (“Trusted portal keys”).

Tiers, bands and packs

A licence names its tier — Community, Business, Enterprise or MSP (older licences of type “standard” show as Business) — and a node band: 100, 250, 500, 1 000, 2 500 or 5 000 monitored nodes, or “Quote” for an unbanded licence. Monitored nodes are the hosts, VMs, devices and Kubernetes nodes the last check-in reported (pods and services are not counted), shown as “Band 1 000 · 712 nodes (71 %)”; a dash means no check-in has reported counts yet. More than 10 % over the band shows an amber “over band” chip — it is informational only: nothing is refused or slowed. Integrations are grouped into packs that follow the integration catalogue’s categories (Cloud & CDN, Monitoring & Observability, Infrastructure & Networking, Data & Storage, Security, Analytics & Apps); a core pack — every alert channel, the AI model providers, HTTP JSON, the DNS and TLS probes and Server Vitals — is part of every tier. Licences include every pack unless the portal narrows the list (see below). When an organisation’s own licence outlasts the install licence, Organisation → Licence says so: “Limited by the instance licence, which expires <date> (<n> days)”.

What a licence can limit

Besides its expiry, a licence may carry integration packs and a few soft limits. Each applies to the members of an organisation (its own licence, else the install licence); a personal account without an organisation is never limited. Nothing already configured stops working: limits are checked only when something is added. A frozen configuration is refused first (the freeze above), so a limit never hides a freeze.

Licence keyChecked whenWhat happens
Integration packscreating an integration, or changing its typea type outside the licensed packs is refused — “Not in your licence — the Security pack is not included. Contact <portal>”; its tile in the Integrations gallery shows a lock. Existing integrations keep collecting. Core integrations are always allowed.
Flowscreating or importing a flow (datacenter and panel layouts count too)from 90 % an amber line on the flows list — “You have used 9 of 10 flows in your licence”; past the limit the new flow is refused
Elements per flowsaving a canvas (the limit is per flow)from 90 % a one-time notice; a save with more elements than the limit is refused — remove some and save again
Metric sourcesadding a metric sourcefrom 90 % a notice; past the limit the new source is refused
Catalogue itemsthe background catalogue sweepnever refused: when an organisation holds more catalogue entries than the cap, the entries discovered longest ago and not seen since are retired first (configured entries are kept); one audit entry per sweep
Nodes / node bandneverinformational only (the band above)
  • An absent limit means unlimited. Organisation → Licence and Admin → Licensing show the limits beside the counts: “Flows 9 / 10 · Elements per flow 200 · Sources 120 / 500 · Catalogue 1 800 / 2 000”.
  • A refusal answers 403 with {"error": "limit_reached", "field", "limit", "current", "contact", "message"} (or "integration_not_licensed" with the pack and type); a create at 90 % or more carries "license_warning": {"field", "limit", "current"} and is recorded once per stage in the activity log (license.warn).
  • The counts are kept in memory for a minute per organisation, so checking a limit costs at most one database statement a minute; a limit nobody’s licence sets costs nothing.

Modules: Infrastructure, APM and Data Platform

Licences are moving to modules: Infrastructure (cloud, hypervisors, network, security, hardware controllers, storage, database health, syslog and Server Vitals), APM (Prometheus, SigNoz, OpenTelemetry, Zipkin, Dynatrace, Sentry, Elastic APM, JVM, Graylog, Elasticsearch / OpenSearch logs, Aria Operations for Logs, analytics apps, SSIS, NiFi) and the Data Platform add-on (custom SQL sources and the NetFlow warehouse). A licence without modules covers every module and refuses nothing. When a licence lists modules, a new integration of a module it does not include is refused (the gallery tile says Needs the APM module — contact …), and so are a new custom SQL source (or an edit that changes its query) and a new NetFlow warehouse without Data Platform — judged on the proxy owner’s organisation for the warehouse. Built-in SQL presets and the database health suite stay free, and integrations, sources and warehouses that already exist keep collecting. Bands are informational: Organisation → Licence and Admin → Licensing show each module’s band and count, amber from 90 % and red over the band, and never refuse.

  • Infra — distinct monitored assets with an address, once each, plus every powered-on VM even without one. A baseboard controller matched to its host, a Kubernetes node on a VM, and two sources that name the same address count once; pods, powered-off VMs, stale assets and cloud resources without an address are not counted.
  • APM — catalogue services from telemetry sources (Prometheus jobs and Graylog log sources included), with service aliases applied. Databases, hosts and Kubernetes services are not APM services.
  • The counts are reported to the licensing portal with every check-in (counts only — never a name or an address) and are a dash until the first check-in after the upgrade.

AI packs

A licence may include an AI pack: how many requests to the platform Claude key (the key a Topologix administrator sets, shown as “Claude (platform key)”) an organisation may make per calendar month (UTC). One action is one request to a model — a monitoring-bot answer that consults the model three times between its tool calls is three actions; the tool calls themselves, connection failures that never reached the vendor and the integration form’s “Test” are not. Requests through the organisation’s own AI model providers are counted too (the portal sees both numbers) but are never limited by the pack. A licence without a pack leaves the platform key exactly as before.

Platform actions this monthWhat happens
under 90 % of the packnothing — Organisation → AI models shows “Platform AI: 312 of 1 000 actions this month”
from 90 %the line turns amber; one license.warn audit entry per month
at the packthe line turns red; the platform key is skipped until the next month — the organisation’s own providers serve every role instead, and the monitoring bot’s model list stops offering “Claude (platform key)” and says why
at the pack, no other providerthe monitoring bot, Explain and the image-to-flow / diagram routes answer 403 {"error": "ai_pack_exhausted", "limit", "used", "month", "contact", "message"}; “Analyze with AI” shows the same sentence; background jobs (change assessment, kernel verdicts, workflows) skip quietly and the server logs it once an hour
  • Organisation → Licence and Admin → Licensing show the pack: “AI pack 1 000 actions/month · 312 used”, or “No AI pack”. Without a pack the AI models line reads “Platform AI: unmetered” (or “no pack — BYO keys only” where the platform key is not offered).
  • A role pinned to the platform key does not fall back when the pack is used up (pins never fall back) — set it to Automatic to let the organisation’s own providers take over.
  • Personal accounts (no organisation) are never limited by a pack. Counting happens in memory and is written once a minute in one database statement; the monthly totals travel with the licence check-in.

Where each person sees it

Super admin — Admin → Licensing

The install’s registration (instance id, portal URL, last check-in, last success, last error and its class, the trusted portal keys, a clock or key problem in words), the install licence, and every organisation on the install with its licence type, expiry, mode, days left and the usage counts last reported (members, integrations, flows, elements, sources, proxies, nodes, services), plus Check in now and Reset identity. Read-only otherwise: only the portal issues licences.

Organisation owner or admin — Organisation → Licence

The organisation’s own licence (type, issued, expiry) and the mode its members experience, with who to contact to extend it. Read-only.

Everyone

The banner and the top-bar chip when something needs attention. An open tab re-reads the licence every 5 minutes while it is visible, so a freeze or a renewal shows without a reload.

Operating it

Settings and logs

There is nothing to tune; the cadence and the graces come from the protocol and the licence.

  • TOPOLOGIX_PORTAL_URL seeds the portal URL on the first boot only; afterwards Admin → Licensing owns it.
  • Log lines: [license] instance <id> state=<state> portal=<url> at boot; per check-in [license] db-cost: heartbeat status=… orgs=N counts q=… budget=…, and [license] db-cost: evaluation … / notices … when a mode changes or a notice goes out.
  • The check-in runs on the primary server process only (restart guard worker_state key license.heartbeat, which also keeps the last reported counts); other processes re-read the licence every 60 seconds.

A test portal for operators

The repository ships a fake portal for trying the whole loop on a non-production install. Its key is a published TEST key — never trust it in production.

  • Other controls: /ok, /revoke (the next 3 check-ins answer “instance revoked”), /empty (the next check-in answers an empty licence set — every licence is kept), /waf (the next 3 requests answer a 403 HTML page — never counted), /down / /up (503 — the cached licences are kept), /reset.
  • npm run smoke:licensing drives register → warning → empty set → frozen → portal down → WAF page → revoke → reset end to end against it on the dev server, and restores server/.env.local afterwards.

dev fake portal

node dev/fake-portal.mjs              # 127.0.0.1:18091, registration code DEV-CODE-1
node dev/fake-portal.mjs --print-env  # the TOPOLOGIX_PORTAL_PUBLIC_KEYS line to trust its key
# then in server/.env.local: TOPOLOGIX_PORTAL_URL=http://127.0.0.1:18091 + that line, restart
curl -X POST http://127.0.0.1:18091/warn     # licences expiring in 5 days → warning
curl -X POST http://127.0.0.1:18091/expire   # expired → frozen on the next check-in
curl http://127.0.0.1:18091/state            # the licences + the usage counts it received

Good to know

  • Licences are signed by the portal and verified on every load: editing a licence row in the database does not extend it, the row is ignored.
  • Licence features (integration packs, limits on flows, flow elements, servers and catalogue items) are carried in every licence and shown verbatim; this version enforces expiry, revocation and registration only.

All integrations →

See it on your own infrastructure

Book a demo and we will walk you through Topologix with your systems in mind: on our cloud, or self-hosted in your own network.