Skip to content

Password Hashing Migration Guide

Overview

This guide explains a critical change in the password hashing mechanism used in the Tracker API application. The system has been updated to use a consistent password hashing approach across all components.

Background

The application previously had inconsistencies in how passwords were handled:

  • Some components used Werkzeug's generate_password_hash and check_password_hash functions (hashes start with pbkdf2:sha256:)
  • Some production users had passwords hashed with scrypt (hashes start with scrypt:)
  • The security module used Passlib's CryptContext with bcrypt scheme (hashes start with $2b$)

This inconsistency caused the "hash could not be identified" error when running in production environments, as the hashing mechanisms were incompatible.

Changes Made

  1. Updated the User model to use the same hashing mechanism as the security module:
  2. Replaced Werkzeug's functions with Passlib's get_password_hash and verify_password
  3. This ensures consistent password handling throughout the application

  4. Modified the migration (006_update_password_hashing.py) to update existing password hashes:

  5. Identifies users with both Werkzeug-format and scrypt-format password hashes
  6. Replaces them with bcrypt hashes for a temporary default password
  7. Logs affected users for administrator reference

Impact on Users

For Administrators

  • Users with existing Werkzeug or scrypt password hashes will have their passwords reset to a default value: ChangeMe123!
  • You should notify these users that they need to reset their passwords after the migration
  • The migration will log which users were affected and what hash type they were using

For End Users

  • If you're unable to log in after this migration, your password may have been reset
  • Use the temporary password ChangeMe123! to log in
  • Change your password immediately after logging in

How to Apply the Migration

Since the application is running in Docker containers, you need to apply the migration within the Docker environment:

# For development environment
docker-compose -f compose-dev.yml exec dev alembic upgrade head

# For production environment
docker-compose exec api alembic upgrade head

Do not try to run the migration locally outside of Docker, as it will fail to connect to the database.

Verification

To verify the migration was successful:

  1. Check the application logs for any "hash could not be identified" errors
  2. Test logging in with both existing users and newly created users
  3. Ensure password reset functionality works correctly

Troubleshooting

If you encounter issues after the migration:

  1. Check the database to ensure all password hashes have been updated:
SELECT id, email, password_hash FROM users;
  • Werkzeug hashes start with pbkdf2:sha256:
  • scrypt hashes start with scrypt:
  • bcrypt hashes start with $2b$

  • If some users still have non-bcrypt hashes, you may need to manually update them:

UPDATE users SET password_hash = '[new_bcrypt_hash]' WHERE id = [user_id];
  1. If login issues persist, ensure the application is using the correct security module and that all dependencies are properly installed.