Skip to content
DPicilloPublic

About

A Modern, Fast, and Cross-Platform LDAP Browser and Directory Management Tool.

Resources

Stars

22 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

15 Commits

Folders and files

Repository files navigation

🧭 LDAPilot

A modern, fast and cross-platform LDAP browser and directory administration tool for Active Directory, OpenLDAP and 389 Directory Server.

CI Latest release

Key Features β€’ Screenshots β€’ Installation β€’ Test Lab β€’ Development β€’ Changelog


πŸš€ Overview

LDAPilot is an LDAP browser and Active Directory management tool for system administrators, identity and access management engineers and developers who need a reliable, modern interface to their directory services.

It works with Active Directory (incl. Samba AD), OpenLDAP, 389 Directory Server / Red Hat Directory Server, FreeIPA and any other LDAP v3 server β€” from simple browsing to account administration, bulk changes and an AI assistant that only writes after you approve.

LDAPilot is an open-source alternative to classic LDAP clients such as Apache Directory Studio, LDAP Admin or Softerra LDAP Browser: a native desktop app (Go + React, no Electron) with a light and a dark theme, a command palette, full keyboard control and cross-platform support.

Current version: 0.5.0 β€” see the changelog.

LDAPilot Home

πŸ“Έ Screenshots

🌳 Directory Browser πŸ” Advanced Search
Directory Browser Advanced Search
πŸ€– AI Chat Assistant πŸ“– Schema Browser
AI Chat Assistant Schema Browser
πŸ“Š Reports πŸ”— New Connection
Reports New Connection

✨ Key Features

πŸ” Connections & Authentication

  • Bind methods β€” simple bind, NTLM, Kerberos / GSSAPI (password or credential cache; the logged-on user via SSPI on Windows) and SASL EXTERNAL with a client certificate
  • TLS trust per connection β€” LDAPS and StartTLS, custom CA certificates (also taken from the server), client certificates (mTLS) and certificate pinning by SHA-256 fingerprint; an unknown or changed certificate opens a trust prompt that shows the chain and the old and new fingerprints
  • Presets for Active Directory, AD Global Catalog, OpenLDAP, 389 Directory Server and FreeIPA; Test Connection reports the server type, vendor, TLS version, identity and naming contexts ("Use as base DN")
  • Read-only profiles enforced in the backend, a password prompt when no password is stored (or, per profile, on every connect), clear bind error hints (AD sub-codes such as 52e, 775), automatic reconnect with a visible "connection lost" state
  • Several directories at once β€” every tab, search result and log belongs to its connection; switch from the status bar or the palette
  • Encrypted storage (AES-256-GCM) for passwords and API keys; import / export of selected profiles without secrets, several profiles deleted at once; referral following that only sends credentials to trusted servers

🌳 Browsing

  • Virtualized tree for large directories; containers with more than 500 children open as a list
  • All naming contexts as roots β€” AD domains of the forest, DomainDnsZones / ForestDnsZones, Configuration and Schema; naming contexts on OpenLDAP and 389DS
  • Preview tabs, Back / Forward, an editable breadcrumb, a Contents list per container, bookmarks and recent entries
  • Find in Tree, Show in Tree from anywhere, drag and drop moves with confirmation, multi-select with batch actions, object statistics per container (can be stopped)
  • Undo for moves and bookmark changes from the toast, the notification bell or Ctrl+Z (10 minutes)
  • Bookmarks follow renamed and moved entries by their permanent id (objectGUID / entryUUID / nsUniqueId) and can be renamed and reordered

✏️ Entries & Attributes

  • Attribute table with schema tooltips, inline editing, MUST / MAY suggestions, SINGLE-VALUE checks and server-maintained attributes protected
  • New Entry templates per server type (AD user / group / computer / contact, LDAP and POSIX users and groups, OUs, custom classes), Copy Entry that never copies passwords or login identities, Rename, Move with a container picker, Compare
  • Binary values β€” photos (thumbnailPhoto, jpegPhoto) with preview and upload, X.509 certificates and PKCS #7 (userSMIMECertificate) decoded, hex dump for everything else, save and upload from file; objectGUID / objectSid shown readably
  • LDIF view of every entry (RFC 2849, re-importable) and Edit as LDIF: edit the entry as text, review the computed changes in a dry run (incl. rename / move from the dn: line), apply them as one atomic modify
  • Certificates show key usage, extended key usage, alternative names and an expiry warning; entries with several photos or certificates ask which one

πŸ”‘ Passwords

  • Per-connection password storage policy (GitHub issue #1): every write path that touches userPassword follows it β€” automatic (OpenLDAP: client-side {CRYPT} SHA-512-crypt; 389DS: the server hashes; AD: unicodePwd), a fixed client-side scheme, server-side hashing, or ask each time
  • Hashing schemes β€” {SSHA}, {SSHA256}, {SSHA512}, {PBKDF2-SHA256/512}, {ARGON2}, {CRYPT} SHA-256 / SHA-512-crypt and bcrypt (weak legacy schemes are marked); already hashed values are recognised and kept
  • RFC 3062 Password Modify extended operation, AD unicodePwd resets with "must change at next logon" and unlock in the same request
  • The stored scheme is read back after every write: cleartext values or hashes the server cannot verify are reported with a fix (Remove Value / Reset Password…); cleartext passwords over an unencrypted connection need an explicit confirmation (never for unicodePwd)
  • Reset Password dialog with generator, strength meter that knows the account names and the password policy, and the account options (must change, unlock, enable)

πŸ‘€ Account Status & Actions

  • One account status for AD (userAccountControl, computed lockout, fine-grained password policies), OpenLDAP ppolicy and 389DS (nsAccountLock, roles, lockout and password policies)
  • Unlock, enable / disable, must change password, password never expires, account expiry and a userAccountControl flag editor that warns when a change weakens the account
  • Status chips in the tree, results, Contents lists and tabs; an Account tab per entry
  • Reports β€” locked-out users, disabled accounts, expiring and expired passwords, never logged on, users without e-mail, password never expires / not required, admin accounts, privileged group members (nested), empty groups, POSIX users and groups, computers; results open in their own tab and export to CSV

πŸ‘₯ Group Membership

  • Effective (nested) membership in both directions with depth, paths ("via"), cycle detection and the AD primary group; AD uses the in-chain matching rule, other servers are resolved level by level
  • Add / remove members one value at a time (never rewriting the member list), Add to Group… for one or many entries, confirmation for changes that would close a cycle

πŸ—‘οΈ Deleted Objects & Recursive Delete

  • AD Deleted Objects view: restore (reanimation) or restore to another container, parents before children, with the list of attributes and memberships a tombstone lost
  • Recursive delete with descendant count β€” the tree delete control when the server has it, otherwise client-side with progress, stop and continue-on-error; naming contexts and large deletes need a typed confirmation

πŸ“¦ Bulk Changes & LDIF

  • Bulk modify from search results or a tree selection with value templates (%givenName% (%sn:lower%)), a dry run table (before β†’ after per entry), apply with progress, stop and "retry failed"
  • LDIF change files (RFC 2849: add, modify, modrdn, delete) with the same dry run β€” incl. AD uniqueness checks for sAMAccountName / userPrincipalName β€” rebasing into another container, and a run report
  • Export of an entry, a list of entries, one level or a subtree as importable LDIF or as CSV

πŸ” Search

  • Quick search by name and object type (users, contacts, groups, computers, OUs β€” per server family) and advanced search with scope, return attributes and a live-validated filter
  • Filter builder that round-trips with the filter text (incl. "does not exist" and AD bit-flag operators), RFC 4515 escaping everywhere
  • AD controls (Show Deleted, Show Recycled) and ManageDsaIT only when the server supports them; paged results, size limits and "Load all"
  • History and saved searches per connection, result columns per connection, CSV / TSV / LDIF export of the visible table
  • Results as tabs β€” keep a search or report result as its own tab (re-run, export, bulk actions) next to the live results

πŸ“– Schema, Server Info & Logs

  • Schema browser for object classes and attributes (inherited MUST / MAY, syntax, RFC 4512 definitions, aliases such as rfc822Mailbox β†’ mail)
  • Server Info with the full RootDSE (controls, extensions, naming contexts, vendor)
  • Operations log per connection and a persistent audit log of every write (old β†’ new values, secrets masked, Show History of an entry across renames)

🎨 Design & Keyboard

  • New design with a light and a dark theme (or follow the system), compact density, zoom 80–150 %
  • Command palette (Ctrl+K): find entries by name, run any command, go to a DN or LDAP URL (Ctrl+G)
  • Full keyboard control β€” every menu command and shortcut comes from one registry; Ctrl+/ lists them all
  • Every write asks before data is lost: unsaved edits are kept per tab and guarded on close and quit

πŸ€– AI Assistant

  • Chat about your directories β€” "Why can't this user log in?", "Which groups is deep.user in?", "Compare the users of both servers"; the assistant searches, counts, reads entries, resolves memberships and account states on every connected directory
  • Providers β€” any OpenAI-compatible API (OpenAI, LiteLLM, vLLM, LM Studio, Ollama /v1), native Ollama, Anthropic, and the Claude Code headless engine (claude -p with a private, per-run MCP server)
  • Model auto-detection from the provider (context window and tool support included); local models stay on your machine
  • Approvals β€” per-connection access (none / ask / read / write); every change is shown as an exact diff with decoded values and needs your approval; read-only profiles always refuse; writes are audited "via AI"
  • Privacy β€” secret attributes are never read, a redaction list for your own attributes, passwords typed into the chat are never sent, generated passwords are shown only to you; chats are stored encrypted
  • Ask AI about … any entry from its menu; the chat can be docked to the side bar or to the right of the editor

πŸ’» Installation

Pre-built Binaries

Every release has builds for all platforms, made by the CI pipeline when the release is made:

Platform File Notes
Windows (amd64) LDAPilot-windows-amd64-installer.exe or the portable LDAPilot-windows-amd64.exe Needs the WebView2 runtime (part of Windows 10/11). The builds are not code-signed, so SmartScreen may ask once ("More info" β†’ "Run anyway").
macOS (Apple silicon and Intel) LDAPilot-macos-universal.zip Unzip and move LDAPilot.app to Applications. The app is not notarized: open it the first time with right-click β†’ Open (or xattr -dr com.apple.quarantine LDAPilot.app).
Linux (amd64) LDAPilot-linux-amd64 (WebKitGTK 4.0, e.g. Ubuntu 22.04, Debian 12) or LDAPilot-linux-amd64-webkit2_41 (WebKitGTK 4.1, e.g. Ubuntu 24.04+, Debian 13+) chmod +x after the download.

SHA256SUMS.txt lists the checksums of all files.

Build from Source

Prerequisites

  • Go 1.26+
  • Node.js 22.12+ (or 20.19+; the frontend tests need 22.18+)
  • Wails CLI v2 matching go.mod: go install github.com/wailsapp/wails/v2/cmd/wails@v2.17.0
  • Linux: GTK 3 and WebKit2GTK, e.g. on Debian 13+ sudo apt install libgtk-3-dev libwebkit2gtk-4.1-dev
git clone https://github.com/DPicillo/LDAPilot.git
cd LDAPilot
scripts/build.sh                     # = wails build with version, commit and build date
scripts/build.sh -tags webkit2_41    # Linux with WebKit2GTK 4.1 (Debian 13+, Ubuntu 24.04+)

The binary is written to build/bin/. scripts/build.sh passes its extra arguments to wails build and stamps version, commit and build date, which Help β–Έ About and bug reports show (Wails builds without Go's VCS information). A plain wails build works too; its About dialog says "v0.5.0 development build".

# Windows (cross-compiled)
scripts/build.sh -platform windows/amd64

# macOS
scripts/build.sh -platform darwin/universal

πŸ§ͺ Test Lab

docker/ contains a lab with OpenLDAP, 389 Directory Server and a Samba Active Directory DC, each seeded with realistic data and the edge cases an LDAP tool has to cope with (escaped DNs, nested and circular groups, locked / disabled / expiring accounts, photos, 1,500-entry containers, deleted objects):

cd docker && docker compose up -d --build
Server Ports Base DN
OpenLDAP 389 (StartTLS), 636 (LDAPS) dc=demo,dc=ldapilot,dc=local
389 Directory Server 4389 (StartTLS), 4636 (LDAPS) dc=dirsrv,dc=ldapilot,dc=lab
Samba AD DC 2389 (StartTLS), 2636 (LDAPS), 3268 / 3269 (Global Catalog), 88 (Kerberos) DC=ad,DC=ldapilot,DC=lab

See docker/README.md for credentials, the seeded data and how to reset the lab.

πŸ› οΈ Technologies

Component Technology
Desktop Wails v2 β€” native desktop app without Electron
Backend Go with go-ldap/ldap/v3, gokrb5, the official MCP Go SDK and Anthropic Go SDK
Frontend React 19 + TypeScript 7, built with Vite 8
Styling Tailwind CSS 4 with semantic design tokens (light and dark theme)
State Zustand
UI @tanstack/react-virtual, Allotment, Lucide, react-markdown

πŸ‘¨β€πŸ’» Development

Quick Start

git clone https://github.com/DPicillo/LDAPilot.git
cd LDAPilot
WAILS_DEV_ALLOWED_HOSTS=wails.localhost wails dev -s -tags webkit2_41   # drop -tags on WebKit2GTK 4.0

This starts the app with hot reload for the frontend (Vite) and automatic recompiles of the Go backend; the frontend is also reachable in a browser at http://localhost:34115. On a fresh checkout frontend/wailsjs/ is generated by Wails (wails generate module needs an existing frontend/dist/).

Tests

go test ./...                                  # Go unit tests (no network)
cd frontend && npx tsc --noEmit -p .           # type check
node --test 'tests/*.test.ts'                  # frontend logic tests (Node 22.18+)
node --test 'tests/ai/*.test.mjs'              # AI chat reducer and helper tests

Project Structure

LDAPilot/
β”œβ”€β”€ main.go             # Wails entry point, binds the services
β”œβ”€β”€ services/           # Wails-bound service layer (connections, browser, editor, search,
β”‚                       #   export/import, bulk, schema, logs, audit, AI facade, UI)
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ ldap/           # LDAP client: connect/auth/TLS, search, CRUD, accounts, passwords,
β”‚   β”‚                   #   membership, deleted objects, schema, referrals
β”‚   β”œβ”€β”€ ai/             # AI harness: providers, agent loop, tools, permissions, encrypted chats,
β”‚   β”‚                   #   Claude Code engine and its MCP server
β”‚   β”œβ”€β”€ ldif/           # LDIF / CSV import and export, RFC 2849 change records
β”‚   β”œβ”€β”€ models/         # Data types shared with the frontend
β”‚   └── config/         # Profiles, encryption, AI config, audit log, paths
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/ # UI by feature (tree, editor, search, ai, …) and ui/ primitives
β”‚   β”‚   β”œβ”€β”€ stores/     # Zustand stores
β”‚   β”‚   β”œβ”€β”€ lib/        # Wails bindings and pure helpers
β”‚   β”‚   └── types/      # TypeScript mirrors of the Go models
β”‚   └── tests/          # node --test suites
β”œβ”€β”€ scripts/build.sh    # stamped production build
└── docker/             # test lab (OpenLDAP, 389DS, Samba AD)

Contributor notes (architecture, contracts and gotchas) are in CLAUDE.md.

πŸ“„ License

This project is licensed under the Apache License 2.0 β€” see the LICENSE file for details.


Developed with ❀️ by David Picillo

About

A Modern, Fast, and Cross-Platform LDAP Browser and Directory Management Tool.

Resources

Stars

22 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages