rowel is a free, open source identity & access management (iam) project written in TypeScript and released under GPL-3.0. It has 944 GitHub stars, 80 forks and 24 open issues, and was last pushed 4 hours ago. On this registry it ranks #39 of 44 tracked projects in Identity & Access Management (IAM), with 5 head-to-head comparisons available.

What is rowel?

Rowel is a free, offline-first password manager for macOS, Windows and Linux that keeps logins, credit card details and secure notes in a locally stored, encrypted SQLite vault, built for individuals who would rather own their secrets than store them in a hosted service.

What it is

Rowel is a cross-platform desktop application built with Tauri 2, pairing a Rust backend with a TypeScript, React and Vite frontend. It lives in the Tauri desktop-application ecosystem and ships as native installers โ€” .dmg, .msi, -setup.exe, .deb, .rpm and .AppImage โ€” rather than as a web service. A vault is a locally stored, encrypted SQLite database using SQLCipher, and each entry's secrets are sealed inside an additional application-level AEAD layer, with AES 256 GCM named as the encryption in use. Secrets stay encrypted at rest and in memory, and are decrypted only at the moment a user reveals or copies them.

The problem it solves is the exposure that comes from keeping credentials on someone else's infrastructure. Rowel's stated position is that no data leaves the computer: the vault lives on the machine, and syncing is an optional extra rather than a requirement. Google Drive Sync can be turned on for those who want it, and the same feature supports moving from one computer to another, as does a plain backup file. In effect this replaces the hosted password-manager account with a vault the user controls, so availability does not depend on a third-party service being online.

Key capabilities

  • Stores three kinds of records: login and password credentials, credit card information, and secure notes for sensitive text.
  • Encrypts the vault with AES 256 GCM and SQLCipher, adding an application-level AEAD layer around each entry's secrets.
  • Generates strong passwords in one click.
  • Supports time-based one-time passwords (TOTP).
  • Offers optional Google Drive Sync, plus migration between computers through either that sync or a backup file.
  • Publishes verifiable releases: SLSA build provenance attested with actions/attest-build-provenance and checkable via gh attestation verify ./Rowel_1.0.0_amd64.AppImage --repo fwdai/rowel, CycloneDX SBOMs named rowel-rust.cdx.json and rowel-js.cdx.json, and auto-updates signed with a minisign key whose public half sits in src-tauri/tauri.conf.json.

Who uses it and how

  • Desktop users on macOS, Windows and Linux who install a packaged release for their platform.
  • Privacy-focused individuals who keep the vault offline and enable Google Drive Sync only when moving between machines.
  • Security-conscious users who verify an installer's build provenance before running it, and audit shipped dependencies with a CycloneDX-aware scanner such as grype sbom:./rowel-rust.cdx.json.
  • Contributors working on the Tauri 2 codebase with Bun 1.3.3 or newer, Node.js 22 for the WebdriverIO end-to-end suite, and a stable Rust toolchain.
  • Anyone upgrading an old installation: releases up to and including v1.0.0-alpha.6 predate the move from swiftyapp/swifty to fwdai/rowel, so their provenance is verified against the former repository instead.

Getting started

Packaged builds for macOS, Windows and Linux are published on the Latest Releases page. Building from source uses Bun: clone the repository, run bun install, then bun run tauri:dev for development or bun run tauri:build for a signed, packaged build of the current operating system.

How it compares

No comparable or competing tools are named in the facts available here, so Rowel stands alone in this registry rather than sitting alongside a documented set of alternatives. What can be said is that it occupies the offline-first, self-owned-vault position among desktop password managers, and that the surrounding material describes only its own behaviour rather than any rival.

When to use it โ€” and when not to

A self-hoster should expect to run the desktop application itself: no server component is described, so the real burden is backup, recovery and the optional Google Drive account. Anyone who needs a browser extension, a mobile client or web access should look elsewhere, because only macOS, Windows and Linux desktop builds are described. The documentation is uneven in places and ends with "There's more to come...", and because the project was renamed, anyone auditing older releases must account for the change from swiftyapp/swifty to fwdai/rowel; the GPL-3.0 licence also matters to anyone intending to reuse the code in a closed product.

project readme (upstream, from github) โ€” read inline

Rowel โ€” Password Manager

Free Offline-first Password Manager for MacOS, Windows and Linux.

Actions Status Financial Contributors on Open Collective GitHub release (latest SemVer including pre-releases) GitHub All Releases Encryption

โค๏ธ it? Then โญ๏ธ it on GitHub or Tweet about it.

Features

  • Store Login/Password credentials
  • Credit card Information
  • Secure notes to store sensitive information
  • One-click Strong Password Generation
  • Time-based One Time Passwords support (TOTP)
  • Google Drive Sync (optional)
  • No data is leaving your computer:
    • Your vault is a locally stored, encrypted SQLite database (SQLCipher); each entry's secrets are sealed in an extra application-level AEAD layer
    • Secrets stay encrypted at rest and in memory, decrypted only when you reveal or copy them
    • Ability to migrate from one computer to another using backup file or GDrive sync
  • There's more to come...

Screenshots

Install

Check the Latest Releases page for the most recent packaged app for MacOS, Windows or Linux.

Verifying a release

Every release is built in GitHub Actions and ships with supply-chain evidence:

  • SLSA build provenance โ€” each installer is attested with actions/attest-build-provenance (keyless OIDC signing). You can prove an installer was built by this repo's workflow, from this source, with the GitHub CLI:

    gh attestation verify ./Rowel_1.0.0_amd64.AppImage --repo fwdai/rowel
    

    (works for the .dmg, .msi, -setup.exe, .deb, .rpm and .AppImage assets โ€” point it at whichever you downloaded).

    Releases up to and including v1.0.0-alpha.6 were built before the project moved from swiftyapp/swifty to fwdai/rowel, so their provenance names the old repository. Verify those with --repo swiftyapp/swifty instead.

  • CycloneDX SBOM โ€” every release attaches rowel-rust.cdx.json (the full Rust dependency graph) and, when available, rowel-js.cdx.json (the frontend). Feed them to any CycloneDX-aware scanner (e.g. grype sbom:./rowel-rust.cdx.json) to audit the exact dependencies a build shipped.

  • Update signature โ€” the auto-updater only installs updates signed with the project's minisign key (public key in src-tauri/tauri.conf.json); the matching private key never leaves CI.

The Rust toolchain (rust-toolchain.toml) and the bun version are both pinned, so builds are reproducible from a fixed toolchain.

Development

Rowel is built with Tauri 2 (Rust backend + TypeScript/React/Vite frontend).

Prerequisites

  • Bun 1.3.3 or newer (what CI pins) โ€” the package manager and script runner for this repo; bun.lock is the committed lockfile
  • Node.js 22 (what .nvmrc and CI pin) โ€” only the E2E suite needs it, since WebdriverIO runs under Node
  • Rust (stable toolchain)
  • Platform build dependencies for Tauri โ€” see the Tauri prerequisites guide (on Linux: libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libgtk-3-dev)

Commands

git clone [email protected]:fwdai/rowel.git
cd rowel
bun install

bun run tauri:dev     # run the app in development
bun run tauri:build   # produce a signed, packaged build for the current OS

bun run tauri:dev:fresh   # same, against a throwaway data dir (first-run flows)

bun run build         # build the frontend only (tsc + vite)
bun run test          # frontend unit tests (Vitest)
cd src-tauri && cargo test   # backend tests

Run the scripts with bun run , not bun : bare bun test starts Bun's own test runner instead of the Vitest suite this repo is written against.

tauri:dev:fresh points ROWEL_DB_DIR at a new temp directory each run, so the app finds no vault there and starts at the setup/restore screen every time. Your real dev vault is left untouched โ€” bun run tauri:dev goes back to it.

Setting ROWEL_DB_DIR yourself overrides that and keeps the same directory across runs, which is how you set a throwaway vault up once and then relaunch into its unlock screen. Nothing here ever deletes a data directory; to start that one over, remove it yourself. Debug builds only: a release build ignores the variable and always uses the OS app-data directory.

Configuration

Google Drive sync (optional)

Drive sync uses your own Google OAuth client โ€” no credentials are bundled with the app. Desktop and iOS need one client each, because Google will not let a Desktop client redirect to a mobile app.

Desktop
  1. In the Google Cloud Console create an OAuth 2.0 Client ID of type Desktop app.

  2. Enable the Google Drive API for the project.

  3. The app requests the https://www.googleapis.com/auth/drive.file scope and listens on the loopback redirect URI http://127.0.0.1:4567/auth/callback.

  4. Provide the credentials as environment/build variables when running or building:

    export GOOGLE_OAUTH_CLIENT_ID=your-desktop-client-id.apps.googleusercontent.com
    export GOOGLE_OAUTH_CLIENT_SECRET=your-desktop-client-secret   # optional
    

    They are read at runtime (std::env::var) and, if absent, fall back to the value baked in at compile time (option_env!). The build succeeds without them โ€” sync simply reports "Google OAuth client not configured" until a client id is supplied.

iOS

An iOS client is a public client: it has no secret, PKCE is mandatory, and its redirect URI is its own client id reversed. So the one thing to configure is that URL scheme, and the client id is derived from it.

  1. In the same project create a second OAuth 2.0 Client ID, of type iOS, with the iOS bundle id from src-tauri/tauri.ios.conf.json (app.rowel.mobile โ€” not the desktop one in tauri.conf.json).

  2. Take the client id it gives you โ€” 123456-abcdef.apps.googleusercontent.com โ€” and reverse it into a scheme: com.googleusercontent.apps.123456-abcdef. (Google shows this as the "iOS URL scheme" on the credential page.)

  3. Add the scheme to src-tauri/tauri.ios.conf.json (there is no plugins block there until you do โ€” a placeholder scheme is not a legal URL scheme and App Store Connect rejects the upload over it, so the file ships without one):

    "plugins": {
      "deep-link": {
        "mobile": [{ "scheme": ["com.googleusercontent.apps.123456-abcdef"] }]
      }
    }
    

    This is the committed source of truth for iOS, and it is safe to commit โ€” an iOS client id is public by design. The Tauri CLI registers the scheme as CFBundleURLTypes in the generated Info.plist during tauri ios build (via tauri-plugin-deep-link's build script), and the app derives both the client id and the redirect URI com.googleusercontent.apps.:/oauth2redirect from it at runtime. Re-run bun run tauri ios init if the Xcode project is out of date.

  4. Add the redirect URI com.googleusercontent.apps.123456-abcdef:/oauth2redirect to the client in the console.

Release builds do not need the block committed: bun run release:ios and the Release iOS workflow derive the scheme from GOOGLE_OAUTH_IOS_CLIENT_ID (in .env / the repository secret) and pass it through tauri ios build --config, which replaces a committed one. That is the only way in โ€” exporting GOOGLE_OAUTH_CLIENT_ID does nothing on iOS, because tauri ios build compiles inside xcodebuild with a replaced environment that carries only the CLI's own TAURI_* variables, so option_env! never sees it. GOOGLE_OAUTH_CLIENT_SECRET is ignored on iOS and must never be shipped in a mobile binary.

Auto-update signing

Release builds are signed for tauri-plugin-updater. The public key lives in src-tauri/tauri.conf.json; the matching private key is never committed and is provided to CI via the TAURI_SIGNING_PRIVATE_KEY (and TAURI_SIGNING_PRIVATE_KEY_PASSWORD) secrets. Generate a keypair with bun run tauri signer generate -w ~/.rowel/updater.key.

Security

Rowel is offline-first: your vault is an encrypted SQLite database (SQLCipher) on your own device, with each entry's secrets sealed in an additional application-level AEAD layer, and there is no backend that holds your secrets. See SECURITY.md for how to report a vulnerability, and docs/threat-model.md for what Rowel does and does not defend against.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

License

GNU/GPL Version 3

Frequently asked questions

Is rowel free to use?

rowel is open source under the GPL-3.0 licence. There is no licence fee and no seat count โ€” you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does rowel do?

๐Ÿ”‘ Free Offline-first Password Manager

What is rowel written in?

rowel is primarily written in TypeScript. Its source is publicly available at https://github.com/fwdai/rowel, and it has 944 GitHub stars.