# Password Protection for markmywords This document describes the password protection feature for encrypted markdown files in markmywords. ## Overview When you encrypt a file with a password, it is automatically password-protected. Users must authenticate with the password before viewing the content in a browser. **Important**: Only encrypted files (`.md.enc`) support password protection. Regular markdown files (`.md`) are always publicly viewable. ## Security Features - **Bcrypt Hashing**: Passwords are hashed using bcrypt, a secure password hashing algorithm - **Session Management**: Once authenticated, users remain authenticated for that file in their session - **File Permissions**: Password database is stored with restricted file permissions (0600) - **No Plain Text**: Passwords are never stored in plain text - **HTTPS Ready**: Works seamlessly with HTTPS/SSL - **Encryption Compatible**: Works with encrypted files for defense-in-depth security ## Configuration ### Environment Variables ```bash # Set a strong secret key for Flask sessions (REQUIRED for production) export FLASK_SECRET_KEY="your-very-secure-random-key" # Optional: Set master admin password for programmatic file operations export MARKMYWORDS_ADMIN_PASSWORD="your-admin-password" ``` ## Using the CLI Tool The `manage_content.py` script provides encryption and password protection management. ### Encrypt a File (Automatically Protected) ```bash python manage_content.py encrypt # Example: python manage_content.py encrypt content/docs/secret-guide.md "mypassword123" ``` This encrypts the file and automatically sets password protection. The same password is used for both encryption and browser authentication. ### Remove Password Requirement (Keep Encryption) ```bash python manage_content.py unprotect # Example: python manage_content.py unprotect content/docs/secret-guide.md.enc # File stays encrypted but no password prompt in browser ``` ### List Protected Files ```bash # List all encrypted/protected files python manage_content.py list # List encrypted files in a directory python manage_content.py list content/docs/ ``` ### Check Protection Status ```bash python manage_content.py status # Example: python manage_content.py status content/docs/secret-guide.md.enc # Output shows: Encrypted: Yes, Protected: Yes ``` ## Encrypted Files with Automatic Protection When you encrypt a file, password protection is automatic: ```bash # Encrypt a file - automatically sets password protection python manage_content.py encrypt content/secret.md "mypassword" # In browser: # 1. User navigates to file # 2. User sees password prompt (same password as encryption) # 3. User enters password # 4. File is decrypted and displayed with full markdown support ``` The same password is used for both encryption and browser authentication. ## Using the API ### Authenticate for an Encrypted File ```bash curl -X POST http://localhost:5000/api/auth/docs/secret-guide.md.enc \ -d "password=mypassword123" # Response: # {"success": true, "redirect": "/view/docs/secret-guide.md.enc"} ``` After successful authentication, the password is stored in the session and used to decrypt the file for display. ## Password Database Passwords are stored in `/config/page_passwords.json` with the following structure: ```json { "content/path/to/file.md": { "protected": true, "password_hash": "$2b$12$...", "created_at": "2024-01-15T10:30:00.000000" }, "content/path/to/encrypted.md.enc": { "encrypted": true, "protected": true, "password_hash": "$2b$12$...", "encrypted_at": "2024-01-15T10:30:00.000000", "created_at": "2024-01-15T10:30:00.000000" } } ``` **Important**: This file should be backed up and kept secure. The password hashes cannot be reversed, but the file itself should have restricted access. ## How It Works 1. **User Requests File**: User navigates to a protected file 2. **Protection Check**: Application checks if file is password protected 3. **Password Prompt**: If protected and user not authenticated, show password form 4. **Authentication**: User enters password 5. **Verification**: Password is checked against the stored bcrypt hash 6. **Session Storage**: On success, file authentication is stored in user's session 7. **Content Display**: Protected file content is displayed 8. **Session Expiry**: Authentication expires when user's session expires (typically when browser is closed) ## Use Cases - **Sensitive Documentation**: Encrypt internal documentation - **Private Notes**: Keep personal notes encrypted and password-protected - **Confidential Information**: Encrypt security guidelines, API keys, or business secrets - **Draft Content**: Encrypt unfinished or embargoed content with password protection - **Temporary Public Access**: Use `unprotect` to share encrypted content without password requirement ## Best Practices 1. **Strong Passwords**: Use passwords with at least 8 characters including mixed case and numbers 2. **Unique Passwords**: Use different passwords for different files 3. **Regular Backups**: Backup the password database 4. **Secure Secret Key**: Set a strong `FLASK_SECRET_KEY` environment variable 5. **HTTPS**: Always use HTTPS in production 6. **Share Carefully**: Share passwords through secure channels only 7. **Monitor Access**: Check logs for authentication attempts ## Troubleshooting ### "Invalid password" error repeatedly - Check that the password is exactly correct (case-sensitive) - Verify the file is actually protected: `python manage_content.py status content/path/to/file.md` ### Session expires too quickly - The session expires based on Flask's session cookie settings - For persistent authentication longer than the browser session, consider implementing "Remember Me" functionality ### Lost access to protected file - If you lose the password, you must unprotect the file using the CLI: ```bash python manage_content.py unprotect content/path/to/file.md ``` - Then set a new password if desired ### Password database corruption - If `/config/page_passwords.json` becomes corrupted, delete it and recreate protections: ```bash rm /config/page_passwords.json python manage_content.py protect content/path/to/file.md ``` ## Security Considerations - **Never** share passwords via email or unencrypted channels - **Always** use HTTPS in production - **Regularly** audit which files are protected - **Securely** delete the password database when no longer needed - **Use** strong, random passwords generated by a password manager - **Backup** the password database in a secure location ## Future Enhancements Potential future features: - Per-user authentication and roles - IP whitelisting for protected files - Audit logging of access attempts - Time-limited access links - Integration with external authentication systems (LDAP, OAuth, SAML)