Repository navigation
Releases: wrogistefan/desktop-2fa
Release list
desktop‑2fa v0.8.1 — Password Strength Enforcement & Vault UX Upgrade
🎉 desktop‑2fa v0.8.1 — Password Strength Enforcement & Vault UX Upgrade
This release introduces full zxcvbn-based password strength evaluation, new vault management commands, improved CLI structure, expanded documentation, and a comprehensive test suite — all while maintaining complete backward compatibility with previous versions.
🔐 New Features
zxcvbn-based password strength evaluation
- Integrated zxcvbn scoring into all vault password flows (
init,unlock,change-password) - Supports both warning-only and strict enforcement modes
- Rejects empty and whitespace-only passwords early for improved robustness
New vault management commands
d2fa vault unlock— unlock an existing vaultd2fa vault change-password— change the vault password- Introduced a dedicated vault command group for clearer CLI organization
🛠 Enhancements
- Preserved backward compatibility by mapping legacy
min_password_entropyto the new zxcvbn score threshold - Improved error handling for vault access, permission issues, and password validation flows
- Refined CLI structure and reorganized command reference
- Strengthened messaging around weak passwords and validation failures
🛡️ Alignment with Modern NIST SP 800‑63B Guidelines
This release brings Desktop‑2FA into alignment with current NIST SP 800‑63B Digital Identity Guidelines, which strongly discourage traditional entropy‑based password checks and outdated complexity rules.
NIST no longer recommends:
- forced password expiration
- composition rules (special characters, mixed case, etc.)
- short minimum lengths (the old 8‑character baseline)
- regex‑based “strength” checks
Instead, NIST explicitly recommends:
- minimum ~15‑character passwords or passphrases
- no composition rules
- no periodic rotation unless a breach occurs
- screening passwords against weak patterns, dictionary words, and leaked credentials
- evaluating password strength using real‑world predictability models, not theoretical entropy
These requirements map directly onto what zxcvbn provides:
- detection of predictable patterns (dates, names, keyboard walks, repetitions)
- dictionary and common‑password detection
- realistic entropy estimation based on real‑world attack models
- resistance to “gaming the system”
- strong support for long passphrases
- actionable feedback for users
The previous calculate_entropy() implementation could not detect predictable structures and therefore could not meet modern NIST expectations. For example, passwords like Password123! are still rated as “strong” by many entropy‑only models, while zxcvbn correctly identifies them as weak.
By integrating zxcvbn into the vault initialization and password‑change flows, Desktop‑2FA now provides:
- compliance with modern NIST guidance
- consistent UX with LocalPass
- significantly stronger protection against offline brute‑force attacks
- a better user experience that encourages long passphrases instead of artificial complexity rules
This upgrade strengthens the overall security model while remaining fully user‑friendly and avoiding unnecessary password restrictions.
📚 Documentation
- Added a comprehensive SECURITY.md covering:
- security goals
- threat model
- password strength policy
- Updated README with:
- zxcvbn documentation
- updated command tables
- links to the security model
- Added documentation update summaries and Issue #21 completion notes
🧪 Tests
- Added a full password strength test suite:
- zxcvbn evaluation
- configuration mapping
- enforcement modes
- vault flows
- CLI behavior
- edge cases
- Added vault integration tests
- Updated existing tests with improved exception assertions and typing
🧹 Chores & Build
- Added dependency:
zxcvbn-python - Bumped version to 0.8.1
- Added internal summary and completion reports for Issue #21
🧩 Compatibility
- No changes to vault format
- No API changes
- No breaking changes
- Fully compatible with 0.8.0
desktop-2fa 0.8.0 — Modular architecture & clipboard support
desktop-2fa 0.8.0 — Modular architecture, clipboard support & structured errors
This release introduces a cleaner internal architecture, unified validation logic,
full clipboard/output control, and structured JSON error responses.
✨ New CLI Options
-
--copy, -c
Copy the generated TOTP code to the clipboard and print it. -
--copy-only
Copy the generated TOTP code to the clipboard without printing it. -
--json
Output full result in JSON format (machine‑friendly). -
--raw
Output only the TOTP code (no extra text). -
--quiet
Suppress normal output (useful with--copy/--copy-onlyor scripting).
🧱 Exit Codes
Desktop‑2FA now uses centralized, documented exit codes:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Generic error |
| 2 | Invalid password |
| 3 | Entry not found |
| 4 | Vault missing |
| 5 | Clipboard unavailable |
| 6 | Invalid flag combination |
📦 JSON Error Format (--json mode)
When using --json, all errors are returned as structured JSON:
{
"error": "<error_code>",
"message": "<human-readable message>"
}Error codes
invalid_password — Invalid vault password
entry_not_found — Entry not found
vault_missing — No vault found
vault_io_error — Failed to access vault file
permission_denied — Cannot access vault directory
corrupted_vault — Vault file is corrupted
unsupported_format — Vault file format is unsupported
clipboard_unavailable — Clipboard not available on this system
🧱 Internal Improvements
Modularized CLI and internal API
Centralized exit codes via ExitCode enum
Unified validation logic between CLI and programmatic API
New ValidationError exception for cleaner error handling
CLI now translates validation errors into proper exit codes
🧪 Testing
Clipboard tests migrated from unittest → pytest
Updated validation tests to reflect new programmatic behavior
Full test suite green
📚 Documentation
Updated README, user manual, and changelog for 0.8.0
Version consistency across pyproject, package, and docs
This is a stable, production‑ready release.
Release 0.7.3
🐛 Fixed
DEF-02: PermissionDenied Not Caught During Vault Creation (HIGH)
When creating a new vault (when vault file doesn't exist), the CLI would attempt to save the vault file. If the directory was not writable, vault.save() raised PermissionDenied, but this exception was NOT caught in the "create new vault" paths, resulting in a full Python traceback.
Added try/except PermissionDenied blocks around all vault.save() calls in vault creation paths
Functions fixed:
add_entry_interactive()
list_entries() (both vault creation paths)
add_entry() (both vault creation paths)
init_vault() (already had the fix)
Users now see: Cannot access vault directory (permission denied). instead of a traceback
📚 Documentation
Updated CHANGELOG with DEF-02 fix details
Updated version to 0.7.3
[0.7.2] — Security & Reliability Patch
🛡️ Security Fixes
DEF-01: Empty Password Hard-Rejection (CRITICAL)
Empty passwords are now immediately rejected with a clear error message. Previously, empty passwords could be accepted during vault creation, bypassing entropy calculations and confirmation prompts.
Added immediate validation for empty passwords in get_password_for_vault() function
Empty passwords are rejected before any entropy calculation
Error message: Password cannot be empty.
Applies to all password input methods: interactive prompts, --password flag, and --password-file
DEF-02: PermissionError Handling (HIGH)
Permission errors are now properly distinguished from vault-not-found errors. The application no longer treats permission denied errors as missing vault files, preventing unnecessary password prompts and vault creation attempts.
Added PermissionDenied and VaultNotFound exception classes for precise error handling
Vault.load() now distinguishes between FileNotFoundError and PermissionError
Vault.save() properly handles PermissionError with user-friendly messages
On permission errors, the CLI:
Does NOT prompt for password
Does NOT attempt to create a vault
Shows: Error: Cannot access vault directory (permission denied).
No Python stack traces are shown to users
📚 Documentation
Updated RELEASE_NOTES.md with detailed security fix documentation
Updated README.md for version 0.7.2
Added password validation rules section to user manual
Added permission denied error handling documentation
🧪 Testing
Updated test_vault_load_file_not_found to expect new error message
All 187 tests pass
[0.7.1] — Security Patch
🛡️ Security Hardening
Fixed a CodeQL-reported issue where sensitive information could be exposed through printed output.
Improved output sanitization to ensure no secrets or password-related data appear in logs or CLI messages.
No functional changes.
Release 0.7.1
Release Notes for Desktop-2FA 0.7.1
Security Patch
This release is a security patch addressing a CodeQL-reported issue where sensitive information could be exposed through error messages and logging.
Security Fixes
- Clear-text Logging Prevention: Fixed an issue where exception details could be included in error messages, potentially exposing sensitive file paths or system information
- Output Sanitization: Improved error handling to ensure no secrets, passwords, or sensitive data appear in logs or CLI messages
- Bare Exception Handling: Replaced broad
except Exception:blocks with more specificexcept OSError:to reduce the risk of catching and exposing unexpected exceptions
Changes
vault.py: Removed exception message fromVaultIOErrormessages to prevent information disclosurehelpers.py: Replaced bareexcept Exception:withexcept OSError:in password file reading functions
Compatibility
- This release maintains full backward compatibility with existing vaults
- No changes to the vault file format
- No functional changes to user-facing behavior
Reference
- CodeQL Alert: Clear-text logging of sensitive information
Release Notes for Desktop-2FA 0.7.0
Vault Semantics & Deterministic UX
This release introduces explicit vault initialization semantics and deterministic rename behavior.
Key Changes
1. Explicit Vault Initialization (#5)
- Clear separation between vault creation and loading
- Always announces vault creation with message:
Vault created at <path> - No silent creation in any mode (interactive or non-interactive)
- Clean error handling for missing/invalid passwords (exits with
typer.Exit(1))
2. Safe Rename Semantics (#9)
- Duplicate detection: The
renamecommand now checks for multiple entries matching the target name before any mutation - Abort on duplicates: If multiple entries match, the command aborts with a clear error message:
Error: Multiple entries named '<name>' exist. Operation aborted. Resolve duplicates first. - No partial renames: Ensures deterministic behavior when duplicates exist
What's New
- Added
create_vault()helper function for consistent vault creation - Added
find_entries()method to Vault class for duplicate detection - Updated all vault-creating commands to use consistent messaging
- Added comprehensive regression tests for vault lifecycle and rename semantics
Documentation
- New "Vault Lifecycle" section in README
- Updated documentation for duplicate entry handling
- Clearer error messages for password-related issues
Compatibility
- This release maintains backward compatibility with existing vaults
- No changes to the vault file format
- Existing data is preserved
Testing
- 180+ tests passing
- Added regression tests for:
- Rename with duplicates (abort)
- Rename with no duplicates (success)
- Vault creation with path announcement
- Password handling in non-interactive mode
Thank You
Thanks to the community for reporting these UX issues and helping improve Desktop-2FA!
Thanks to the community for reporting these UX issues and helping improve Desktop-2FA!
**desktop‑2fa 0.6.2 — Documentation & CI Stability Hotfix**
🎉 desktop‑2fa 0.6.2 — Documentation & CI Stability Hotfix
This release delivers a set of small but important improvements that stabilize the development workflow, ensure consistent test behavior, and clarify documentation around vault compatibility after the security audit.
No functional changes were made to vault logic, cryptography, or CLI behavior.
✅ What’s Included
CI & Code Quality
- All linting issues resolved (Ruff)
- Codebase fully formatted with Black
- MyPy type checking passes cleanly
- Test suite updated and corrected where needed
→ 161 tests passing, 92% coverage
These fixes ensure that local development and GitHub Actions behave identically.
📝 Documentation Updates
- Updated
CHANGELOG.mdto reflect CI/test fixes - Clarified vault compatibility notice introduced in 0.6.0
- Version updated to 0.6.2 as defined in
pyproject.toml
🔒 Security & Stability
- No changes to:
- vault format
- cryptographic parameters
- encryption/decryption logic
- vault lifecycle behavior
- All invariants remain intact
This release is strictly a maintenance and documentation update.
🚀 Release Status
The project is fully ready for distribution:
- CI green across the board
- Tests deterministic and stable
- Documentation aligned with behavior
- Versioning consistent
📦 Next Steps
To publish the release:
-
Commit and push all changes
-
Create the Git tag:
git tag v0.6.2 git push origin v0.6.2 -
GitHub Actions will automatically build and upload the package to PyPI
desktop-2fa 0.6.0 — Vault Security Audit Complete
Overview
Version 0.6.0 marks a major milestone for desktop-2fa:
the full Vault Security Audit (Phases 1–6) is now complete.
This release stabilizes the vault subsystem, hardens all cryptographic
operations, and introduces a comprehensive, deterministic test suite
covering every critical behavior of the vault format, crypto, IO, and UX.
The project transitions from “experimental” to “auditable and stable”.
🔐 Security & Cryptography
Phase 5 — Cryptography Audit Completed
- Hardened Argon2id parameters (time_cost=4, memory_cost=128 MiB, parallelism=2)
- Verified AES-GCM usage (96-bit nonce, 256-bit key, tag validation)
- Documented KDF + encryption contract
- Ensured no insecure defaults or nonce reuse
🧪 Testing
Phase 6 — Full Test Suite Implemented
A complete pytest suite (31 tests) now covers:
- Error semantics (InvalidPassword, CorruptedVault, UnsupportedFormat, VaultIOError)
- Vault file format validation (magic header, version, salt, blob structure)
- Atomic filesystem safety (temp files, fsync, replace failures)
- UX-level destructive-action safeguards (import-vault, backup-vault)
- Cryptographic correctness (nonce length, tag verification, key length)
- Integration scenarios (round-trip, corrupted files, mixed failures)
All tests are deterministic and platform-independent.
🧱 Stability
- No changes to vault/CLI/crypto implementation were required
- All tests pass locally and in CI
- Vault subsystem is now stable, predictable, and auditable
🚀 What’s Next
Planned upcoming phases:
- Phase 7: Hypothesis property-based testing
- Phase 8: CI pipeline (pytest + coverage + mypy)
- Phase 9: Pre-release hardening (0.9.x series)
✔️ Summary
desktop-2fa 0.6.0 delivers a hardened, fully tested vault subsystem and
lays the foundation for the upcoming 0.7–0.9 stabilization cycle.
Enjoy the release!
v0.5.5 — Security fixes, clarified threat model
🔐 Security
- Removed hardcoded vault password
- Vault encryption now relies exclusively on a user‑supplied password.
- No default, embedded, or fallback passwords remain in the codebase.
- This fixes a critical security flaw present in earlier versions.
🧠 CLI & UX
- Explicit interactive mode handling
- Interactive password prompting is now a deliberate CLI decision rather than implicit TTY inference.
- This improves reliability across CI, scripting, and testing environments while preserving correct behavior in real terminals.
📚 Documentation
- Clarified security model and project scope
- Added an explicit threat model and non‑goals.
- Documented design trade‑offs and limitations.
- Clearly stated that this project is not a replacement for hardware tokens or strict device separation.
🧪 Testing
- Improved CLI test determinism by decoupling interactive behavior from environment‑specific TTY detection.
- All tests now pass reliably across platforms and execution contexts.
This release focuses on correctness, transparency, and architectural clarity rather than new features.
Users are encouraged to review the updated README to understand the intended use cases and limitations of the project.
v0.5.4
🚀 Desktop‑2FA v0.5.2 — Interactive CLI Improvements
🚀 Desktop‑2FA v0.5.2 — Interactive CLI Improvements
This release focuses on improving the CLI user experience.
The add command is now fully interactive, and the global --version flag has been added for convenience and consistency with common CLI tools.
🔧 New features
• Interactive add command
If issuer or secret is not provided, the CLI now prompts the user interactively:
- Service provider name
- TOTP secret (hidden input)
• Global --version / -V flag
You can now check the installed version using:
d2fa --version
🐛 Fixes
• Better error handling for empty or invalid TOTP secrets
• Clearer interactive prompts
• Improved CLI stability after the Pydantic v2 migration
📦 Upgrade
pip install --upgrade desktop-2fa
🙌 Thanks
Thanks to everyone testing and providing feedback — each iteration makes Desktop‑2FA a more polished, reliable, and user‑friendly desktop TOTP tool.
🚀 Desktop‑2FA v0.5.0 — Pydantic Vault Upgrade
🚀 Desktop‑2FA v0.5.0 — Pydantic Vault Upgrade
This release delivers a major internal upgrade to the vault system, bringing stronger validation, safer serialization, and long‑term maintainability.
The entire data layer has been migrated to Pydantic v2, enabling strict type safety and predictable behavior across CLI, vault operations, and TOTP generation.
🔐 Highlights
Pydantic‑Powered Vault
- Introduced new validated models:
TotpEntryVaultData
- Strong validation for:
- Base32 secrets
- TOTP period
- Digit count
- Algorithm names (
SHA1,SHA256,SHA512)
Improved CLI
- All commands now use
account_nameinstead of the oldnamefield. - Updated
codecommand replaces the previousgenerate. - Import/export logic fully aligned with the new vault format.
TOTP Generator
- Unified TOTP generation via
desktop_2fa.totp.generator.generate. - Fully RFC 6238 compliant.
- Hardened algorithm selection and input validation.
Vault Serialization
- Replaced deprecated Pydantic v1 APIs:
@validator→@field_validator.json()→.model_dump_json().parse_raw()→.model_validate_json()
- Deterministic JSON structure for export/import.
Testing & CI
- Entire test suite updated to new models.
- Achieved 100% test coverage across all modules.
- CI verified on Python 3.11 and 3.12.
- Linting, formatting, and type‑checking fully clean (Ruff, Black, MyPy).
⚠️ Breaking Changes
TokenEntryremoved → replaced byTotpEntry.entry.nameremoved → replaced byentry.account_name.- Vault JSON format updated.
- CLI command
generatereplaced bycode.
If you are upgrading from v0.4.x, please follow the upgrade guide below.
🔧 Upgrade Guide (v0.4.x → v0.5.0)
- Export your existing vault: