⭐ GitHub: github.com/grloper/NoMorePwn-Password-Manager · open source (MIT) · by @grloper
grloper / NoMorePwn-Password-Manager
NoMorePwn local desktop vault, password history/generator and browser login capture; installed integration needs configuration
NoMorePwn
A local desktop password vault with groups, history, a password generator and browser login capture. Built with Python, PySide6, SQLite and a Chromium/Firefox extension. Browser autofill is not implemented.
Use cases
Organize local credentials into groups, generate passwords, review credential history, or capture a login into an unlocked desktop vault. The screenshots and tests use fictional accounts in disposable vaults.
Password and note fields use authenticated AES-GCM encryption. Service names, usernames and group metadata remain plaintext in SQLite. Password derivation uses Argon2id, with a PBKDF2 fallback. These implementation choices have not received an independent security audit.
Releases and install (Windows)
Download the latest pre-release, v1.0.27: Setup.exe · portable.exe · SHA256SUMS.txt
Windows builds are published on the Releases page. Each release has three assets:
-
NoMorePwn-<version>-Setup.exe: installer (Start-menu shortcut, optional launch at sign-in, uninstaller; no admin rights required). -
NoMorePwn-<version>-portable.exe: single-file portable build. -
SHA256SUMS.txt: SHA-256 checksums of…
Do you still store your passwords in a notepad? I used to. A text file, no encryption, sitting on the same machine as everything else. It worked until it obviously didn't. NoMorePwn is the vault I built to replace it: a file on your machine, code you can read, no account, no server, no rent.
Try it now: download the v1.0.27 installer or portable build from GitHub Releases, open it, and create a test vault. No account, nothing to sign up for.
One licensing note: the repository is released under the MIT License, so you can read, reuse and modify it under the terms of the LICENSE file.
A real capture of the app's own UI. I drove the real controller offscreen with a throwaway vault in a temp directory and obviously fake entries (example.com, demo-user). No real vault or password was used. The "security score" on the dashboard looks like that because every fake account has no MFA flag.
What it is
A PySide6 desktop app with a single SQLite vault file. It has groups, credential history, a password generator, a security dashboard, and backup and restore. No browser extension, on purpose: the tool is going truly offline, so passwords get in through a local file you choose, or by typing them in.
What the cryptography does
I did not write any primitives. The code uses the cryptography package's AES-GCM and argon2-cffi for key derivation. What I did write is the glue, and the glue is where mistakes live, so here is exactly what it does:
- A master password plus a random 16-byte salt goes through Argon2id (time cost 3, 64 MiB, parallelism 4). If
argon2-cffiis missing it falls back to PBKDF2-SHA256 with 600,000 iterations. The KDF name and parameters are stored with the vault, and they are bounds-checked before any derivation runs so a hostile vault file cannot make the app burn unbounded memory. - Password and note fields are sealed with AES-256-GCM, a fresh random 96-bit nonce each time.
- Each ciphertext carries additional authenticated data naming its row and field, so a valid blob copied into another row fails to decrypt.
- The derived key is only in memory while the vault is unlocked.
That card comes from docs/AUDIT.md, which is my own review: I read the code, built it from a clean venv, ran the tests and the app. It found no critical or high issues in the vault design and one medium issue that I fixed (copied passwords were eligible for Windows clipboard history and cloud clipboard). It also lists the medium issues that are still open, and they are the part to read carefully:
- Service names, usernames and group names are plaintext in SQLite.
- There is no unlock rate limit, so offline guessing against a stolen vault file depends entirely on your master password (minimum length is 10).
- The KDF parameters stored in the vault are not themselves authenticated. A writer could cause an unlock failure, not a key disclosure.
- The master password is not Unicode-normalized. Normalizing it now would break existing vaults, so I have not changed it.
- Installers are unsigned and dependencies are version ranges, not hash-locked.
- Python keeps secrets in immutable objects, so the app cannot erase them from memory, and nothing here defends against malware running as your user.
The clipboard
Copied passwords are cleared after 20 seconds, but only if the clipboard still holds the value I copied, so I do not wipe something you copied afterwards. The review found that copies were still eligible for Windows clipboard history and cloud clipboard, so copies now carry the Windows hints that exclude them (best-effort: apps that ignore the hints can still read the clipboard while it holds the value, and other platforms ignore them). A copied secret is also wiped when the app quits.
Why not just use 1Password?
Fair question, and an honest answer: 1Password is good. It has never lost a customer vault, and its encryption is serious. If you want the polished product, use it.
Here is what you are buying: closed code you cannot read, a subscription with no free plan (Individual is $3.99 a month at renewal after the March 2026 price rise), and a vault that lives behind their account. Their newer audit reports now sit behind a request gate instead of open downloads. You are trusting their white paper and their auditors, not code you can inspect.
NoMorePwn is the opposite bet: a file on your machine, code you can read, no account, no server, no rent. The breach check uses the same Have I Been Pwned data their Watchtower uses. The difference is not the data, it is who holds your vault.
| Notepad | 1Password | NoMorePwn | |
|---|---|---|---|
| Local file | Yes | No | Yes |
| Code you can read | Yes | No | Yes |
| Account required | No | Yes | No |
| Subscription | No | Yes | No |
The extension is being removed, on purpose
An earlier version had a browser extension that auto-imported credentials. That was the wrong feature for this tool, so it is being removed, with no checkbox to bring it back. NoMorePwn is going truly offline: passwords get in through a local file you choose, or by typing them in. Nothing phones home except the breach check you ask for, and that sends only the first five characters of a hash.
How I tested it, and what that does and does not show
For this post I ran the Python suite from a clean checkout of main: python -m unittest discover -s tests with a temporary NOMOREPWN_DATA and the offscreen Qt platform ran 304 tests, all OK, with 11 skipped (Linux or optional dependencies). The browser end-to-end scripts, which drive a real isolated Chromium against local login fixtures, were not re-run for this post, so I am not quoting numbers for them. All fixtures use fictional credentials.
That is component-chain evidence. It is not proof that an installed browser, a registered native host and the packaged app work together on your machine, and the README says that registration of installed browsers, Firefox runtime behaviour and packaged installers remain unverified.
Releases
Windows builds (installer, portable exe, and a SHA256SUMS file) are published as GitHub releases. They are not code-signed, so SmartScreen will likely warn. The checksum file sits in the same release as the binaries, so it catches a corrupted download but not a compromised release. The in-app updater only follows the release GitHub marks as Latest, checks a checksum, refuses downgrades and asks you first. Code signing and a signed checksum are not done.
Run it from source
python -m venv .venv # activate the environment for your shell python -m pip install -r requirements.txt python -m nomorepwn_app Set NOMOREPWN_DATA to a disposable directory first, before the process starts. Network features (update check, optional breach check) exist; the breach check sends only a 5-character SHA-1 prefix, and only when you ask for it.
Why publish something unfinished
Security tools improve under adversarial reading. The repository has a threat model that lists adversaries and says "No" where the answer is no. I would rather have someone find the gap in my reasoning now.
The honest part
- Installers are unsigned and dependencies are version ranges, not hash-locked.
- Service names, usernames and group names are plaintext in SQLite.
- No independent security audit.
- No unlock rate limit, so offline guessing against a stolen vault file depends entirely on your master password.
Try it, and help
Please review docs/THREAT_MODEL.md against the code and tell me where they disagree. Report vulnerabilities privately through the Security tab of github.com/grloper/NoMorePwn-Password-Manager (use disposable vaults only, never real data). Good first contributions: signed builds, a macOS or Linux package, and fault-injection tests for backup and restore, which the project's own readiness notes call out.
What would you check first — the crypto, the import path, or the metadata?





