Modern, encrypted password manager for Linux desktops.
Rust · GTK4 · libadwaita · AES-256-GCM · Argon2id
Ashy Pass is a desktop password manager designed around GNOME-style ergonomics and modern cryptography. The 3.x series is a ground-up rewrite in Rust on top of GTK4 / libadwaita, replacing the previous Python implementation.
The on-disk vault uses AES-256-GCM authenticated encryption with Argon2id key derivation. Legacy 2.x Fernet vaults are auto-migrated on first unlock — no manual export required.
The project ships as a multi-crate workspace:
| Crate | Role |
|---|---|
ashypass-core |
Pure library: crypto, vault, importers, generators, sync, backup. No GTK. |
ashypass-app |
GTK4 / libadwaita desktop application. |
ashypass-cli |
Terminal companion sharing the same vault and keyring item. |
ashypass-native-host |
Chrome / Firefox native-messaging host for browser extensions. |
- AES-256-GCM authenticated encryption per field (password, notes, TOTP secret).
- Argon2id master verification and per-entry key derivation (
t=3, m=64 MiB, p=4by default, auto-tuned at first run). - Quick Unlock with PIN-wrapped vault-key state stored in Secret Service (GNOME Keyring / KWallet), never in plaintext settings.
- Automatic session lock with configurable idle timeout and pre-lock warning toast.
- Clipboard auto-clear after a configurable interval; only clears if the contents are still the secret you copied.
- HIBP audit with k-anonymity (only the first 5 hex digits of the SHA-1 hash are sent).
- Soft-delete trash with configurable retention; entries are recoverable until purge.
- Vault FIDO2 configuration is preserved but disabled until CTAP2 registration and assertion are fully implemented. LUKS FIDO2 enrollment remains available for external drives.
- Zero-knowledge — the master password and derived keys never leave the machine.
- Encrypted SQLite storage (rusqlite,
FK ON DELETE CASCADE). - Categories, favorites, full-text search, and per-entry tags.
- Per-entry TOTP with selectable algorithm (SHA1 / SHA256 / SHA512), digits (6 / 8), and period.
- Favicon fetcher with on-disk cache (
<host>/favicon.ico→ Googles2fallback). - One-click copy with timed auto-clear and clipboard scoping.
- Strong passwords with configurable length and character classes.
- Six-word passphrases by default from the 2,048-word BIP39 English list.
- Numeric PINs.
- Real-time strength meter (entropy-based: Weak → Very Strong).
- CSV (Chrome, Firefox, Bitwarden-compatible).
- KeePass (
.kdbx) read-only import. - 1Password export bundles.
- Aegis and andOTP JSON for TOTP, auto-tagged under category
2FA. - Native
.ashyv2 encrypted export with a complete SQLite snapshot; v1 remains import-compatible and full restores are written to a new validated file. - CSV export (Chrome-compatible).
- Nextcloud Passwords bidirectional sync (REST API v1.0) — folders, tags, password versions.
- WebDAV / Nextcloud Files encrypted backup with generation-aware conflict detection.
- Google Drive backup via direct REST + OAuth 2.0 PKCE (no Python SDK), uploading to a dedicated
AshyPass Backupsfolder. - Each backend has list / restore / delete from inside Settings.
ashypass-native-hostimplements the Chrome native-messaging wire protocol (u32length prefix + UTF-8 JSON).- Supported commands:
ping,list,search,match_url,get,generate. - Reuses the Secret Service item so the GUI's Quick Unlock policy applies — no separate browser unlock.
ashypass-cli: list, search, copy, generate, and add entries from the shell.- Shares the GUI's vault file and keyring item; falls back to a silent stdin prompt when no stored master is available.
- libadwaita styling; dark mode follows the desktop.
- Sidebar-based settings dialog organised into Security · Data · Cloud · Appearance sections.
- Default window 800×650, minimum 700×570.
- Toast notifications, view stacks, and animated transitions.
- gettext-based localization with 29 language catalogues shipped (
bg, cs, da, de, el, en, es, et, fi, fr, he, hr, hu, is, it, ja, ko, nl, no, pl, pt, pt_BR, ro, ru, sk, sv, tr, uk, zh).
| Area | State |
|---|---|
| Core crypto (Argon2id + AES-256-GCM v2) | Stable |
| v1 → v2 vault migration (Fernet → AES-GCM) | Stable |
| Vault CRUD, search, categories, favorites, trash | Stable |
| Password / passphrase / PIN generation + strength meter | Stable |
| TOTP view + RFC 6238 generation | Stable |
| HIBP audit (k-anonymity) | Stable |
Importers (CSV, Aegis, andOTP, KeePass, 1Password, .ashy) |
Stable |
| Settings dialog (sidebar layout) | Stable |
| Google Drive backup (REST + OAuth PKCE) | Stable — requires build-time client ID |
| WebDAV / Nextcloud Files backup | Stable |
| Nextcloud Passwords bidirectional sync | Stable |
| Browser native-messaging host | Stable |
| CLI companion | Stable |
| Quick Unlock via Secret Service | Stable |
| Favicon fetch + cache | Stable |
| FIDO2 vault factor (CTAP2 register / assert) | Disabled until fully implemented; existing config preserved |
| i18n (gettext-rs, 29 catalogues) | Translated and CI-compiled |
| OS | Linux with GTK 4.12+ |
| Toolchain | Rust 1.85+, pkg-config, GTK4 / libadwaita dev headers |
| Runtime libs | gtk4, libadwaita, gettext, sqlite, openssl, glibc, gcc-libs, optional Secret Service daemon (gnome-keyring / kwallet) |
| Memory | ~50 MiB resident |
| Disk | ~30 MiB binary + vault |
git clone https://github.com/big-comm/ashypass.git
cd ashypass
cargo build --release --workspace
./target/release/ashypassThe fido2 feature name is retained for build compatibility, but vault-factor UI remains disabled until the hardware flow is complete.
Provide Google Drive credentials at build time (without these the Cloud Backup page shows a "not configured" notice):
ASHYPASS_GOOGLE_CLIENT_ID=xxx.apps.googleusercontent.com \
ASHYPASS_GOOGLE_CLIENT_SECRET=xxx \
cargo build --release -p ashypass-appBuild the auxiliary binaries:
cargo build --release -p ashypass-cli # produces ./target/release/ashypass-cli
cargo build --release -p ashypass-native-host # produces ./target/release/ashypass-native-hostcd pkgbuild
makepkg -siThe PKGBUILD compiles every locale/*.po into usr/share/locale/<lang>/LC_MESSAGES/ashypass.mo and installs the desktop file, icons, native host binary, and privileged drive helper.
- Launch Ashy Pass.
- Set a master password on the Vault tab — used to derive the AES-256-GCM key.
- (Optional) Enable Quick Unlock in Settings → Security to store PIN-wrapped device state in Secret Service.
- Add entries, or import a CSV / KeePass database from Settings → Data.
- Use the Generator tab to pick a type, tweak options, and copy.
- Inside the add/edit dialog, the password row carries a generate button (⚡) with presets: Strong, Passphrase, PIN, Custom.
- Edit any entry, paste a Base32 secret in the TOTP Settings group, choose algorithm/digits/period, save.
- The 2FA tab lists live codes; click to copy.
- Nextcloud Passwords — Settings → Cloud → Nextcloud Passwords: enter URL, username, app password, choose a folder, hit Sync. Conflicts are resolved by version timestamps.
- WebDAV backup — Settings → Cloud → WebDAV: encrypted database is uploaded with a generation marker so concurrent writes don't silently overwrite.
- Google Drive backup — Settings → Cloud → Google Drive → Sign in: the system browser opens an OAuth PKCE flow with a
127.0.0.1callback. Back up now uploads a consistent SQLite snapshot; Restore latest validates and saves a new timestampedpasswords-restored-*.dbwithout replacing the active vault.
- Build / install
ashypass-native-host. - Create the browser-specific native-messaging manifest with the companion extension's actual extension ID and point it at
/usr/lib/ashypass/ashypass-native-host. - Install that manifest in the browser's documented
NativeMessagingHostsdirectory. The package does not guess or install an extension ID.
ashypass-cli list # all entry metadata
ashypass-cli list --search github # filter title, username, or URL
ashypass-cli show <id-or-title> # print one decrypted entry
ashypass-cli gen --length 24 # generate without storing
ashypass-cli add # interactive add- Vault second-factor controls are intentionally unavailable until real CTAP2 registration and assertion are implemented.
- External LUKS2 drives can still enroll FIDO2 keyslots through
systemd-cryptenroll.
| File | Purpose |
|---|---|
~/.config/ashypass/settings.json |
UI prefs, lock / clipboard timeouts, generator defaults, trash retention |
~/.config/ashypass/fido2.json |
Preserved preview FIDO2 configuration; not currently enforced |
~/.local/share/ashypass/passwords.db |
Encrypted SQLite vault |
~/.local/share/ashypass/token.json |
Google Drive OAuth tokens |
~/.local/share/ashypass/favicons/ |
Cached site icons |
ashypass/
├── crates/
│ ├── ashypass-core/ # Pure library — no GTK
│ │ └── src/
│ │ ├── crypto/ # argon2_kdf, aes_gcm_v2, fernet_legacy, key, autotune
│ │ ├── db/ # rusqlite vault, schema, migration v1→v2
│ │ ├── generator.rs # passwords / passphrases / PINs
│ │ ├── strength.rs # entropy-based strength meter
│ │ ├── totp.rs # RFC 6238 (SHA1 / SHA256 / SHA512)
│ │ ├── importers/ # aegis, andotp, ashy, bitwarden, csv, keepass, onepassword
│ │ ├── backup/ # drive, webdav, oauth, sync
│ │ ├── sync/ # nextcloud_passwords, nextcloud_engine
│ │ ├── audit.rs · hibp.rs # password-health + breach checks (k-anonymity)
│ │ ├── favicons.rs # fetch + on-disk cache
│ │ ├── fido2.rs # preserved preview schema; hardware disabled
│ │ ├── keyring.rs # Secret Service secrets and Quick Unlock state
│ │ └── settings.rs # serde-backed user prefs
│ ├── ashypass-app/ # GTK4 / libadwaita desktop UI
│ │ └── src/
│ │ ├── main.rs · state.rs · session.rs · clipboard.rs · events.rs
│ │ └── ui/ # window, vault_view, generator_view, totp_view,
│ │ # settings_dialog (sidebar), i18n (tr! macro)
│ ├── ashypass-cli/ # Terminal companion (shares vault + keyring)
│ └── ashypass-native-host/ # Chrome/Firefox native-messaging host
├── locale/ # 30 .po files + ashypass.pot template
├── scripts/ # update-translations.sh, packaging helpers
└── pkgbuild/ # Arch / Manjaro PKGBUILD
See CRYPTO_SPEC.md for the exact algorithm parameters and blob layout — useful for porting or interoperability.
UI strings are wrapped in the tr!() macro, which delegates to gettext_rs and caches per-thread results behind a &'static str.
To refresh the template and recompile catalogues after editing source strings:
./scripts/update-translations.shThe script runs xgettext (recognising both tr! and tr_static!), msgmerge --no-fuzzy-matching against every locale/*.po, and msgfmt into usr/share/locale/<lang>/LC_MESSAGES/ashypass.mo. The PKGBUILD performs the same compile step at packaging time, so the CI/CD pipeline only needs the source .po files committed.
- Fork and create a feature branch from
main. - Run
cargo fmt --allandcargo clippy --workspace --all-targets -- -D warnings. - Add tests next to the code you touch (see existing
#[cfg(test)]modules inashypass-core). - Keep commit messages in English; UI strings stay in English and are translated via the
.poworkflow above. - Open a PR against
main.
MIT — see LICENSE.
- BIP39 — 2,048-word English list used for passphrase generation.
- GNOME — GTK4 / libadwaita.
- RustCrypto —
argon2,aes-gcm,pbkdf2,hmac,sha2. - rusqlite — embedded SQLite bindings.
- Have I Been Pwned — breach corpus consumed via the k-anonymity range API.
- Nextcloud — Passwords and Files REST APIs.