⭐ GitHub: github.com/grloper/NoMorePwn-Password-Manager · open source (MIT) · by @grloper

GitHub logo 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.

Actual desktop vault with fictional credentials

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…

NoMorePwn banner: shield logo, tagline "A local password vault you can read, review and try to break", chips for Python and PySide6, AES-256-GCM and Argon2id, pre-release, no independent audit, open source (MIT)

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.

NoMorePwn demo: unlock screen, typing a master password, vault list with three items, security dashboard, password generator

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.

The vault view: grouped fictional items, detail pane showing a masked password and a strength meter

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-cffi is 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.

Security at a glance: audited facts (Argon2id parameters, AES-256-GCM with row-bound AAD, local socket with per-install token, clipboard hygiene, dependency audit) next to the open medium gaps and what is not done yet

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.

The password generator screen with a generated fictional password, a strength meter and length and character class controls

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?