Skip to main content
By the end of this guide, you will have a Maverics Orchestrator configured as a virtual LDAP directory — authenticating LDAP bind requests against a modern cloud identity provider and returning directory data to LDAP-dependent applications, without changing the application’s LDAP configuration.
Console terminology: In the Maverics Console, the combination of applications, policies, headers, and connector bindings is managed through User Flows. In YAML, these elements are configured directly within each app’s configuration block under apps[].policies[].

What Is LDAP Provider Mode?

Many enterprise applications — especially legacy and commercial off-the-shelf (COTS) products — depend on LDAP for authentication and directory lookups. These applications perform LDAP bind operations to validate user credentials and LDAP search operations to retrieve user attributes like group memberships, email addresses, and display names. The Maverics Orchestrator’s LDAP Provider mode creates a virtual LDAP directory that presents a standard LDAP interface to these applications while sourcing identity data from modern cloud identity providers such as Azure AD, Okta, or PingFederate. Applications continue using their existing LDAP configuration — the Orchestrator handles the translation between LDAP protocol operations and cloud IdP APIs. The most common deployment pattern pairs LDAP Provider with HTTP Proxy mode in a facade architecture, where the Orchestrator handles both the browser-facing authentication (via HTTP Proxy) and the application’s backend LDAP operations (via LDAP Provider). See Step 6 for details on this pattern.

Prerequisites

  • A running Maverics Orchestrator — If you have not installed the Orchestrator yet, follow the Quick Start guide or see the installation reference.
  • An identity provider account — You need credentials for an identity provider such as Azure AD, Okta, or PingFederate. This IdP will serve as the upstream source of identity data that the Orchestrator translates into LDAP responses.
  • A target LDAP-dependent application — An application that authenticates users via LDAP bind operations or retrieves user attributes via LDAP search queries.
  • Service Extension development capability (Go) — Unlike other Orchestrator modes, the LDAP Provider requires Go-based Service Extensions for its core operations. There is no declarative-only configuration path. You will need to write Service Extensions that handle LDAP bind authentication and search queries. See Service Extensions reference.
  • Knowledge of your application’s LDAP expectations — You must know the bind DN format your application uses, the search base DN, the LDAP attributes it expects in search results (e.g., cn, sAMAccountName, memberOf), and the bind method (simple bind or SASL/NTLM).
Service Extensions are required. Every LDAP Provider integration requires Go-based Service Extensions to handle LDAP operations (bind authentication, search queries, credential lookups). The LDAP Provider cannot function without them. Plan for Service Extension development as part of your integration timeline.

Configure LDAP Provider Mode

1

Create an Orchestrator Deployment

In the Maverics Console, all configuration lives within a Deployment — a managed Orchestrator instance with its own configuration, storage provider, and signing keys. Before you can configure the LDAP Provider, you need a Deployment to hold the configuration.
  1. Log in to the Maverics Console.
  2. Navigate to Deployments in the sidebar and click Create.
  3. Enter a name for your deployment (e.g., LDAP Provider).
  4. Select a deployment provider. The Console supports several options:
    • Evaluation — Strata-managed storage, no infrastructure needed. Best for getting started.
    • AWS S3, Azure Blob Storage, or Google Cloud Storage — customer-managed cloud storage for production.
    • GitHub or GitLab — deploy bundles to a Git repository.
    • Download Only — manual bundle download for air-gapped environments.
    See Publishing Deployment Configs overview for provider setup details.
  5. Click Create.
Your new deployment opens automatically. You can now configure the LDAP Provider, identity connectors, and Service Extensions within it.
2

Enable the LDAP Provider

The LDAP Provider must be enabled and configured at the deployment level. This sets up the virtual LDAP directory server that LDAP-dependent applications will connect to.
  1. Open your deployment and click the gear icon in the sidebar to open Deployment Settings.
  2. Find the LDAP Provider section.
  3. Toggle Enable to on.
  4. Select the Protocol: ldap:// (unencrypted) or ldaps:// (TLS-encrypted). Use ldaps:// for production deployments.
  5. Set the URI — the address and port the LDAP Provider listens on (e.g., ldaps://0.0.0.0:636 for TLS on the standard LDAPS port, or ldap://0.0.0.0:389 for unencrypted).
  6. If using ldaps://, provide the TLS Certificate file path and TLS Key File path.
  7. Click Save.
The LDAP Provider Deployment Settings fields are documented in detail in the LDAP Provider reference. Use the Console UI tab there for field-by-field descriptions.
3

Connect your identity provider

An identity provider (IdP) is the service that manages your user accounts — Azure AD, Okta, Google Workspace, or an on-premises directory. Connecting the Orchestrator to your IdP tells it where to source identity data for LDAP responses.The Orchestrator uses Identity Fabric connectors to communicate with your IdP. The connector provides the upstream identity data that your Service Extensions (configured in the next steps) will translate into LDAP responses.You will need your IdP’s client ID, client secret, and discovery URL. These credentials allow the Orchestrator to query the IdP for user authentication and attribute data.
  1. Navigate to Identity Fabric in the sidebar and click Create.
  2. Select your identity provider from the list. Choose a provider-specific option (such as Okta (OIDC), Microsoft Entra ID (OIDC), or Auth0 (OIDC)) or select Generic OIDC Configuration for any OIDC-compliant provider. SAML and LDAP connector options are also available.
  3. Fill in the connector form:
FieldRequiredDescription
NameYesA friendly name for your identity provider (e.g., upstream-idp).
OIDC Well Known URLYesYour IdP’s OIDC discovery endpoint (e.g., https://your-idp.example.com/.well-known/openid-configuration).
OAuth Client IDYesThe client ID from the application you registered in your IdP for Maverics.
Client Authentication MethodYesSelect OAuth Client Secret (default) or OAuth JWT Client Authentication.
OAuth Client SecretYesThe client secret from your IdP. For production, use a secret provider.
Redirect URLsYesThe callback URL where your IdP redirects after authentication.
ScopesNoSpace-separated OIDC scopes (e.g., openid profile email).
  1. Click Save.
Not sure which connector to use? The Identity Fabric overview includes a comparison table mapping each connector to its supported protocols and use cases.
Protocol translation: The Orchestrator’s mode (LDAP Provider) determines what protocol your application speaks. The connector determines what protocol your IdP speaks. These are independent — you can connect an OIDC-only or SAML-only IdP and the Orchestrator (through your Service Extensions) will translate identity data into LDAP responses for your application. See the Identity Fabric overview for all connector types.
4

Write the authentication Service Extension

The authentication Service Extension handles LDAP bind operations. When an LDAP-dependent application sends a bind request (DN + password), this Service Extension validates the credentials against your upstream identity provider and returns success or failure.This step is unique to the LDAP Provider — other Orchestrator modes handle authentication declaratively. The LDAP Provider requires a Go Service Extension because LDAP bind semantics vary widely across applications, and the translation from LDAP bind to cloud IdP authentication (typically via OIDC Resource Owner Password Credentials grant or a direct API call) requires custom logic.Your authentication Service Extension should:
  1. Receive the bind DN and password from the LDAP client
  2. Parse the bind DN to extract the username or identifier
  3. Translate the credentials into an authentication request against the upstream IdP (e.g., ROPC grant, SCIM API, or direct API call)
  4. Return success or failure to the LDAP client
See the Service Extensions reference for the function signature, available context objects, and build instructions.
Illustrative example only. The following Service Extension is a simplified test example with hardcoded credentials. A production implementation would validate credentials against your upstream identity provider (e.g., via ROPC grant or direct API call) and retrieve user data from api.Session() or api.Cache(). See the Service Extensions reference for production patterns.
simple.go
import (
  "strings"

  "github.com/strata-io/service-extension/orchestrator"
)

// This is an example Simple Authentication Service Extension that shows a quick way
// to test a Bind request using the Simple Authentication method between the
// application and the Orchestrator. In this example, only a user with the username
// of `bob` and the password of `th3Bu!ld3R` to be authenticated.
//
// A production version of this Service Extension would typically retrieve the
// password hash of the user from either `api.Cache` or `api.Session` and would
// compute the hash of the password received and compare it with the one stored. The
// user is typically a short-lived / one-time user created by an Orchestrator serving
// as the identity-aware proxy, after the end-user has been authenticated by
// the configured IdP.
func Authenticate(api orchestrator.Orchestrator, username string, password string) (bool, error) {
  api.Logger().Debug(
    "service", "LDAP Provider",
    "extension", "Authenticate",
    "msg", "authenticating user",
    "username", username,
  )

  if strings.EqualFold(username, "bob") && password == "th3Bu!ld3R" {
    api.Logger().Debug(
      "service", "LDAP Provider",
      "extension", "Authenticate",
      "msg", "user authenticated",
      "username", username,
    )
    return true, nil
  }

  api.Logger().Debug(
    "service", "LDAP Provider",
    "extension", "Authenticate",
    "msg", "user not authenticated",
    "username", username,
  )
  return false, nil
}
  1. Open your deployment and click the gear icon to open Deployment Settings.
  2. In the LDAP Provider section, find the Authentication area.
  3. Toggle Enable Simple Auth to on.
  4. Under Authentication Service Extension, select your compiled Service Extension from the dropdown.
  5. Click Save.
5

Write the search Service Extension

The search Service Extension handles LDAP search operations. When an LDAP-dependent application sends a search request (base DN, scope, filter, requested attributes), this Service Extension translates the query into lookups against your upstream identity sources and returns matching entries in LDAP format.Your search Service Extension should:
  1. Receive the search parameters (base DN, scope, filter, requested attributes) from the LDAP client
  2. Parse the LDAP filter to determine what the application is looking for
  3. Query the upstream identity source (cloud IdP API, database, etc.) for matching users or groups
  4. Map the upstream attributes into the LDAP attribute names the application expects (e.g., cn, sAMAccountName, memberOf, mail)
  5. Return the matching entries in LDAP format
See the Service Extensions reference for the function signature, available context objects, and build instructions.
Illustrative example only. The following Service Extension returns hardcoded attributes for a test user. A production implementation would query your upstream identity provider or attribute source for real user data, typically via api.Session(), api.Cache(), or api.AttributeProvider(). See the Service Extensions reference for production patterns.
search.go
import (
  "strings"

  "github.com/strata-io/service-extension/ldap"
  "github.com/strata-io/service-extension/orchestrator"
)

// This is an example of an Search Service Extension and shows a simple way to verify
// the LDAP connection between the application and the Orchestrator. It is configured
// to return hard-coded attributes for a test user, regardless of the Search request
// received.
//
// A production version will be dependant on the application and environment; however,
// typically, attributes originate from the end-users Session and would NOT be
// hardcoded. For example, if the policy requires a user to be authenticated
// using Entra ID, then the attributes would likely come from Entra ID, and stored
// on the cache via the Orchestrator servicing as the proxy for the application.
func Search(api orchestrator.Orchestrator, dn string, filter string, reqAttrs []string) (map[string]map[string]interface{}, error) {
  api.Logger().Debug(
    "service", "LDAP Provider",
    "extension", "Search",
    "msg", "processing request",
    "user", ldap.BindDN(api.Context()),
    "dn", dn,
    "filter", filter,
    "attributes", strings.Join(reqAttrs, ","),
  )

  result := make(map[string]map[string]interface{})

  // User attributes would typically originate from the users Session and would NOT
  // be hardcoded. For example, if the policy requires a user to be authenticated
  // using Entra ID, then the attributes would likely come from Entra ID.
  userAttrs := make(map[string]interface{})
  userAttrs["Name"] = "Test User"
  userAttrs["mail"] = "[email protected]"
  userAttrs["givenName"] = "Test"
  userAttrs["sn"] = "User"

  result["CN=Test,CN=Domain Users,CN=Users,DC=acme,DC=local"] = userAttrs

  api.Logger().Debug(
    "service", "LDAP Provider",
    "extension", "Search",
    "msg", "request processed",
    "dn", dn,
    "filter", filter,
    "attributes", strings.Join(reqAttrs, ","),
  )

  return result, nil
}
  1. Open your deployment and click the gear icon to open Deployment Settings.
  2. In the LDAP Provider section, find the Search area.
  3. Under Search Service Extension, select your compiled Service Extension from the dropdown.
  4. Click Save.
6

Configure the facade pattern (optional)

The most common LDAP Provider deployment pairs it with HTTP Proxy mode in a facade (or “sandwich”) pattern. In this architecture, the application sits between two Orchestrator roles:
  • HTTP Proxy handles browser-facing authentication — intercepting HTTP requests, redirecting users to a cloud IdP for modern authentication (MFA, conditional access), and injecting identity headers or stuffing login forms
  • LDAP Provider handles the application’s backend LDAP operations — authenticating bind requests and serving search results from the same cloud IdP
This pattern lets you modernize the full authentication stack for LDAP-dependent applications without changing any application code.To set up the facade pattern:
  1. Configure an HTTP Proxy application for the web tier — follow the HTTP Proxy Auth guide to set up reverse proxy authentication with header injection or form-stuffing.
  2. Configure the LDAP Provider (this guide) for the backend tier — the same Orchestrator instance or a separate one handles the application’s LDAP bind and search requests.
  3. Add a shared cache if running separate Orchestrator instances — when the HTTP Proxy and LDAP Provider run as separate Orchestrator instances (the most common facade deployment), they need a shared cache so that one-time credentials generated by the proxy Orchestrator can be validated by the LDAP Provider Orchestrator.
The facade can be deployed as a single Orchestrator running both HTTP Proxy and LDAP Provider modes, two separate Orchestrator instances, or groups of Orchestrators for high-availability deployments. When both modes run on a single Orchestrator instance, the local in-memory cache is sufficient.
See the LDAP Provider reference — Pairing with HTTP Proxy for the complete architecture diagram, credential delivery methods, and shared cache requirements.
7

Publish and test

With the LDAP Provider enabled, identity connector configured, and Service Extensions in place, you are ready to publish and test the virtual LDAP directory.
  1. At the bottom of the deployment Settings page, click Publish Preview in the sticky footer bar.
  2. In the Deployment Manager dialog, review the configuration diff to verify your changes.
  3. Optionally add a revision note describing what changed (e.g., “Initial LDAP Provider setup”).
  4. Click Publish to deploy the configuration bundle to your storage provider.
  5. The Orchestrator detects the new bundle on its next poll cycle and applies the configuration automatically.
See Publishing Deployment Configs overview for details on the publishing lifecycle, revision history, and bundle verification.
Test the LDAP connection:Point your LDAP client application at the Orchestrator’s LDAP endpoint and verify the full flow:
  1. Test connectivity — Use an LDAP client tool (such as ldapsearch or Apache Directory Studio) to connect to the Orchestrator’s LDAP URI and verify the connection is accepted.
ldapsearch -H ldaps://your-orchestrator.example.com:636 -x -b "dc=example,dc=com" -s base "(objectClass=*)"
  1. Test bind authentication — Attempt a bind operation with valid credentials to verify the authentication Service Extension is working.
ldapsearch -H ldaps://your-orchestrator.example.com:636 -x -D "[email protected],dc=example,dc=com" -W -b "dc=example,dc=com" "([email protected])"
  1. Test search — After a successful bind, perform a search to verify the search Service Extension returns the expected attributes.
  2. Test with your application — Point your LDAP-dependent application at the Orchestrator’s LDAP endpoint and walk through a full authentication and data retrieval flow.
Success! Your Maverics Orchestrator is acting as a virtual LDAP directory — authenticating LDAP bind requests against your cloud identity provider and serving directory data to your LDAP-dependent application. The application continues using its existing LDAP configuration while the actual identity data comes from your modern cloud IdP.

What’s Next