Self-service password change & reset for Active Directory and LDAP — written in Go.
Give users a simple, secure web interface to change or reset their directory passwords — no tickets, no scripts.
- Active Directory & LDAP Support: Works with both AD and OpenLDAP directory services
- Dual Mode Operation: Self-service password change (authenticated) and email-based password reset
- Configurable Password Policies: Enforce minimum length, numbers, symbols, uppercase, lowercase requirements
- Security First: LDAPS support, cryptographic token generation, rate limiting, no password storage
- Real-Time Validation: Client-side validation with immediate feedback on password requirements
- Accessibility Excellence: WCAG 2.2 Level AAA compliant with full keyboard navigation and screen reader support
- Modern UX: Dark mode support, adaptive density, responsive design, optimized for password managers
- Production Ready: Single binary deployment, Docker support, comprehensive logging
- Developer Friendly: Go backend, TypeScript frontend, Tailwind CSS, embedded assets
docker run -d -p 3000:3000 \
-e LDAP_SERVER=ldaps://dc1.example.com:636 \
-e LDAP_IS_AD=true \
-e LDAP_BASE_DN=DC=example,DC=com \
-e LDAP_READONLY_USER=readonly \
-e LDAP_READONLY_PASSWORD=readonly \
-e PASSWORD_RESET_ENABLED=true \
-e SMTP_HOST=smtp.gmail.com \
-e SMTP_PORT=587 \
-e [email protected] \
-e SMTP_PASSWORD=your_app_password \
-e [email protected] \
-e APP_BASE_URL=https://password.example.com \
ghcr.io/netresearch/ldap-selfservice-password-changerAccess at http://localhost:3000
Prerequisites:
- Go 1.25+
- Node.js 24+
- Corepack (
npm i -g corepack)
# Clone and build
git clone https://github.com/netresearch/ldap-selfservice-password-changer
cd ldap-selfservice-password-changer
corepack enable
pnpm install
pnpm build
# Configure (create .env.local or use flags)
cp .env.local.example .env.local
# Edit .env.local with your directory server details
# Run
./ldap-selfservice-password-changerGopherPass is configured via environment variables or command-line flags. Key settings:
LDAP_SERVER- Directory server URI (ldaps://server:636)LDAP_IS_AD- Set totruefor Active DirectoryLDAP_BASE_DN- Base DN for user searchesLDAP_READONLY_USER- Service account with read accessLDAP_READONLY_PASSWORD- Service account password
MIN_LENGTH- Minimum password length (default: 8)MIN_NUMBERS- Required numeric characters (default: 1)MIN_SYMBOLS- Required special characters (default: 1)MIN_UPPERCASE- Required uppercase letters (default: 1)MIN_LOWERCASE- Required lowercase letters (default: 1)
PASSWORD_RESET_ENABLED- Enable email-based password resetSMTP_HOST/SMTP_PORT- Mail server configurationSMTP_USERNAME/SMTP_PASSWORD- SMTP authenticationSMTP_FROM_ADDRESS- Sender email addressAPP_BASE_URL- Base URL for reset linksRESET_TOKEN_EXPIRY_MINUTES- Token validity (default: 15)RESET_RATE_LIMIT_REQUESTS- Max requests per window (default: 3)
For complete configuration options, run ./ldap-selfservice-password-changer --help
The password reset feature allows users to reset forgotten passwords via secure email-based token verification.
- Email-Based Verification: Secure tokens sent via SMTP (Google Workspace supported)
- Cryptographic Security: 32-byte tokens generated with
crypto/rand - Rate Limiting: Configurable limits prevent abuse (default: 3 requests/hour per user)
- Token Expiration: Tokens expire after 15 minutes (configurable)
- Single-Use Tokens: Tokens cannot be reused after password reset
- No User Enumeration: Generic responses prevent account discovery
- Directory Integration: Automatic email-to-username lookup
- User navigates to
/forgot-passwordand enters their email - System looks up user in directory and generates secure token
- Reset email sent with link:
https://your-domain.com/reset-password?token=XXX - User clicks link, enters new password with real-time validation
- Password updated in directory, token marked as used
Security Best Practice: Use dedicated service accounts with minimal permissions.
For Active Directory:
- Read-only account (
LDAP_READONLY_USER): Default Users group permissions - Reset account (
LDAP_RESET_USER, optional): Grant "Reset password" permission on user OU
For OpenLDAP:
# Read-only access
access to dn.subtree="ou=users,dc=example,dc=com"
by dn="cn=readonly,dc=example,dc=com" read
# Password reset access (optional dedicated account)
access to attrs=userPassword
by dn="cn=password-reset,dc=example,dc=com" write
by self write
by * auth
Strongly Recommended for Production: Use ldaps:// instead of ldap:// to encrypt credentials in transit.
# ✅ Recommended: Encrypted connection
LDAP_SERVER=ldaps://dc1.example.com:636
# ⚠️ Not recommended: Unencrypted connection (passwords visible on network)
LDAP_SERVER=ldap://dc1.example.com:389When LDAPS is Required:
- Active Directory password changes (AD protocol requirement)
- Production deployments accessible over untrusted networks
- Compliance requirements (HIPAA, PCI-DSS, SOC 2)
When plain LDAP may be acceptable:
- Internal trusted networks with network-level encryption (VPN, WireGuard)
- Development/testing environments
- Legacy systems where LDAPS deployment is not feasible
GopherPass Behavior:
- Accepts both
ldap://andldaps://connections (non-blocking) - Logs warning at startup when using unencrypted connections
- Provides visibility for security monitoring and compliance auditing
Setting up LDAPS:
- Ensure your LDAP/AD server has valid TLS certificates configured
- Use port 636 for LDAPS (vs port 389 for plain LDAP)
- Test connection:
openssl s_client -connect dc1.example.com:636
Comprehensive documentation is available in the docs/ directory:
- API Reference - JSON-RPC API specification and validation rules
- Development Guide - Setup, workflows, and troubleshooting
- Testing Guide - Testing strategies and recommendations
- Accessibility Guide - WCAG 2.2 AAA compliance and testing procedures
- Architecture - System architecture overview
For a complete overview, see the Documentation Index.
# Copy example environment
cp .env.local.example .env.local
# Edit .env.local with your directory server details
# Start development environment with Mailhog
docker compose --profile dev up
# Application: http://localhost:3000
# Mailhog UI: http://localhost:8025 (view password reset emails)corepack enable
pnpm install
cp .env.local.example .env.local
# Edit .env.local with your settings
# Run with hot-reload
pnpm devGopherPass was originally developed by Netresearch DTT GmbH for Active Directory environments and later expanded to support OpenLDAP. The project emphasizes security, accessibility, and user experience while maintaining simplicity and ease of deployment.
Contributions are welcome! Please:
- Follow Conventional Commits for commit messages
- Use
gofmtandprettierformatting standards - Ensure tests pass and add new tests for features
- Update documentation for significant changes
GopherPass is licensed under the MIT License.
Built with ❤️ by Netresearch DTT GmbH