šŸ”Œ Lumos Connector API

Introduction

The Lumos Connector API is a standardized interface for Identity and Access Management (IAM) operations across various third-party systems. It enables seamless integration between Lumos and external applications by providing a consistent set of operations calledĀ capabilities.

Each integration (referred to as a "connector") implements these capabilities to work with different third-party API providers, focusing primarily on:

  • User access management
  • User activity monitoring

Core Components

Connectors

A connector is a specialized library that acts as a bridge between Lumos and third-party applications. It handles:

  • Translation of Lumos requests into app-specific API calls
  • Conversion of app-specific responses into standardized Lumos formats
  • Authentication and authorization flows
  • Data format transformations

Capabilities

Capabilities are standardized operations that each connector can implement. They provide:

  • Consistent interfaces across different connectors
  • Predictable behavior patterns
  • Standardized error handling
  • Unified data structures

Data Model

Accounts

Accounts represent individual users or service accounts within a system.

They serve as the primary entities for access management and support lifecycle operations such as creation, activation, deactivation, and deletion.

Accounts can be associated with multiple entitlements and are typically identified by a unique account ID within the system.

Entitlements

Entitlements represent a permission or capability that can be granted to user accounts, such as an access level.

They define specific permissions, access rights, or memberships and are always associated with a resource, which may be global or specific.

Entitlements are categorized byĀ entitlement_typeĀ (e.g., roles, permissions, group memberships) and have defined constraints for minimum and maximum assignments.

The naming of entitlements may vary, such as using "membership" for group associations.

Resources

Resources represent entities within an application that can be accessed or managed.

They are identified by a uniqueĀ resource_typeĀ within each app and include a global resource (represented by an empty string) for top-level entities.

Resources can represent hierarchical structures, such as Workspaces containing Users and Groups, and serve as the context for entitlement assignments.

The usage of Resource IDs depends on the specific hierarchy, with an empty string for global resources and specific IDs (e.g., Workspace ID) for nested resources.

Associations

Associations define relationships from accounts to entitlements (which are resource specific).

They follow a hierarchical structure of Account -> Entitlement -> Resource, with no direct account-to-resource associations allowed.

Associations enable flexible access control models.

Note: The specific structure and use of resources and entitlements may vary depending on the integrated system's architecture and access model.

How to Use This API

  1. Discover available connectors
  2. Learn about a specific connector
  3. Configure a connector
  4. (optional) Authenticate with OAuth
  5. Read data from the connected tenant
  6. Write (update) data in the connected tenant

Authenticating with a Connector

The Credentials Model

A single connection to an app may require more than one credential. A connector might, for example, use OAuth for the app's REST API and a separate SCIM token for user provisioning.

To support this, every connector declares the full set of credentials it accepts. Each credential has:

  • A stable credential ID unique within the app (e.g. lucid_oauth, lucid_scim)
  • An authentication model describing its shape (OAuth, token, basic, JWT, and so on)
  • Setup instructions shown to the person configuring the connection
  • An optional flag, for credentials the connector can operate without (usually at a reduced scope)

Requests then carry a credentials array, where each entry is tagged with the ID it was declared under:

{
  "credentials": [
    {
      "id": "lucid_oauth",
      "oauth": { "access_token": "..." }
    },
    {
      "id": "lucid_scim",
      "token": { "token": "..." }
    }
  ],
  "request": {},
  "settings": { "team_id": "123456" }
}

The key inside each entry (oauth, token, basic, jwt, service_account, key_pair, oauth_client_credentials, oauth1) matches that credential's authentication model.

Legacy single-credential connectors. Older connectors accept exactly one credential and receive it on a single auth object instead of the credentials array. Both shapes are supported, a connector's schema (below) tells you which one it uses.

Authentication Models

Authentication modelRequest keyTypical use
OAuth 2.0oauthAuthorization code flow (3-legged)
OAuth 2.0 Client Credentialsoauth_client_credentialsMachine-to-machine (2-legged)
OAuth 1.0oauth1Legacy OAuth 1.0a APIs
TokentokenAPI keys and bearer tokens
Basic AuthbasicUsername and password
JWTjwtJWT-based auth
Service Accountservice_accountService account key files
Key Pairkey_pairPublic/private key pairs (e.g. Snowflake)

OAuth-based Authentication

The API supports two OAuth flow types. When a connector declares more than one OAuth credential, pass credential_id on each OAuth request so the connector knows which credential the request applies to.

Authorization Code Flow (3-legged OAuth)

Requires a multi-step flow:

  1. Authorization URL
  • Call get_authorization_url to start the OAuth flow
  • Redirect user to the returned authorization URL
  1. Handle Callback
  • Process the OAuth callback using handle_authorization_callback
  • Receive access and refresh tokens
  1. Token Management
  • Use refresh_access_token to maintain valid access
  • Store refresh tokens securely

Client Credentials Flow (2-legged OAuth)

Suitable for machine-to-machine authentication:

  1. Direct Token Request
  • Call handle_client_credentials_request with client credentials
  • Receive access token (and optionally refresh token)
  1. Token Management
  • Use refresh_access_token to maintain valid access (if refresh tokens are supported)
  • Store tokens securely

The flow type is configured per credential and determines which capabilities are available. Both flows support customizable authentication methods (Basic Auth or request body) and different request formats (JSON, form data, or query parameters).

Validation

Validation happens at two points, and the two are deliberately different.

1. Per-credential validation, while configuring

Call validate_credential_config with a single credential to check it before the connection is saved. This is a fast check — it confirms the credential is well-formed (required fields present, no stray whitespace, expected prefix or length, allowed scopes are granted on an access_token, etc.) and returns customer-facing messages explaining anything that is wrong.

{
  "request": {
    "credential": {
      "id": "lucid_api_key",
      "token": { "token": "key-123456" }
    }
  },
  "settings": { "team_id": "123456" }
}

The response reports validity plus any errors to display:

{
  "response": {
    "valid": false,
    "validation_errors": [
      "Invalid API key format. Lucid API keys must start with 'key-'."
    ]
  }
}

This capability is available on every connector that uses the credentials model.

2. Connection validation, against the live API

Call validate_credentials with the full set of credentials to prove they actually work:

  1. The connector makes a real, lightweight authenticated request to the app
  2. On success it returns the unique tenant ID for the authenticated organization

Authentication Schema

Each connector publishes the credentials it accepts, so a configuration UI can be built from it without app-specific knowledge.

  • info.credentials_schema — an array with one JSON Schema entry per credential the connector accepts. Each entry carries:
    • id — the credential ID to send back in the credentials array
    • description — markdown setup instructions for the customer
    • x-optional — whether the connector can run without this credential
    • x-credential-type — the authentication model, and therefore the request key to nest the payload under (oauth, token, …)
    • properties, required and field_order — the credential's fields, their order, and which are secret or hidden
  • info.authentication_schema — used only by legacy single-credential connectors, and empty for connectors using the credentials model. Where it is populated, credentials_schema is empty, and vice versa — so you can use whichever is non-empty to detect which shape a connector uses.

The connector's OpenAPI document (from app_info) carries the same per-credential schemas under components.securitySchemes, keyed by credential ID, each with an additional x-credential-name display label. It additionally exposes info.x-allowed-credentials: the list of credential-ID combinations that form a valid connection. For example:

"x-allowed-credentials": [
  ["lucid_oauth", "lucid_scim"],
  ["lucid_oauth", "lucid_scim", "lucid_api_key"]
]

This connector can be configured either with OAuth plus a SCIM token, or with those two plus an optional API key that unlocks license entitlements. Any combination not listed is not a valid configuration.

Pagination

Lumos connectors implement a standardized pagination mechanism to handle large datasets efficiently. The pagination system uses opaque tokens to maintain state across requests.

How Pagination Works

  1. Request FormatĀ Every request can include an optionalĀ pageĀ parameter:
{
     "page": {
       "token": string,  // Optional: opaque token from previous response
       "size": number    // Optional: number of items per page
     }
   }

  1. Response FormatĀ Paginated responses include aĀ pageĀ field:
 {
     "response": T[],    // Array of items
     "page": {
       "token": string,  // Token for the next page
       "size": number    // Items per page
     }
   }

Using Pagination

  1. Initial Request
  • Make the first request without a page token
  • Optionally specify a page size
  1. Subsequent Requests
  • Include theĀ tokenĀ from the previous response
  • Keep the same page size for consistency
  1. End of Data
  • When there's no more data, the response won't include a page token

Example Flow

// First request
POST /connectors/pagerduty/list_accounts
{
  "page": { "size": 100 }
}

// Response
{
  "response": [...],
  "page": {
    "token": "eyJwYWdlIjogMn0=",
    "size": 100
  }
}

// Next request
POST /connectors/pagerduty/list_accounts
{
  "page": {
    "token": "eyJwYWdlIjogMn0=",
    "size": 100
  }
}

Implementation Notes

  • Page tokens are opaque and should be treated as black boxes
  • Tokens may encode various information (page numbers, cursors, etc.)
  • The same page size should be used throughout a pagination sequence
  • Invalid or expired tokens will result in an error response