[ Switch to styled version → ]


← Docs index

Identity & SSO

This document describes integration with external identity providers (IDPs) for centralized authentication. It covers supported providers, configuration, JWT validation, JWKS caching, external IDs, and directory sync.

Overview

Enterprise networks can integrate with external identity providers (IDPs) to centralize authentication. Agents can present tokens from an organization's IDP, such as OIDC, SAML, Entra ID, LDAP, or a custom webhook. The registry validates these tokens before granting access.

Identity integration is configured per-network. Each network can have its own IDP configuration.

Supported providers

Configuration

Configure an identity provider with the `set_idp_config` protocol command.

{
  "command": "set_idp_config",
  "type": "oidc",
  "url": "https://accounts.example.com/.well-known/openid-configuration",
  "client_id": "pilot-network-prod",
  "admin_token": "your-admin-token"
}

The IDP configuration is stored in the registry and persists across restarts. The IDP can also be set through a blueprint using the `identity_provider` field.

To query the current configuration:

{
  "command": "get_idp_config",
  "admin_token": "your-admin-token"
}

An audit event (idp.configured) is emitted when the IDP is set or changed.

JWT validation

The registry includes built-in JWT validation supporting two algorithms:

Validate a token with the `validate_token` protocol command.

{
  "command": "validate_token",
  "token": "eyJhbGciOiJSUzI1NiIs...",
  "admin_token": "your-admin-token"
}

The command returns `valid` (boolean), `claims` (the decoded JWT claims if valid), or `error` (a string describing the validation failure).

The validator checks the following claims:

JWKS caching

For RS256 tokens, the registry fetches the provider’s JSON Web Key Set (JWKS) to obtain public keys for signature verification. JWKS responses are cached.

If the JWKS endpoint is unreachable and the cache has expired, validation fails. The registry does not fall back to accepting unverified tokens.

Security

The validator enforces the expected algorithm based on configuration to prevent algorithm confusion attacks. The `alg` header in the JWT must match the configured algorithm.

A 60-second clock skew tolerance is applied to all time-based claims (exp, nbf, iat) to accommodate minor clock differences between the IDP and the registry.

Webhook identity

For systems that do not support OIDC or SAML, a webhook identity provider can be configured. The registry sends the agent’s credentials to an HTTP endpoint, which returns an approval or rejection.

{
  "command": "set_idp_config",
  "type": "webhook",
  "url": "https://auth.example.com/verify-agent",
  "admin_token": "your-admin-token"
}

The endpoint receives a POST with the agent’s identity information and must return a JSON response indicating authorization status.

External IDs

Agents can be mapped to external identity systems using external IDs.

{
  "command": "set_external_id",
  "node_id": 5,
  "external_id": "[email protected]",
  "admin_token": "your-admin-token"
}

{
  "command": "get_identity",
  "node_id": 5,
  "admin_token": "your-admin-token"
}

External IDs are free-form strings, such as email addresses, UPNs, or LDAP DNs. They are stored in the registry and included in audit events. An `identity.external_id_set` audit event is emitted on change.

Directory sync

Directory sync pushes entries from an external directory to the registry, managing network members.

The sync operation is performed with the `directory_sync` command.

{
  "command": "directory_sync",
  "network_id": 1,
  "entries": [
    {
      "external_id": "[email protected]",
      "node_id": 5,
      "role": "admin",
      "tags": ["frontend", "us-east"]
    },
    {
      "external_id": "[email protected]",
      "node_id": 8,
      "role": "member"
    }
  ],
  "remove_unlisted": true,
  "admin_token": "your-admin-token"
}

The sync operation performs the following actions:

Directory sync supports role pre-assignment. When a new member is added through sync, they receive their assigned role immediately.

The sync status can be queried.

{
  "command": "get_directory_status",
  "network_id": 1,
  "admin_token": "your-admin-token"
}

The command returns the last sync timestamp, number of entries processed, and any errors. A `directory.synced` audit event is emitted after each sync.

Related