Matches the spend capture rate check: the lease (interval - 1s) is not released, so replicas firing later in the interval skip. A restart within the interval applies config changes at the next interval; documented.
7.3 KiB
LDAP team synchronization
LDAP sync periodically reads a selected set of directory groups, creates missing LiteLLM teams, and reconciles their memberships using accounts that already exist in LiteLLM. Login continues to use your existing authentication setup.
Install the proxy dependencies with pip install 'litellm[proxy]'. A database and shared Redis are required, including when running multiple workers in one proxy. Each worker uses the existing job lock so only one worker synchronizes at a time.
general_settings:
coordination_redis:
host: os.environ/REDIS_HOST
port: os.environ/REDIS_PORT
ldap_sync:
enabled: true
server_url: ldaps://ldap.example.org:636
group_search_base: ou=groups,dc=example,dc=org
group_filter: "(cn=project-*)"
user_search_base: ou=people,dc=example,dc=org
group_id_attribute: cn
group_name_attribute: cn
member_attribute: member
user_match_attribute: mail
litellm_match_field: user_email
interval_minutes: 30
dry_run: true
litellm_settings:
default_team_params:
models: [your-approved-model]
max_budget: 100
budget_duration: 30d
The example uses anonymous LDAP reads over TLS. For a service account, add bind_dn: os.environ/LDAP_BIND_DN and bind_password: os.environ/LDAP_BIND_PASSWORD. Every enabled sync requires TLS, including anonymous reads and dry runs. Use ldaps:// or set start_tls: true with ldap://. LDAPS and StartTLS verify the server certificate, using the system trust store or the optional ca_cert_path CA bundle.
Start with dry_run: true, restart the proxy, and review the planned team creation and member additions/removals in its normal logs. Set dry_run: false and restart to apply changes. The first run starts shortly after startup and later runs start every interval_minutes, which must be at least 5. Only one replica syncs per interval: the job lock lasts the whole interval, so a restart soon after a run, for example to switch off dry_run, takes effect at the next interval rather than immediately. Logs also report matched and unmatched users and skipped groups. There is no separate sync UI or run-history table.
Identity and membership
group_id_attribute is matched exactly to LiteLLM's team_id. The default cn must be a unique, stable string across your selected groups. A group named project-alpha therefore creates or updates the team with ID project-alpha. A manually created team with that same ID is included in the sync. Matching only the display name does not adopt a different team.
group_name_attribute supplies the new team's display name. Team creation inherits default_team_params, the same way SCIM-created teams do. Existing team names, model permissions, budgets and other settings remain unchanged.
By default, member contains full user DNs. The sync reads each referenced user entry and compares its mail attribute to existing LiteLLM user_email values, ignoring email case. litellm_match_field may instead be user_id or sso_user_id, matched exactly. Set user_match_attribute to the LDAP attribute carrying the corresponding identity. Missing LiteLLM accounts are skipped and counted in the logs, then picked up by a later run after normal onboarding. Changing a user's matched LDAP attribute, such as their mail, without updating LiteLLM makes them unmatched, so the next run removes them from every synchronized team and deletes their keys for those teams. Update the matching LiteLLM field first, for example user_email through /user/update. Duplicate matches skip the affected group rather than choosing an account.
For POSIX groups, set member_attribute: memberUid. These values are looked up under user_search_base using member_lookup_attribute, which defaults to uid. Other membership attributes such as uniqueMember or roleOccupant are treated as full DNs. Only direct users are supported. Each member must be a user entry with the person, organizationalPerson, inetOrgPerson, user or posixAccount object class. Any other member, including a nested group of any class, skips its group and leaves that team unchanged. Binary group identifiers and AD ranged membership responses are also rejected.
LDAP is authoritative for the membership of every matched team, including manually added members. Retained members keep their team roles. New members receive the regular member role. The shared membership operation updates the team roster, user membership list and member budget/spend association together. Removing a member also deletes their existing keys for that team, following the same behavior as SCIM/team-member removal. User accounts and memberships in other teams are retained. Global user roles and disabled states are unchanged.
Failure behavior
A group no longer returned by LDAP leaves its team and memberships unchanged. A group that resolves to no LiteLLM users leaves a team that still has members unchanged and logs a warning, because an unreadable or misnamed membership attribute looks the same as an empty group. Set allow_empty_groups: true to let such a group remove every member and their team keys. No team or user is ever deleted, and no user is provisioned by this sync.
Failed or incomplete group searches, referrals, duplicate group IDs, invalid responses and LDAP operation exceptions abort the directory snapshot without applying it. A member DN whose entry no longer exists skips only its group, so other groups still synchronize and that team keeps its current members until the DN is removed or restored. Unreadable entries still abort the snapshot. Groups with missing, blank or multivalued IDs skip individually. Other member validation failures, such as ambiguous identities or nested groups, also skip their affected group. A membership-write failure for one valid group does not prevent other valid groups from synchronizing. A user disappearing during the membership write causes that group's transaction to make no changes. Repeated successful runs with the same roster do not rewrite it.
The LDAP identity must have permission to read every selected group, its complete membership attributes, and the user identity attributes. LDAP can omit attributes hidden by access controls just as it omits empty attributes, so the sync cannot distinguish every permission restriction from an empty group. Verify the bind account and dry-run output before enabling writes. Other permission or attribute changes can still remove some members, so re-run a dry run after changing directory access controls or group schemas.
Runs have a time budget shorter than their shared Redis lease. A directory read that exceeds it stops the LDAP reader between entries and lookups, and the run makes no changes. Once writes begin, the run checks the budget between teams and stops before the next team rather than interrupting one in progress, so one slow team can finish past the budget. Remaining teams retry at the next interval from current state. LDAP socket timeouts and server search time limits use timeout_seconds as an upper bound and are capped further for short sync intervals. If the proxy shuts down during a team's update, a removed member's key can remain usable from the auth cache until user_api_key_cache_ttl expires, the same as other key deletions. Stopping the sync (enabled: false or removing the block and restarting) leaves current teams and memberships in place.