Netmon Docs · API Reference

Super-Adminv7.0.20

The most privileged administrative surfaces of the appliance — directory (LDAP / Active Directory) integration, the out-of-band operating-system upgrade flow, and the approval queue for dynamically-registered OAuth clients.

Nothing on this page is routine: wiring the appliance to a directory changes who can log in, the OS-upgrade endpoints hand the machine to an out-of-band assistant, and the client-approval queue decides which self-registered OAuth clients may complete an authorization flow.

These endpoints belong to the system functional area; an MCP or OAuth token needs the mcp:system scope, and the calling user needs the permission shown on each endpoint. Most endpoints here require permission:sa (super-admin); the OAuth client-approval endpoints require the broader permission:system.

Two cross-cutting points apply to the whole chapter:

LDAP / Active Directory

These endpoints configure directory-backed authentication: the bind connection to your LDAP or Active Directory server, a connection test that can also discover groups, the mapping of directory groups to appliance permissions and tag restrictions, and a manual user-sync.

The bind password is the one encrypted field in this section — see the note on Save LDAP configuration.

Get LDAP configuration

GET/api/ldap/configsa

Returns the saved LDAP configuration, or null when nothing has been saved yet. The bind password is never included in the response.

Response 200

{
  "status": 201,
  "hasError": false,
  "config": {
    "enabled": true,
    "host": "dc01.example.com",
    "port": 636,
    "use_ssl": true,
    "use_tls": false,
    "verify_tls": false,
    "base_dn": "dc=example,dc=com",
    "bind_dn": "cn=svc-netmon,ou=service,dc=example,dc=com",
    "directory_type": "active_directory",
    "expand_nested_groups": true
  }
}

Example

curl -sS https://APPLIANCE/api/ldap/config \
  -H "Authorization: Bearer $TOKEN"

Save LDAP configuration

POST/api/ldap/configsa

Creates or updates the LDAP configuration (single-row upsert). When enabled is true, an encrypted transport is mandatory: at least one of use_ssl (LDAPS) or use_tls (STARTTLS) must be set, otherwise the save is refused.

Request body

FieldTypeRequiredNotes
enabledbooleanyesMaster on/off switch for LDAP auth.
hoststringrequired if enabledServer hostname. Max 255.
portintegerno1–65535.
use_sslbooleannoUse LDAPS.
use_tlsbooleannoUse STARTTLS.
verify_tlsbooleannoVerify the server’s TLS certificate. Governs trust only, not whether encryption is required.
base_dnstringrequired if enabledSearch base. Max 512.
bind_dnstringrequired if enabledService-account DN. Max 512.
bind_passwordstringnoService-account password. Encrypted at rest; only written when present.
search_filterstringnoMax 512.
username_attributestringnoMax 64.
email_attributestringnoMax 64.
first_name_attributestringnoMax 64.
last_name_attributestringnoMax 64.
directory_typestringnoactive_directory or openldap.
timeoutintegerno1–60 seconds.
fallback_to_localbooleannoAllow local-account login if LDAP is unreachable.
auto_provisionbooleannoCreate local user rows for directory users on first login.
expand_nested_groupsbooleannoResolve transitive (nested) group membership.
Encrypted field

bind_password is write-only. It is encrypted before storage and never returned by Get LDAP configuration. Omit it on a save to leave the stored password unchanged; only send it when you intend to set a new password.

Response 200

{ "status": 201, "hasError": false, "message": "LDAP configuration saved" }

Errors

StatusBodyWhen
200{"status":false,"hasError":true,"message":"Enable SSL (LDAPS) or STARTTLS — LDAP authentication requires an encrypted connection."}enabled is true but neither use_ssl nor use_tls is set.

Example

curl -sS -X POST https://APPLIANCE/api/ldap/config \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"enabled":true,"host":"dc01.example.com","port":636,"use_ssl":true,
       "base_dn":"dc=example,dc=com","bind_dn":"cn=svc-netmon,dc=example,dc=com",
       "bind_password":"s3cret","directory_type":"active_directory"}'

Test the LDAP connection

POST/api/ldap/testsa

Attempts a bind against the supplied settings and reports success plus the count and list of groups discovered. If bind_password is omitted, the stored password is reused — but only when host, port, and bind_dn exactly match the saved configuration; testing any other target requires an explicit password.

Request body

The same fields accepted by Save LDAP configuration (host, port, bind_dn, base_dn, use_ssl/use_tls, bind_password, etc.). All are read from the request as-is; supply enough to make a bind.

Response 200

{
  "status": 201,
  "hasError": false,
  "message": "Connected successfully",
  "groups_found": 42,
  "groups": ["CN=Netmon Admins,OU=Groups,DC=example,DC=com"]
}

Errors

StatusBodyWhen
200{"status":false,"hasError":true,"message":"Enter the bind password to test a different server, port, or bind DN."}Password omitted while testing a target other than the saved one.
200{"status":false,"hasError":true,"message":"<bind error>"}The bind failed.

Example

curl -sS -X POST https://APPLIANCE/api/ldap/test \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"host":"dc01.example.com","port":636,"use_ssl":true,
       "bind_dn":"cn=svc-netmon,dc=example,dc=com","bind_password":"s3cret",
       "base_dn":"dc=example,dc=com"}'

Browse LDAP groups

GET/api/ldap/groupssa

Returns groups from the directory using the saved configuration, optionally filtered by a search term. Use it to populate a group picker when building mappings.

Query parameters

FieldTypeRequiredNotes
searchstringnoSubstring filter applied to group names.

Response 200

{
  "status": 201,
  "hasError": false,
  "groups": ["CN=Netmon Admins,OU=Groups,DC=example,DC=com"]
}

Example

curl -sS "https://APPLIANCE/api/ldap/groups?search=netmon" \
  -H "Authorization: Bearer $TOKEN"

List group-to-permission mappings

GET/api/ldap/mappingssa

Returns every directory-group-to-permission mapping, each resolved to its permission name and slug.

Response 200

{
  "status": 201,
  "hasError": false,
  "mappings": [
    {
      "id": 3,
      "ldap_group_dn": "CN=Netmon Admins,OU=Groups,DC=example,DC=com",
      "ldap_group_name": "Netmon Admins",
      "permission_id": 1,
      "permission_name": "Super Admin",
      "permission_slug": "sa"
    }
  ]
}

Example

curl -sS https://APPLIANCE/api/ldap/mappings \
  -H "Authorization: Bearer $TOKEN"

Create or update a mapping

POST/api/ldap/mappingssa

Maps a single directory group to a single permission. The pair (ldap_group_dn, permission_id) is unique — re-saving the same pair updates the stored group name rather than creating a duplicate.

Request body

FieldTypeRequiredNotes
ldap_group_dnstringyesGroup distinguished name. Max 512.
ldap_group_namestringnoDisplay name. Max 255.
permission_idintegeryesMust reference an existing permission.

Response 200

{
  "status": 201,
  "hasError": false,
  "mapping": {
    "id": 3,
    "ldap_group_dn": "CN=Netmon Admins,OU=Groups,DC=example,DC=com",
    "ldap_group_name": "Netmon Admins",
    "permission_id": 1
  }
}

Example

curl -sS -X POST https://APPLIANCE/api/ldap/mappings \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"ldap_group_dn":"CN=Netmon Admins,OU=Groups,DC=example,DC=com",
       "ldap_group_name":"Netmon Admins","permission_id":1}'

Replace all permissions for a group

POST/api/ldap/mappings/bulksa

Sets the complete permission set for one directory group in a single call: all existing mappings for the group DN are removed and replaced with the supplied list. Send an empty permission_ids array to clear a group’s permissions.

Request body

FieldTypeRequiredNotes
ldap_group_dnstringyesGroup DN. Max 512.
ldap_group_namestringnoDisplay name. Max 255.
permission_idsarrayyesInteger permission ids; each must exist.

Response 200

{ "status": 201, "hasError": false, "message": "Group permissions updated" }

Example

curl -sS -X POST https://APPLIANCE/api/ldap/mappings/bulk \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"ldap_group_dn":"CN=Ops,OU=Groups,DC=example,DC=com",
       "ldap_group_name":"Ops","permission_ids":[5,6,7]}'

Delete a mapping

DELETE/api/ldap/mappings/{id}sa

Removes a single group-to-permission mapping by id.

Path parameters

NameTypeNotes
idintegerMapping id from the list endpoint.

Response 200

{ "status": 201, "hasError": false, "message": "Mapping deleted" }
Destructive

This permanently removes the mapping. Directory users who relied on this group for the mapped permission lose it on their next sync or login.

Example

curl -sS -X DELETE https://APPLIANCE/api/ldap/mappings/3 \
  -H "Authorization: Bearer $TOKEN"

List group tag restrictions

GET/api/ldap/group-tagssa

Returns the device-tag restrictions attached to each directory group. A directory user inherits the tag restrictions of every group they belong to, limiting them to the matching devices.

Response 200

{
  "status": 201,
  "hasError": false,
  "tags": [
    {
      "ldap_group_dn": "CN=Site-A,OU=Groups,DC=example,DC=com",
      "tag_id": 11,
      "slug": "site-a",
      "name": "Site A"
    }
  ]
}

Example

curl -sS https://APPLIANCE/api/ldap/group-tags \
  -H "Authorization: Bearer $TOKEN"

Replace tag restrictions for a group

POST/api/ldap/group-tagssa

Sets the complete set of device-tag restrictions for one directory group: all existing tags for the group DN are removed and replaced with the supplied slugs. Send an empty tag_slugs array to clear a group’s tag restrictions (the field must still be present).

Request body

FieldTypeRequiredNotes
ldap_group_dnstringyesGroup DN. Max 512.
tag_slugsarrayyes (may be empty)Device-tag slugs; each must exist.

Response 200

{ "status": 201, "hasError": false, "message": "Group tags updated" }

Example

curl -sS -X POST https://APPLIANCE/api/ldap/group-tags \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"ldap_group_dn":"CN=Site-A,OU=Groups,DC=example,DC=com","tag_slugs":["site-a"]}'

Sync all LDAP users

POST/api/ldap/syncsa

Forces an immediate re-evaluation of every directory-backed user against the current group mappings and tag restrictions, applying permission and tag changes without waiting for each user’s next login. Takes no request body.

Response 200

{
  "status": 201,
  "hasError": false,
  "message": "Synced 18 users",
  "synced": 18,
  "errors": 0
}

Example

curl -sS -X POST https://APPLIANCE/api/ldap/sync \
  -H "Authorization: Bearer $TOKEN"

OS upgrade

These endpoints drive the out-of-band operating-system upgrade flow (Debian 11 → 12). The upgrade itself runs in a separate web interface on the appliance — these endpoints only report state, install the upgrader package bundled with the appliance release, start/stop the upgrader service, and hand back the one-time access token for its interface.

Get upgrade status

GET/api/osUpgrade/infosa

Returns a diagnostic snapshot the operator reviews before committing: the running OS codename, the installed appliance version, any PostgreSQL clusters present, and whether the out-of-band upgrader is installed, active, enabled, and available to install.

Response 200

{
  "codename": "bullseye",
  "netmon_version": "7.0.20",
  "postgres_clusters": [
    { "version": "13", "cluster": "main", "port": "5432", "status": "online", "raw": "13 main 5432 online ..." }
  ],
  "upgrader_installed": false,
  "upgrader_active": "inactive",
  "upgrader_enabled": "disabled",
  "upgrader_package_available": true
}

Example

curl -sS https://APPLIANCE/api/osUpgrade/info \
  -H "Authorization: Bearer $TOKEN"

Install the OOB upgrader

POST/api/osUpgrade/installsa

Installs the out-of-band upgrader package that ships bundled inside the appliance release. Idempotent — if the upgrader is already installed it returns immediately. Takes no request body.

Response 200

{ "ok": true }

When the upgrader is already present:

{ "ok": true, "already_installed": true }
Destructive

This installs a system package via the OS package manager. It is a privileged system change and a prerequisite for the OS upgrade flow that follows. Run it deliberately, not speculatively.

Errors

StatusBodyWhen
404{"status":404,"message":"No netmon-upgrader package is bundled with this release."}No upgrader package is staged in this build.
500{"status":500,"message":"Failed to install the netmon-upgrader package."}The package install failed.

Example

curl -sS -X POST https://APPLIANCE/api/osUpgrade/install \
  -H "Authorization: Bearer $TOKEN"

Start the OOB upgrader

POST/api/osUpgrade/startsa

Starts the out-of-band upgrader service and returns its interface URL plus a one-time access token. The token authenticates you to the upgrader’s own interface, which then owns the upgrade from there. Takes no request body.

Response 200

{
  "url": "https://APPLIANCE:7443/",
  "token": "a1b2c3d4e5f6…"
}
Destructive

Starting the upgrader begins the out-of-band OS upgrade workflow, which reboots the appliance and performs a distribution upgrade. Only start it when you are ready to upgrade the operating system.

One-time token

The token is rendered once and never persisted, logged, or returned again. Capture it from this response and open the upgrader interface immediately; if you lose it, stop and start the upgrader to mint a fresh one.

Errors

StatusBodyWhen
500{"status":500,"message":"Failed to start netmon-upgrader"}The service failed to start.
500{"status":500,"message":"Upgrader started but token file is unreadable"}The service started but the token could not be read.

Example

curl -sS -X POST https://APPLIANCE/api/osUpgrade/start \
  -H "Authorization: Bearer $TOKEN"
The full upgrade walkthrough

These endpoints only bootstrap the out-of-band assistant; the screen-by-screen upgrade itself — the checkpoint, the two reboots, and the rollback path — is documented in the System Upgrade Guide.

Stop the OOB upgrader

POST/api/osUpgrade/stopsa

Stops the out-of-band upgrader service, which also invalidates its current access token (the next start mints a new one). Use it after the upgrade completes, or to abort before any phase has run. Idempotent. Takes no request body.

Response 200

{ "ok": true }

Errors

StatusBodyWhen
500{"status":500,"message":"Failed to stop netmon-upgrader"}The service failed to stop.

Example

curl -sS -X POST https://APPLIANCE/api/osUpgrade/stop \
  -H "Authorization: Bearer $TOKEN"

OAuth client approval

OAuth clients may register themselves dynamically, but a self-registered client cannot complete an authorization flow until an operator approves it. These endpoints are the review queue: list the clients awaiting approval, approve one, or reject (delete) one.

Permission

Unlike the rest of this chapter, the client-approval endpoints require permission:system rather than permission:sa.

List pending clients

GET/api/oauth/clients/pendingsystem

Returns every dynamically-registered OAuth client still awaiting approval, oldest first.

Response 200

{
  "clients": [
    {
      "client_id": "abc123",
      "client_name": "Claude Desktop",
      "redirect_uris": ["https://client.example/callback"],
      "grant_types": ["authorization_code", "refresh_token"],
      "token_endpoint_auth_method": "none",
      "created_at": "2026-06-14T09:12:00Z"
    }
  ]
}

Example

curl -sS https://APPLIANCE/api/oauth/clients/pending \
  -H "Authorization: Bearer $TOKEN"

Approve a client

POST/api/oauth/clients/{clientId}/approvesystem

Approves a pending client so it can complete authorization flows. Idempotent — approving an already-approved client returns the current approval state without re-stamping it. The approving user’s id is recorded for audit.

Path parameters

NameTypeNotes
clientIdstringThe client’s client_id.

Response 200

{
  "client_id": "abc123",
  "approved_at": "2026-06-15T10:00:00Z",
  "approved_by_user_id": 1
}

Errors

StatusBodyWhen
404{"error":"not_found"}No client with that id.

Example

curl -sS -X POST https://APPLIANCE/api/oauth/clients/abc123/approve \
  -H "Authorization: Bearer $TOKEN"

Reject a client

DELETE/api/oauth/clients/{clientId}system

Rejects and deletes a client. Works on both pending and already-approved clients — rejecting an approved client revokes it, and its refresh-token chain is dropped with it.

Path parameters

NameTypeNotes
clientIdstringThe client’s client_id.

Response 200

{ "deleted": true }

Errors

StatusBodyWhen
404{"error":"not_found"}No client with that id.
Destructive

This permanently deletes the client and, for an approved client, revokes its tokens. Any integration using that client stops working immediately.

Example

curl -sS -X DELETE https://APPLIANCE/api/oauth/clients/abc123 \
  -H "Authorization: Bearer $TOKEN"