Directory Connector

The Generic REST Directory Connector lets OneLogin import users from any external system that exposes a REST API returning JSON, without a purpose-built connector. You describe the API in a JSON template: how to authenticate, which requests to make, and how to read users from the responses. The directory service runs that template to import users into OneLogin.

Examples

See the examples section for step-by-step walkthroughs of configuring the connector for specific source systems.

How it works

Each Generic REST directory holds two JSON templates and a set of secrets:

ItemPurpose
Authorization templateDeclares the authentication methods used to call the remote API, including OAuth 2.0 flows (authorization code and client credentials). Multiple authorizations can be defined for a single directory.
Communication templateDeclares the HTTP requests used for each import action and how to interpret the responses.
TokensSecret values, such as API keys, that templates reference instead of embedding. Tokens and OAuth access and refresh tokens are stored encrypted.

OAuth access tokens are refreshed automatically. If a response matches an oauth_refresh status code defined in the template, the connector refreshes the token and retries the request.

Import actions

The import section of the communication template defines one request per action:

ActionRequiredDescription
usersYesReturns the users to import.
users_countYesReturns the total number of users.
user_idsYesReturns the unique identifiers of the users.
fieldsYesReturns the user fields the remote system supports.
optional_fieldsNoReturns additional fields that can optionally be mapped.

An optional export section can define requests for creating and updating users and for searching by email in the remote system.

User attributes

Imported users must provide external_id, firstname and lastname. At least one of email or username is also needed. The following attributes are optional: phone, company, title, department, notes and distinguished_name. A status attribute can also be supplied to update the OneLogin user status (active, unactivated or suspended).

Attribute mapping and custom fields

Attributes from the source system can also be mapped to any custom fields created in your OneLogin tenant to extend the user schema, not just the standard OneLogin attributes. You control how attributes flow from the source system to OneLogin in the attribute mapping section of the connector. This section becomes available after the connector has successfully connected to the source system.

Request configuration

Each request can specify the following properties.

PropertyDescription
base_url, pathThe target of the request. These can be set once at the import level and inherited by individual actions.
full_urlAn absolute URL that takes precedence over base_url and path. Used for next-page links.
methodThe HTTP method.
headers, isolated_headersRequest headers.
parameters, bodyQuery string parameters and request body.
skip_empty_body_propertiesOmit body properties that resolve to empty values.
page_increasePagination by incrementing a parameter or body value.
replayRepeat the request until a condition is met. See Pagination.
responsesHow to validate, extract and filter the response.

A request can also be an ordered list of requests, where later requests use the output of earlier ones through previous_response.

Template variables

Templates use {$variable} placeholders, resolved when each request runs. Values can be read with dotted paths or bracketed keys, for example {$tokens.api_key}. The following root variables are available:

VariableContents
tokensThe directory’s stored token values.
oauth.access_tokensThe current OAuth access tokens, keyed by authorization name.
responsesResponses from earlier requests in a chained request.
paginationThe current pagination state.
userThe user being processed, for export requests.
user_statusThe OneLogin user status values active, unactivated and suspended.

Response handling

The responses block of a request controls how the result is read:

  • extract selects the data to return. See How extraction works.
  • validate checks that the response contains what is expected.
  • filters excludes records from the result.
  • Per-status handlers, keyed by HTTP status code, apply different extract, validate and filters settings depending on the response code.
  • oauth_refresh lists the status codes that trigger an OAuth token refresh.

How extraction works

After each request, the connector parses the JSON response and applies the extract configuration to turn it into the data the import needs, such as a list of users with named attributes. The names you give each extracted property are the source attribute names you later map to OneLogin attributes in the connector’s attribute mapping.

Extraction types

Each extracted property is an object containing one or more extraction types. At least one is required.

TypeDescription
*by_pathReads a value from the response using a dot-separated path.
*rawUses a fixed string, which can contain template variables.
*constantUses a fixed value, typically as a fallback.
#mapOptional. Translates the extracted value using a lookup table.

When more than one type is given, the first non-empty value wins, in the order *by_path, *raw, *constant.

Paths

A *by_path value must start with body (the JSON response body) or headers (the response headers). The rest of the path walks the JSON structure:

Path elementMeaning
nameThe property with that name.
0, 1, …The item at that position in an array.
*Every item in an array.
*fFlattens nested arrays into one array.
*lengthThe number of items in an array.

For example, body.*.custom_attributes.hr_firstname reads custom_attributes.hr_firstname from every item in a response whose body is an array.

Extracting a list of users

To extract many records, wrap the extract configuration in an array. Each extracted property is evaluated across the whole response, and the results are combined by position to build one user per item. A property that returns a single value rather than a list, such as a *raw or *constant value, is applied to every user.

"extract": [
  {
    "first_name": { "*by_path": "body.*.custom_attributes.hr_firstname" },
    "last_name":  { "*by_path": "body.*.custom_attributes.hr_lastname" },
    "staffid":    { "*by_path": "body.*.custom_attributes.hr_staff_id" },
    "managerID":  { "*by_path": "body.*.custom_attributes.hr_managerID" },
    "personal_email": { "*by_path": "body.*.custom_attributes.hr_personal_email" },
    "isManager":  { "*by_path": "body.*.custom_attributes.hr_isManager" },
    "title":      { "*by_path": "body.*.custom_attributes.hr_title" },
    "id":         { "*by_path": "body.*.id" },
    "status": {
      "*by_path": "body.*.custom_attributes.hr_user_status",
      "#map": {
        "active": "{$user_status.active}",
        "disabled": "{$user_status.suspended}",
        "terminated": "{$user_status.suspended}"
      }
    },
    "hr_driven_identity": { "*raw": "TRUE" },
    "department": {
      "*by_path": "body.*.custom_attributes.hr_department",
      "*constant": "missing"
    }
  }
]

This example shows the supported patterns:

  • Custom and nested attributes. *by_path reaches into nested objects such as custom_attributes, so provider-specific fields like hr_staff_id can be imported alongside standard ones such as id. Extracted properties can be mapped to custom fields in OneLogin. See Attribute mapping and custom fields.
  • Value translation with #map. The status property converts the source system’s values into OneLogin user statuses. Values with no entry in the map pass through unchanged, and numeric strings in the result are converted to numbers.
  • Fixed values with *raw. hr_driven_identity is set to TRUE for every imported user.
  • Fallback values with *constant. If a user has no hr_department value, department is set to missing instead of being left empty.

Limits

Extract configurations can be nested up to 50 levels deep. Extract configurations that don’t specify at least one extraction type, or that use a *by_path value without a body or headers prefix, are rejected when the template is validated. Required user attributes that extraction doesn’t provide cause the import to fail with an invalid data error.

Pagination

Two pagination styles are supported. They cannot be combined on a single request.

  • page_increase increments a query parameter or body value on each call, for APIs that use page numbers or offsets.
  • replay repeats the request using while or until (exactly one) to decide when to stop. Combined with full_url, this follows cursor and next-link style pagination, such as the @odata.nextLink used by Microsoft Graph and Entra ID.

For next-link pagination, the connector only follows full_url values that use http or https and match the origin (scheme, host and port) of the configured base_url, so credentials are never sent to another host. Redirects are not followed. Replay stops with an error after 10,000 iterations rather than importing truncated data. replay is not supported inside a chained request.

Import behavior

SettingValue
Import strategyBulk
Page size20
Maximum users per import11,000
DeprovisioningNot performed
Group importNot supported

Imports run in the background and can be started manually or on a schedule. See Scheduled imports.

Scheduled imports

The connector can import users automatically on a schedule. When adding the connector to your tenant, set the Automatic import CRON definition setting to a standard cron expression that defines how often and at what time the import runs. Leave it blank to turn automatic import off. The schedule can be changed or cleared later by editing the connector.

For example:

Cron expressionRuns
0 * * * *Every hour, on the hour
*/30 * * * *Every 30 minutes
0 2 * * *Every day at 02:00
0 6 * * 1-5At 06:00, Monday to Friday

The schedule is validated when you save it:

  • It must be a valid cron expression, with a precision of one minute at most. Second-level schedules are rejected.
  • The interval between runs must be at least 5 minutes.

A scheduled run works the same way as a manual import. It does not run when:

  • The connector is disabled. Disabling it removes the schedule, and the schedule is registered again when the connector is re-enabled.
  • No schedule is set.
  • A previous import is still in progress. The run is skipped, and the next scheduled time starts a new import.

Choose an interval longer than a typical import duration, so that runs don’t regularly overlap and get skipped.

Security

  • Token values and OAuth tokens are encrypted at rest and are excluded from logs.
  • Plain http is only followed for pagination URLs on the same origin as the configured base_url. Use https endpoints for production integrations.