Skip to main content

password-key

PyPI Python CI License: MIT

Cryptographically secure passwords that are safe to paste anywhere.

Most password generators hand you k9$P@x/2' and let you discover — an hour later, three layers deep in a stack trace — that @ split your database URL, $ was expanded by your shell, and ' broke your SQL. password-key is built around one idea:

URL-safe output is the default. Letters, digits, and - _ . ~ — the only punctuation RFC 3986 guarantees is safe in a URL — and characters that also carry no special meaning in a SQL literal or a shell. At 32 characters that is still ~193 bits of entropy, far beyond any brute-force attack. The restriction buys safety and costs nothing.

The password is copied to your clipboard, never printed (terminal scrollback is a file on disk), drawn from the OS cryptographic RNG via Python's secrets module, and the whole package has zero runtime dependencies — the smallest possible supply-chain surface for a tool that generates credentials.

Install

pipx install password-key    # recommended for CLI use
# or
pip install password-key

Usage

$ password-key

  Length    : 32 characters
  Charset   : URL-safe (letters, digits, - _ . ~) — safe anywhere
  Strength  : ~193 bits of entropy (excellent)
  Clipboard : COPIED

  Paste it into your password manager now, then copy
  something harmless to clear the clipboard.

The essentials:

password-key                  # 32 chars, URL-safe → clipboard
password-key -l 48            # longer
password-key --words 6        # diceware passphrase (see below)
password-key --clear 30       # auto-clear the clipboard after 30 s
password-key --no-ambiguous   # drop 0 O 1 l I | (for reading aloud)
password-key --full           # full punctuation (see warning below)
password-key --show           # display it too (still copied)
password-key --print          # bare password on stdout, for scripts
password-key -i               # interactive menu
pwk                           # short alias for all of the above

Passphrases

$ password-key --words 6

  Words     : 6
  Charset   : 6 words, EFF Large Wordlist (URL-safe)
  Strength  : ~77 bits of entropy (strong)
  Clipboard : COPIED

Diceware passphrases from the EFF Large Wordlist (7,776 words, ~12.9 bits each) — for the secrets a human has to type or remember. The default - separator keeps even passphrases URL-safe. Six words is the EFF's recommendation; use --words 7 (~90 bits) for anything facing offline attack.

Auto-clear

$ password-key --clear 30
  ...
  Clearing clipboard in  30s  (Ctrl+C to keep it)

After the countdown, the clipboard is wiped only if it still holds the password — if you copied something else in the meantime, it is left alone.

Scripting

--print writes the bare secret to stdout and everything else to stderr, so it composes:

DB_PASSWORD=$(password-key --print)
password-key --print --count 5        # five candidates, one per line

Python API

from password_key import generate, generate_passphrase, entropy_bits, FULL

generate()                        # 32-char URL-safe password
generate(48)                      # longer
generate(20, charset=FULL)        # full punctuation
generate(exclude_ambiguous=True)  # no 0 O 1 l I |
generate_passphrase(6)            # 'correct-horse-battery-staple-...'
entropy_bits(66, 32)              # 193.42...

Everything is drawn from secrets — never random.

When you do need punctuation

Some systems mandate a symbol class. --full adds ! # $ % & ( ) * + , - . : ; < = > ? @ [ ] ^ { | } _ ~ and guarantees at least one upper, lower, digit, and symbol:

$ password-key --full

  Charset   : full punctuation — NOT safe in a DSN without percent-encoding
  WARNING   : percent-encode this before putting it in a connection string

An unencoded @ or % inside postgresql://user:PASSWORD@host/db splits the string and surfaces much later as a confusing "could not translate host name". If you must embed a --full password in a URL, percent-encode it first:

from urllib.parse import quote
quote(password, safe="")

Even --full deliberately excludes quotes, backslash, backtick, and space — they add ~0.1 bits per character and are the characters that turn a working password into an escaping bug.

Security design

Decision Why
secrets (OS CSPRNG), never random random is seeded, deterministic pseudo-randomness — unfit for credentials.
Unbiased selection secrets.choice uses rejection sampling internally; no character is ever more likely than another (verified by a chi-squared test in CI).
Clipboard, not terminal Terminal scrollback is written to disk. The secret is displayed only on explicit request or when no clipboard exists.
Zero dependencies Nothing to typosquat, nothing to compromise. Clipboard access uses the Win32 API directly (ctypes) and pbcopy / wl-copy / xclip elsewhere.
Guarded auto-clear --clear wipes the clipboard only while it still holds the generated password.
No state, no telemetry, no network Passwords are never logged, cached, or written anywhere.

Found a vulnerability? See SECURITY.md.

Windows double-click launcher

Prefer not to open a terminal? New Password.bat launches the interactive menu with a double-click. A standalone PowerShell implementation (no Python required) lives in contrib/new-password.ps1.

Contributing

Issues and PRs welcome — see CONTRIBUTING.md.

License

Built by ArcForge Labs.

MIT. The bundled EFF Large Wordlist is © the Electronic Frontier Foundation, CC BY 3.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

password_key-1.1.0.tar.gz (69.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

password_key-1.1.0-py3-none-any.whl (60.5 kB view details)

Uploaded Python 3

File details

Details for the file password_key-1.1.0.tar.gz.

File metadata

  • Download URL: password_key-1.1.0.tar.gz
  • Upload date:
  • Size: 69.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for password_key-1.1.0.tar.gz
Algorithm Hash digest
SHA256 64da632e19c5d2539d0841db4a65ecdd09a0c3253043d110c69933f4e855db40
MD5 b2629bc9245dcdc5cf40c76c34ca421c
BLAKE2b-256 b7082f9950700dd6806564c120b4616c9477a38364b35a61e5fe28825e2da962

See more details on using hashes here.

Provenance

The following attestation bundles were made for password_key-1.1.0.tar.gz:

Publisher: publish.yml on nathanramoscfa/password-key

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file password_key-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: password_key-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 60.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for password_key-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9afd014b325bb3c54c3b141de1a87e9e2c77936ffe8e65a054d8c3fedc6884d1
MD5 0cd796b548db0373c0ff225e803aefd3
BLAKE2b-256 9e753d69bfec86aa4094f780f7561c57d0b1037419bbffe587f313e217ed9a6e

See more details on using hashes here.

Provenance

The following attestation bundles were made for password_key-1.1.0-py3-none-any.whl:

Publisher: publish.yml on nathanramoscfa/password-key

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.1.2

2 files

1.1.1

2 files

This release

1.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page