Overview
Version 3.1.6.5 is a stability and reliability release focused on encryption key management. It addresses several critical issues that could cause empty passwords, HTTP 500 errors, or account lockouts — particularly for LDAP/AD environments and after admin key regeneration operations.
What's Changed
Critical Fixes
Empty passwords on recently created items
A race condition could cause the user's private_key and public_key to become desynchronized. When this happened, sharekeys for new items were encrypted with a public key that no longer matched the private key — resulting in empty passwords displayed to the user. The write order has been corrected across all key generation paths (handleUserKeys, generateOneTimeCode, password change, profile update).
If you already have affected users (can see items but passwords appear empty for recently created ones while older items still work): use the "Generate new keys" action from the Users administration page (see below).
HTTP 500 when viewing items (auto_reencryption_failed in log_system)
Decryption failures in custom fields or item data could trigger an unhandled exception and crash the entire page load. Decryption is now wrapped in try/catch: the item loads normally and a warning toast identifies which specific fields could not be decrypted.
AD/LDAP users locked out after account reactivation
When a disabled AD account was reactivated, the password hash was updated before key recovery completed. If recovery failed, subsequent logins would silently use corrupted encryption keys, causing 500 errors when accessing items. The authentication flow now only updates the password hash after successful key recovery.
Transparent recovery data not persisted
When user RSA keys were regenerated (admin password reset, recovery code, admin key regeneration), the transparent recovery fields (user_derivation_seed, private_key_backup, key_integrity_hash) were not saved to the database. This caused attemptTransparentRecovery() to fail with key_integrity_check_failed for AD/LDAP users who changed their password, ultimately disabling their account. All key regeneration paths now persist recovery data correctly.
Locked account producing no feedback
When an account was disabled, the login page showed no error message. The error response format has been fixed so users now see a clear "account is locked" notification.
Encryption Key Architecture Change
Private keys now read from user_private_keys table
All read paths for user private keys have been migrated from the teampass_users.private_key column to the teampass_user_private_keys table (filtered on is_current = 1). The private_key column in teampass_users is still written to (dual-write) for backward compatibility but is no longer the source of truth.
The upgrade script ensures the TP_USER account has its private key properly stored in user_private_keys.
New Admin Features
"Generate new keys" action in Users administration
A new option is available in the user action menu on the Users page. When triggered (with confirmation), it regenerates all sharekeys and the user's public, private, and seed keys. The user can then log in with their normal password and access all shared passwords again. Note: personal item passwords are lost when using this action — the user will be prompted to re-encrypt personal items with their old password if applicable.
On-the-fly backup comments by @guerricv in #5073
On-the-fly backups now support an optional comment field. You can add a comment when creating a backup and edit comments on existing backups from the backup list. Comments are stored in the .meta.json sidecar file and displayed in the backup table.
phpseclib v3 Migration Fix
The sharekey migration from phpseclib v2 to v3 had two issues:
- Updated sharekeys kept their old encryption_version=1 instead of being marked as v3
- Migration could be marked as complete before all sharekeys were actually migrated
Both are fixed. A new CLI repair script is available for users with inconsistent migration state:
php scripts/repair_phpseclib_migration.php --help
Other Changes
- API key regenerated during key regeneration: The API key in the api table was encrypted with the old public key and became undecryptable after key regeneration. It is now automatically regenerated.
- "Generate API key" button moved to the user Profile page.
- "Sync LDAP password" button removed from the user menu (no longer needed).
- Private key decryption failure: instead of a 500 error or misleading "bad credentials" message, users now see a clear toast: "Unable to decrypt your encryption keys. Please contact your administrator to regenerate your keys."
- Personal items preserved during admin key regeneration: personal item sharekeys are no longer deleted when an admin regenerates a user's keys.
- Missing fields in users table fixed in fresh install step 5.
- Fix PHP Warning on Tasks page: undefined receiver_name by @guerricv in #5068
- Fix console error when pressing Enter in Users search by @guerricv in #5074
Repair Scripts
Two CLI scripts are included for diagnosing and repairing existing issues:
Script: scripts/fix_integrity_hash.php
Purpose: Repairs users with missing or incorrect key_integrity_hash / transparent recovery data
────────────────────────────────────────
Script: scripts/repair_phpseclib_migration.php
Purpose: Diagnoses and fixes users with incomplete phpseclib v3 sharekey migration
Run with --help for usage details.
Upgrade Notes
- Run the standard upgrade process (/install/upgrade.php). The upgrade script will automatically migrate the TP_USER private key to the user_private_keys table.
- If you have users reporting empty passwords or 500 errors, use the "Generate new keys" action from the Users administration page as a first resolution step.
- If you upgraded from a version prior to 3.1.6 and some users still have phpseclib v1 sharekeys, run php scripts/repair_phpseclib_migration.php --dry-run to check and --fix to repair.
- For AD/LDAP environments: users who were previously locked out with auto_reencryption_critical_failure can be repaired by running php scripts/fix_integrity_hash.php.
Full Changelog: 3.1.6.3...3.1.6.5
Last important topics
- 3.1.6.0 - Migration is forced when user is login. If you want to migrate progressively, set
FORCE_PHPSECLIBV3_MIGRATIONtoFALSE(in file./includes/config/include.php). - 3.1.5.10 - Refactor: Remove user password sanitization (see documentation)
- 3.1.5.2 - New: Personal items migration phase implemented with improved management (see documentation)
- 3.1.5.0 - New: transparent user password recovery in case of password change in external AD (please read documentation)
Important
- Requires at least
PHP 8.1 - New password library implemented, read about impacts
Languages
Please join Teampass v3 translation project on Poeditor and translate it for your language.
Installation
Follow instructions from Documentation.
Upgrade
Follow instructions from Documentation.
Ideas and comments
Are welcome ... please use Discussions.