Open-source project
nextcloud/passman avatar
nextcloud/passman

Passman and the Nextcloud password manager that keeps vault keys off the server

🔐 Open source password manager with Nextcloud integration

827 stars118 forksJavaScriptAGPL-3.0

At a glance

What is it?
Passman is a password manager app for Nextcloud with multiple vaults, client-side 256-bit AES encryption and a built-in OTP generator. The vault key never leaves the browser, but the server still re-encrypts what it stores, and the developer API is described as outdated and unmaintained.
Who is it for?
Passman suits organisations that already run Nextcloud and want a shared password vault without adding a separate SaaS dependency, and that can live with an app whose client ecosystem lives in separate repositories.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A password manager that lives inside the Nextcloud you already run

Passman is a full featured, open source password manager built as a Nextcloud app, and the whole point of the arrangement is that the vault lives in infrastructure the organisation already operates. It is installed like any other Nextcloud application, and the project is listed in the Nextcloud App Store, with a public demo instance and a project homepage at passman.cc.

The feature list is what you would expect from a serious password store. There are multiple vaults, so shared credentials can be separated rather than pooled into one list. Custom credential fields are user-defined, so a record can hold whatever your team needs beyond username and password. A built-in OTP generator covers one-time passwords without a separate authenticator app. A password analyzer scores strength, and there is both internal sharing and sharing by link.

Import is supported from a long list of other managers, though the project marks that feature as experimental: KeePass, LastPass, DashLane, ZOHO, Clipperz.is, EnPass and ocPasswords are all named. Migration is usually the hardest part of switching password managers, so having the importers in place matters more than the polished feel of the vault screen.

The vault key never reaches the server

The security model has two layers, and it is worth separating them because they protect against different things.

The first layer is in the browser. All passwords are encrypted client side with sjcl using 256-bit AES, and the key for that encryption is a vault key that you supply. The project states it plainly: vault keys are never sent to the server. That means a server administrator, and anyone who obtains a database dump or backup of the Nextcloud instance, sees ciphertext for the credential contents rather than the secrets themselves.

The second layer is on the server. Encrypted credentials are sent up and encrypted again by the server, using a routine described in the project documentation. The server-side step exists so that a compromise of the vault key alone does not hand over usable data, and so that the stored blobs are not merely obfuscated by a client-side key that might turn up in a browser cache.

What the two layers do not do is make the Nextcloud instance irrelevant. Whoever can run code on the server, or read config.php, is inside the trust boundary. That is a real limitation, and it is the reason the project's own advice to back up two specific configuration values matters so much.

passwordsalt and secret in config.php are the root of server-side protection

The server-side encryption routine is documented step by step, and it is worth reading closely because it is where the operational risk lives. A key is generated using `passwordsalt` and `secret` from config.php, and the documentation flags that those values should be backed up. The key is then stretched with PBKDF2, a password-based key derivation function, and Encrypt-then-MAC is used so that encrypted data carries its own authenticity guarantee. Under the hood the project uses openssl with the `aes-256-cbc` cipher, the initialization vector is hidden, and a double HMAC is applied for source data verification.

Two details deserve attention. Stretching with PBKDF2 is what makes a leaked or guessable secret expensive to attack, and it is what connects the strength of your config.php values to the strength of the stored data. Hidden initialization vectors and the MAC together mean a modified ciphertext will fail to decrypt rather than yielding garbage.

The operational consequence is concrete: the protection of everything in the vault ultimately rests on two values that live in a file on the server. Generating them properly, storing them in your secret management, and backing them up is the security work this app delegates to you. Losing them means losing the ability to decrypt stored credentials, and leaking them defeats the second encryption layer entirely.

Generation, strength scoring and one-time passwords

Three small features sit on top of the vault and are implemented with well-known libraries rather than home-grown code. Password generation uses sjcl randomization, so the randomness comes from a cryptographic library rather than a language random function. Strength measurement uses zxcvbn, the estimator that scores a candidate against patterns of real passwords rather than against simple composition rules.

The OTP generator is built in, which is the detail that changes daily use. A user who has to switch to another application to read a one-time password is a user who will skip the step, and the two-factor code is exactly the thing that most often gets skipped. Keeping the generator in the same vault as the credential also keeps the shared secret and the current code together for colleagues who need access.

User-defined credential fields sit alongside this. In a team setting that is what lets one record carry a server hostname, a port, a certificate note and a link to internal documentation, instead of a shared password that a person has to hold in their head along with everything else.

Sharing, share links and the administrator kill switch

Credentials can be shared inside the installation and through a link, and administrators may disable the sharing feature entirely. That switch is the thing to think about when placing Passman in an organisation, because sharing is what turns a password store into a distribution system for secrets.

Shared vault entries are the normal case and the good one: a colleague opens the vault, sees the credential they need, and never handles the raw password. Share links extend that outside the installation, to somebody without a Nextcloud account, and they are the case with the sharper edges, because a link that escapes can be forwarded.

The project does not publish a retention or expiry policy for share links in the documentation available here, and it does not describe an audit trail for who read a shared credential. What it does publish is the operation log question in a different form, and the fact that an administrator can turn sharing off. For a deployment, the sane sequence is to enable sharing only where a business case exists for it, and to check how the link behaves once the underlying credential changes.

Installing the app, and the local development loop

Passman is a Nextcloud app, so installation follows the app path: place it in the apps directory of a Nextcloud instance and enable it. The repository layout matches that model, with an `appinfo/` directory holding the app metadata and an `appinfo/info.xml` file that the README badges read to show the supported Nextcloud and PHP version ranges.

For local work, the project documents Docker images maintained in a separate repository, passman-dev-docker-build. Two images are published. The development image is meant for local hacking, with your checkout bind mounted so you can run grunt and try different Nextcloud and PHP stacks. The demo image is pre-baked, the kind used for the public demo instance, without the development tooling. The default login for all images is `admin` and `admin`.

bash
docker run -d -p 8080:80 -p 8443:443 \
  -v /path/to/passman:/var/www/html/apps/passman \
  --name passman-dev

The JavaScript side is built with grunt, and the top-level Makefile drives the standard Nextcloud app packaging while delegating the JavaScript work to npm scripts:

bash
npm run build
bash
npm run test

The package manifest pins grunt 1.4.1 and a full set of contrib plugins for concatenation, minification, sass compilation and linting, and the test stack is karma with jasmine, running against Chrome and Firefox launchers. The repository also carries a Makefile, a composer.json for the PHP side, and a swagger.yaml at the root.

Clients live in separate repositories, and the API is not maintained

The Passman ecosystem is split across repositories, and that split has consequences for anyone depending on it. The browser extension, Passman Webextension, is described as a fully rewritten extension for the Passman Nextcloud app using modern frontend and extension frameworks, and it is published in the Chrome Web Store and as an add-on for Firefox. The native Android client is a separate project too, distributed through the Google Play Store, IzzyOnDroid and F-Droid.

The API is the weak point, and the project says so without hedging. A developer API is offered and linked from the repository wiki, but the documentation states that it is very outdated and not maintained, and invites people to update it. There is a swagger.yaml in the repository root, which is at least a description of the interface shape, but a machine readable description and a maintained contract are not the same thing.

For an internal deployment that only needs people to log in and use vaults, that is tolerable. For a product team that wants to build a script, a chat bot or a service account on top of Passman, it is the decisive fact, and the invitation to update the wiki is an invitation to take on the maintenance work yourself.

Three database engines, frequent releases and an AGPL licence

Database support is broader than many Nextcloud apps manage. SQLite, MySQL and MariaDB, and PostgreSQL are all supported, and CI runs PHPUnit against each of the three on GitHub Actions, with separate workflow files for the SQLite, MySQL and PostgreSQL runs. That is a meaningful statement about the code, because a password store that only worked on one engine would be a deployment risk for every existing Nextcloud installation.

The release cadence is brisk. Recent versions include 2.6.5 on 2026-10-17, 2.6.4 on 2026-10-10 and 2.6.3 on 2026-09-22, and the last push to the repository was on 2026-10-20, with the default branch named master. The project is not archived, and the repository carries a CHANGELOG.md, an AUTHORS.md, a CONTRIBUTING.md and a `l10n/` directory with translations, plus a `.tx/` directory pointing at the translation workflow.

The licence is AGPL-3.0, with the COPYING file at the root. That is the significant legal difference from a typical Apache or MIT project, and the obligation it carries is the network use clause: a modified version offered to users over a network must be offered with its corresponding source. Running an unmodified instance for your own organisation is a different situation from offering a modified one to others, and teams with plans to fork should read the licence text and take their own advice rather than rely on a summary.

Editorial conclusion

Passman suits organisations that already run Nextcloud and want a shared password vault without adding a separate SaaS dependency, and that can live with an app whose client ecosystem lives in separate repositories. It is the wrong choice for anyone who needs a dependable public API today, since the project itself says the developer API is very outdated and not maintained, and for teams unwilling to hold the `passwordsalt` and `secret` values in config.php as the root of their server-side protection. Before deploying, decide how those two values are generated and backed up, and test the import path from whichever manager your users are moving from.

Frequently asked questions

Does Passman ever send the vault key to the server?

No. The project states that vault keys are never sent to the server, and that all passwords are encrypted client side with sjcl using 256-bit AES before the encrypted credentials are uploaded. The server encrypts the stored data a second time.

Which configuration values does Passman need backed up?

The server-side key is generated from `passwordsalt` and `secret` in config.php, and the documentation explicitly says to back those up. The key is then stretched with PBKDF2, encrypted data uses encrypt-then-MAC with the aes-256-cbc cipher in openssl, and a double HMAC verifies the source data.

Which databases does Passman support?

SQLite, MySQL and MariaDB, and PostgreSQL are all supported, and CI runs PHPUnit against each of the three on GitHub Actions through separate workflow files for SQLite, MySQL and PostgreSQL.

Can Passman import from other password managers?

Yes, though the feature is marked experimental. Named sources include KeePass, LastPass, DashLane, ZOHO, Clipperz.is, EnPass and ocPasswords, so migration from most commercial managers is possible before the app is put into service.

Is the Passman API safe to build on?

The project states that the developer API is very outdated and not maintained, and that people are welcome to update it. A swagger.yaml description exists at the repository root, but anyone planning to depend on the API programmatically should expect to maintain that integration themselves.

What clients are available for Passman?

A rewritten browser extension is published in the Chrome Web Store and as a Firefox add-on, and a native Android app is distributed through the Google Play Store, IzzyOnDroid and F-Droid. Both live in separate repositories from the main Nextcloud app.

Official sources

  1. License: AGPL-3.0
  2. nextcloud/passman on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nextcloud-passman.svg)](https://hysenlabs.com/projects/nextcloud-passman)

Was this useful?