16.1.1.6. System endpoints

The system REST API exposes the server’s configuration store and a handful of operational endpoints: the HSM unlock, an entropy source, per-token configuration tests, the rendered system documentation, and listings of configured RADIUS servers, CA connectors and nodes. See System Config for the conceptual chapter.

Most endpoints require admin authentication. Create/update and the setDefault shortcut are gated by the policy action configwrite, configread, configdelete; deletion by configwrite, configread, configdelete. The rendered documentation requires system_documentation, the HSM unlock requires set_hsm_password, and the entropy endpoint requires getrandom. GET /system/ / GET /system/<key> may be called by any authenticated user; non-admin callers only see configuration entries flagged as public.

GET /system/documentation

Render the current server configuration (system config, app config, resolvers, realms, policies, admin accounts) into a single reStructuredText document. The response is text/plain; consumers typically pipe it through Sphinx to produce a rendered status report.

Requires admin authentication and the policy action system_documentation.

Status Codes:
  • 200 OK – text/plain body containing the rendered document.

GET /system/gpgkeys

Return the public GPG keys held in the directory configured via PI_GNUPG_HOME. These keys are used to verify imported token seed files.

Requires admin authentication.

Status Codes:
  • 200 OK – dict of public GPG keys (keyed by fingerprint) in result.value.

GET /system/(key)
GET /system/

Return system configuration.

Without a path component, returns all configuration entries as a dictionary. With <key> in the path, returns only that entry’s value.

Both admins and authenticated users may call this endpoint, but non-admins only see configuration entries that are flagged as public. Querying a non-public key as a regular user returns null. Admin access is gated by the policy action configwrite, configread, configdelete when at least one configread policy is defined.

Parameters:
  • key – optional path component, the configuration key to fetch.

Request Headers:
  • PI-Authorization – authentication token.

Status Codes:
  • 200 OK – configuration dictionary or single value in result.value.

Example request:

GET /system/ HTTP/1.1
Host: example.com
Accept: application/json

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": {
      "AutoResync": "False",
      "splitAtSign": "True",
      "PrependPin": "True",
      "DefaultCountWindow": "10"
    }
  },
  "version": "privacyIDEA unknown"
}

Example request (single key):

GET /system/totp.hashlib HTTP/1.1
Host: example.com
Accept: application/json

Example response (single key):

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": "sha1"
  },
  "version": "privacyIDEA unknown"
}
POST /system/setConfig

Set one or more system configuration entries. The body is a flat dictionary of keyname: value pairs; per-entry metadata may be supplied using keyname.type and keyname.desc companion keys. Setting keyname.type to password causes the value to be stored encrypted.

Requires admin authentication and the policy action configwrite, configread, configdelete.

JSON Parameters:
  • <keyname> – configuration value to store.

  • <keyname>.type – optional type tag — int, string, text, or password (encrypted at rest).

  • <keyname>.desc – optional human-readable description.

Request Headers:
  • PI-Authorization – authentication token.

Status Codes:
  • 200 OK – dict mapping each set key to "insert" or "update" in result.value.

Example request:

POST /system/setConfig HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "splitAtSign": true,
  "totp.hashlib": "sha1",
  "totp.hashlib.desc": "The hash algorithm used for TOTP tokens"
}

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": {
      "splitAtSign": "update",
      "totp.hashlib": "update"
    }
  },
  "version": "privacyIDEA unknown"
}
POST /system/setDefault

Set token default values that apply to newly enrolled tokens. Existing tokens are not affected. At least one of the listed parameters must be supplied.

Requires admin authentication and the policy action configwrite, configread, configdelete.

JSON Parameters:
  • DefaultMaxFailCount – maximum allowed authentication failures before a token is locked.

  • DefaultSyncWindow – synchronization window size.

  • DefaultCountWindow – counter window size.

  • DefaultOtpLen – OTP value length (typically 6 or 8).

  • DefaultResetFailCount – whether the fail counter should be reset on successful authentication (True / False).

Status Codes:
  • 200 OK – dict mapping each updated key to "insert" or "update" in result.value.

  • 400 Bad Request – none of the listed parameters was supplied.

DELETE /system/(key)

Delete a system configuration entry.

Requires admin authentication and the policy action configwrite, configread, configdelete.

Parameters:
  • key – path component, the configuration key to delete.

Status Codes:
  • 200 OK – True on success in result.value.

POST /system/hsm

Provide the password for the configured security module (HSM / PKCS#11) so privacyIDEA can unlock its encryption key. Until the HSM is unlocked, tokens whose secrets are protected by the HSM cannot be used.

Requires admin authentication and the policy action set_hsm_password.

JSON Parameters:
  • password – the security-module password (required).

Status Codes:
  • 200 OK – {"is_ready": <bool>} in result.value; True if the HSM is now unlocked.

GET /system/hsm

Return the readiness state of the configured security module.

Requires admin authentication.

Status Codes:
  • 200 OK – {"is_ready": <bool>} in result.value; True if the HSM is unlocked and usable.

GET /system/random

Return cryptographically random bytes from the server’s RNG. Clients use this when seeding tokens (CLI initializing a Yubikey, WebUI creating a token secret) so that the secret material is sourced from a trusted, centrally audited generator — and, when privacyIDEA is configured against an HSM, from the HSM’s hardware RNG.

Requires admin authentication and the policy action getrandom.

Query Parameters:
  • len – number of random bytes to return; default 20.

  • encode – encoding for the result — hex (default) or b64.

Status Codes:
  • 200 OK – the encoded random bytes in result.value.

POST /system/test/(tokentype)

Probe the server-side configuration of a given token type by invoking that token class’ test_config classmethod with the request body. The shape of the body and what the test actually does are token-type specific (the email token, for example, sends a test email through the configured SMTP server).

Requires admin authentication and the policy action configwrite, configread, configdelete.

Parameters:
  • tokentype – path component, the token type to test (e.g. email).

Jsonparam:

any token-type-specific configuration fields.

Status Codes:
  • 200 OK – True if the configuration is valid, False otherwise; detail.message carries a human-readable description.

GET /system/names/radius

Return the identifiers of all configured RADIUS servers (only the names, not the full configurations). The WebUI uses this when enrolling a RADIUS token to populate the server-selection dropdown.

Requires the enrollment policy action enrollRADIUS.

Status Codes:
  • 200 OK – list of RADIUS-server identifiers in result.value.

GET /system/names/caconnector

Return the configured CA connectors with their templates but without their connection configuration (no secrets are included). The WebUI uses this when enrolling a certificate token to populate the CA-selection dropdown and the per-CA template list.

Requires the enrollment policy action enrollCERTIFICATE.

Status Codes:
  • 200 OK – list of CA-connector dictionaries (name, type, templates) in result.value.

GET /system/nodes

Return the privacyIDEA nodes declared in the server configuration. Each entry carries the node name and uuid and is used by multi-node features (per-node periodic tasks, per-node resolver visibility, …).

Requires admin authentication.

Request Headers:
  • PI-Authorization – authentication token.

Status Codes:
  • 200 OK – list of {"name", "uuid"} dictionaries in result.value.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": [
      {"name": "node1", "uuid": "12345678-1234-1234-1234-1234567890ab"},
      {"name": "node2", "uuid": "12345678-4321-1234-1234-1234567890ac"}
    ]
  },
  "version": "privacyIDEA unknown"
}

Added in version 3.10: Return node information with names and UUIDs

GET /system/health/certificates

Return certificate expiry information for the certificates privacyIDEA depends on. Several sources are inspected automatically:

  • LDAP resolvers - the TLS server certificate of every resolver whose URI uses ldaps:// or that has START_TLS enabled (source = ldap-resolver).

  • Keycloak resolvers - the TLS server certificate of the resolver’s base_url when it is an https:// endpoint (source = keycloak-resolver).

  • EntraID resolvers - the client-certificate credential used to authenticate against Entra, for resolvers configured with client_credential_type = certificate. The certificate is read from the resolver’s private_key_file; only its validity period is inspected (source = entraid-resolver). The Microsoft endpoints themselves are not probed, as their certificates are managed by Microsoft.

In addition, the privacyIDEA server certificate can be reported via two admin-configured pi.cfg keys (both opt-in, see Metrics and certificate health):

  • PI_SERVER_CERT_FILE - path to a cert file on disk to read.

  • PI_HEALTH_CERT_PROBES - list of {"host": "...", "port": int} dicts naming TLS endpoints to probe over the network.

Probe targets are never derived from request headers - that would be an SSRF primitive.

The result is cached for PI_CERT_CHECK_CACHE_SECONDS seconds (default 3600). Pass ?refresh=1 to bypass the cache.

Each entry carries source, name, host, tls_mode, the certificate subject / issuer / not_after / days_remaining, an error message (or null), checked_at (ISO 8601, when the list was probed rather than when it was served from the cache), and a status of ok (>30 days), warning (<=30 days), critical (<=7 days), expired (<=0 days), or error (the certificate could not be read).

Query Parameters:
  • refresh – If truthy, bypass the cache and re-check.

Response JSON Object:
  • value (list) – List of certificate status entries (see above).

Request Headers:
  • PI-Authorization – The authorization token

GET /system/health/resolver_timing

Return rolling resolver-operation timing aggregates per resolver and op.

Reads pre-aggregated counters/buckets stored by privacyidea.lib.metrics.observe() calls wrapped around every UserIdResolver public method (get_user_info, get_user_list, check_pass, add_user, update_user, delete_user, get_user_id, get_username). Covers all resolver types uniformly (LDAP, SQL, HTTP, EntraID, Keycloak, passwd).

The values are aggregated across all privacyIDEA nodes and 5-minute windows that fall within the requested window. Each entry carries labels (resolver, resolver_type, op), the count of observations, avg / p50 / p95 / max durations in seconds, and buckets (ordered [upper_bound_seconds, cumulative_count] pairs). The buckets let a client roll several operations of one resolver into a single, correct combined percentile instead of taking the maximum of the per-op p95s. p50 / p95 are approximated from the histogram buckets and so round up to the next bucket boundary; they are null when the quantile lies in the open-ended (> 5 s) tail.

Query Parameters:
  • since_seconds – Window length in seconds. Default 3600 (1h).

Response JSON Object:
  • value (list) – One entry per (resolver, resolver_type, op) triple (see above for the per-entry fields).

Request Headers:
  • PI-Authorization – The authorization token

GET /system/health/notification_delivery

Return rolling delivery counters and latency for the three notification channels (push, SMS, email).

The result is a dict with one key per channel (push, sms, email) plus the echoed since_seconds. Each channel folds rows by its primary label dimension:

  • push: gateway (the SMS gateway identifier configured for Firebase)

  • sms: gateway (the SMS gateway identifier)

  • email: identifier (the SMTP server identifier)

Each channel value is a list of per-target entries, sorted by total volume. An entry carries key (the gateway/identifier), the outcome counts ok / failed / error / total, and - when latency was recorded - avg / p50 / p95 / max (seconds) plus duration_count.

Query Parameters:
  • since_seconds – Window length in seconds. Default 3600 (1h).

Response JSON Object:
  • value (dict) – {"push": [...], "sms": [...], "email": [...], "since_seconds": <int>} (see above for the per-entry fields).

Request Headers:
  • PI-Authorization – The authorization token

DELETE /system/user-cache

Flush the user cache. The user cache speeds up repeated user-store lookups; flushing it forces the next lookups to hit the backing resolvers again. Useful after a resolver configuration change.

Requires admin authentication.

Request Headers:
  • PI-Authorization – authentication token.

Status Codes:
  • 200 OK – {"status": True, "deleted": <n>, "flushed_resolvers": <m>} in result.value, where n is the number of rows removed from the usercache table and m the number of resolvers whose entries were dropped from the Redis user cache (0 when it is not enabled). Both are reported because either store can hold entries: with Redis enabled the table is usually empty, so deleted alone would say nothing was cleared. m short of the number of configured resolvers means Redis could not be reached and entries may remain.

Example response:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "status": true,
    "value": {"status": true, "deleted": 42, "flushed_resolvers": 2}
  },
  "version": "privacyIDEA unknown"
}