Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ldaprecord Laravel Package

directorytree/ldaprecord

LdapRecord is a full-featured LDAP ORM for PHP and Laravel. It offers ActiveRecord-style models, a fluent query builder, authentication, and multi-domain connection management, making OpenLDAP and Active Directory integration simple and expressive.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. LdapRecord is an ActiveRecord-style ORM that maps LDAP directory entries onto Eloquent-shaped models, with a fluent query builder, attribute casts, relationships (group membership ↔ member), global scopes, pagination and chunking. For a Laravel product where the directory is the identity source of truth, this is a strong architectural fit: the directory layer speaks the same idioms as the rest of the app, so authorization logic ("is this user under OU=Contractors?", "is this user a member of CN=Admins?") can be expressed as scoped queries rather than a parallel integration language. Crucially, the package is split into a framework-agnostic core plus a Laravel adapter (auth guard, user provider, config publishing, DirectoryFake), which means the LDAP logic is not welded to the delivery framework.

Integration feasibility. Integration is a Composer install plus a published ldap.php config (connections, base DNs, TLS/SASL, failover). Models are hand-written classes per object class (User, Group, OU) with casts for AD-specific encodings. Authentication plugs into Laravel's guard system. Testing is the notable strength for a TPM: DirectoryFake plus auth events and the Ldap::DEBUG_* constant set (v3.7.2) let us assert login and provisioning behavior in CI without a domain controller, removing the usual "QA needs VPN and a service account" bottleneck.

Technical risk. The risks are domain risks, not library-shape risks:

  • No transactionality. LDAP writes are not atomic across objects. Joiner/mover/leaver automation that touches user, group and OU entries can half-succeed. We need idempotency and compensating logic in our own service layer.
  • Correctness of authorization queries. Recent patches are a tell: v4.1.1 fixed query cache keys to include search bases and controls (PR #822) and fixed {base} substitution in whereMemberOf. A stale or mis-scoped cache key here is a security defect, not a performance defect. Any caching of directory-derived permissions must be reviewed as authz code.
  • Write safety. v4.1.1 also fixes "prevent deleting populated groups when detaching relationships" (PR #827) and redacts password arguments from exception traces (PR #778). Both are adoption gates for automated writes, and both were only fixed very recently — evidence that write paths are younger and less exercised than read paths.
  • Bus factor and independent verification. ~581 stars, no recorded dependents, single-vendor (DirectoryTree) stewardship, no commercial support tier. The absence of listed dependents understates real usage (the Laravel adapter is widely deployed) but it does mean we cannot lean on a visible ecosystem for peer review.
  • Release-date signal. The most recent release is dated 2026-10-08, i.e. the project is actively maintained on a roughly monthly patch cadence, with parallel support on v3 and v4 branches — good for stability, but it also means "stay on v3" is a viable short-term de-risking option.

Key questions to resolve before commit.

  1. Which directory, exactly — AD, OpenLDAP, or both — and is it the same instance per environment? Behavior diverges (AD whereMemberOf, timestamp formats, objectGUID/SID binary handling, password-change protocol).
  2. Read-only or read-write in phase one? Automated writes materially change the risk envelope and the review bar.
  3. Who owns directory schema and base-DN design — us or a separate identity/IT team? {base} substitution helps, but OU structure is a dependency we don't control.
  4. What is the TLS posture, and would we ever need allow_insecure_password_changes? That flag exists, which means the unsafe path is one config line away and needs an explicit decision recorded.
  5. How large are the directories, and what are the paging limits (AD default 1000)? This drives whether we need chunking everywhere and how v4.1.1's paging-control cleanup (PR #829) matters to us.
  6. What is our authz caching strategy, and can we accept eventual consistency?
  7. Do we require a support contract or SLA? If yes, this package is a build-on-library decision, not a vendor decision.
  8. Which Laravel/PHP versions must we support at launch, and does that force v3 or v4?

Integration Approach

Stack fit. The package sits inside our existing Laravel service as a library, not a service: no new runtime, no new datastore, no new deployment unit. It requires PHP 8.x with the ldap extension enabled on every app node — an infrastructure checklist item that is easy to miss in containerized environments. Laravel 11, 12 and 13 compatibility exists on both the v3 and v4 branches (v3.8.6 / v4.0.3), and PHP 8.5 deprecation fixes landed in v4.0.8, so framework currency is not a blocker.

Migration path. Three plausible entry points, in ascending cost:

  • Greenfield identity feature — lowest friction; start on v4 at >=4.1.1.
  • Replace ad-hoc ldap_* wrappers — the ORM absorbs attribute mapping, paging, error handling and DN parsing that is currently hand-rolled. insertAndGetDn / renameAndGetDn with base-DN substitution (v3.3.0) make porting legacy create/rename scripts tractable; refresh() returning false for missing entries instead of throwing changes control flow in ways our call sites must be audited for.
  • Escape a commercial IAM contract or a shadow SQL copy of the org chart — the largest scope; requires the sequencing below.

Two version decisions should be made explicitly and early:

  • Floor at v4.1.1. Anything earlier carries the group-deletion and password-in-traces defects. If we must stay on v3 for framework reasons, v3.8.6 is the last v3 line and needs a written risk acceptance.
  • Treat v3 → v4 as its own migration. There is a documented upgrade guide, but it has behavior changes (select semantics, nested filter grouping, orFilter/andFilter) that were still being corrected through v4.0.2. Do not bundle the v4 upgrade with a framework upgrade.

Compatibility notes to encode as constraints. AD objectGUID/SID serialization and UTF-8 handling were fixed in v3.5.1; 32-bit PHP timestamp handling in v4.0.4; the TLS upgrade state bug in v3.6.0. These suggest we should standardize on 64-bit PHP, UTF-8 end-to-end, and a single supported connection configuration rather than a matrix.

Sequencing (each step shippable and reversible).

  1. Spike (1–2 weeks). Read-only connection against a real directory using DirectoryFake in CI and a live DC in staging. Output: a written AD/OpenLDAP assumptions doc, base-DN inventory, and a working auth guard.
  2. Read-only authentication. AD/OpenLDAP login for an internal-only cohort behind a flag. Instrument bind failures, latency, and failover behavior.
  3. Directory-derived authorization. Group and OU queries behind global scopes, with an explicit, reviewed cache strategy and cache keys proven correct against search base and controls. This is the step that prevents building a shadow org chart in SQL.
  4. Automated writes (joiner/mover/leaver). Group membership and attribute updates only, with dry-run mode, per-operation audit logging, idempotency, and a compensating-action runbook. Do not enable relationship detach paths without reviewing #827.
  5. Self-service password change. User::changePassword() (v4.1.0, OpenLDAP Argon2 supported) behind TLS enforcement, with the allow_insecure_password_changes decision documented as an explicit "no."
  6. Legacy retirement. Port remaining Perl/PHP directory scripts; morphIntoOrFail and model-morphing (v3.4.0) cover heterogeneous object classes.

Operational Impact

Maintenance. Low code-level maintenance, moderate version-tracking effort. The library is actively patched (roughly monthly; v4.0.5 → v4.1.1 within recent history) with a parallel v3 line, so we should budget a recurring review of release notes rather than assume quiet. Ownership is a single vendor maintainer; the realistic mitigation is internal: pin a known-good version, keep our LDAP model layer thin and centralized, and avoid subclassing deep internals so an upstream break has a small blast radius. Everything LDAP-schema-specific — object classes, attribute names, base DNs, group naming conventions — is our ongoing maintenance burden, not the package's.

Support. MIT, community-supported, no SLA. Documentation at ldaprecord.com is unusually complete (per-version docs, upgrade guides, base-DN substitution, caching). Escalation for a production incident lands on our platform team. If the business requires contractual support for identity infrastructure, this is the wrong dependency — plan to own it. Conversely, "self-hosted, no per-seat license, no vendor schema lock-in" is a real cost avoidance versus a commercial IAM offering.

Scaling. The directory is the bottleneck, not PHP. Scaling concerns are:

  • Query volume. Eloquent habits transfer, which is a trap: a directory query inside a loop is a network round-trip against a domain controller. Enforce eager loading of relationships and a "no directory calls in view/render paths" rule.
  • Pagination and chunking. Large result sets require paged results; v4.1.1 fixed paging-control cleanup on early chunk termination and pagination-state reset after paginate, so pin at that floor and test early-exit paths.
  • Caching. Necessary for authz at scale, and dangerous — the v4.1.1 cache-key fix is exactly the class of bug that survives load testing and fails an audit.
  • Connections. Multiple connections and failover are supported; connection reuse and pool sizing per app worker need to be set deliberately, and connection secure state must be verified on reconnect (v3.8.3 fixed resetting that flag on close()).

Failure modes to instrument.

Failure Symptom Mitigation
DC unreachable / failover Login and authz timeouts Failover config, short timeouts, circuit breaker, cached-but-correct authz fallback with explicit staleness policy
Bind failure Login rejected for valid users BindException surfaced in the Failed auth event (v3.6.1); distinguish credential vs. connectivity in logs
TLS upgrade failure start_tls local errors Track TLS-upgraded state (v3.6.0); alert on handshake errors; never silently fall back to plaintext
Partial write User updated, group membership not Dry-run, idempotent retries, compensating runbook, per-operation audit trail
Over-broad detach Populated group deleted Pin >=4.1.1; restrict who can call relationship detach; test against a seeded group
Secret leakage Passwords in exception traces Pin >=4.1.1 (PR #778); add a log-scrubbing assertion to CI
Stale authz cache Wrong group / wrong OU scope Cache keys must include search base and controls; treat as security-reviewed code; add a regression test

Ramp-up. For an Eloquent-fluent team the API ramp is days; the LDAP ramp is weeks and is the real cost. Engineers must absorb distinguished names, search filters, OIDs and controls, paged results, AD's binary objectGUID/SID encodings, AD's 1000-object paging limit, AD timestamp epoch quirks, and password-change protocol differences between AD and OpenLDAP. Plan for at least one engineer to become the named directory owner, and front-load a written internal runbook (connection config, base DNs, object classes, read-only vs. write policies, escalation path) during the spike rather than after the first incident. DirectoryFake plus the DEBUG_* constants materially shorten this curve — use them from day one so the team learns from tests instead of from the production directory.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table