Self-hosted service
pglombardo/PasswordPusher avatar
pglombardo/PasswordPusher

Password Pusher: Self-Hosted One-Time Secret Sharing with Expiry and Audit Logs

🔐 Securely share sensitive information with automatic expiration & deletion after a set number of views or duration. Track who, what and when with full audit logs.

3,194 stars461 forksRubyApache-2.0

At a glance

What is it?
Password Pusher is an Apache-2.0 Ruby web app that turns a password, note, file or URL into a link that expires after a set number of views or a set duration. It is aimed at teams that want the audit trail on their own infrastructure rather than a vendor's.
Who is it for?
Adopt Password Pusher if you need one-time secret links that expire by view count or duration and you want the audit records inside infrastructure you control, and if a Ruby on Rails application plus a database is a deployment shape your team already runs. Do not adopt it if you need a hosted service with a support contract, if you cannot operate Postgres or MySQL and a Rails release cycle, or if your threat model requires the server never to hold plaintext.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

The problem Password Pusher addresses, and who actually has it

Sending a credential over chat or email leaves a copy in a message history, a mailbox, a backup and possibly a compliance archive. Deleting the message later does not reach those copies. Password Pusher changes the shape of the exchange: the sender creates a push, and the recipient receives a link that stops working after a configured number of views, a configured duration, or both. The README describes the intent plainly, positioning it against sending secrets "over chat or email", with the data removed once expired. The audience is narrower than the feature list suggests. It fits an IT team, an MSP, or a platform group that already runs its own services and wants the record of who shared what and when to sit in its own database. It also fits individuals who want a hosted instance without self-hosting, since the project runs pwpush.com and an OSS demo at oss.pwpush.com. It does not fit someone looking for a zero-operations SaaS with a support contract, and it does not fit a workflow where the recipient must be able to retrieve the secret again after the view limit is spent. There is no recovery path in the described design, which is the point.

How expiry, encryption and the audit trail fit together

The mechanism is a Rails application backed by a database, with a stateless mode available as a separate container image (pwpush-ephemeral). When a push is created, the payload is stored encrypted and the record carries expiry rules: a maximum view count, a time limit, or both. An optional passphrase adds a second factor the recipient must supply before the payload is revealed. Optional logins let the instance attribute views to named accounts, which is what turns the audit log from a list of anonymous retrievals into something with an identity column. The README states that sensitive data is removed entirely once expired, so the deletion is part of the expiry action rather than a separate cleanup job the operator schedules. Two design choices are worth naming. First, the delivery page is deliberately unbranded, described as having no logos or unrelated links, which reduces the chance a recipient mistakes a legitimate push page for a phishing page. Second, the API surface is split: /api/v2 covers create, retrieve, audit, active and expired workflows, while the older /p, /f and /r routes remain for backwards compatibility. That split means new integrations should target v2, but existing scripts written against the v1-style routes will keep working.

Getting an instance running with Docker and the environment variables that matter

The README states that a self-hosted instance runs with Docker Compose and automatic SSL/TLS, and that Docker is the documented path for standing one up "in minutes". The project publishes two images, pglombardo/pwpush for the database-backed deployment and pglombardo/pwpush-ephemeral for the stateless variant. Configuration is done through environment variables with a PWP__ prefix. Two examples appear in the supplied material: PWP__REQUIRE_MFA=true, which lets an admin require TOTP-based MFA instance-wide, and the theme variables, which the README says can set a custom theme, logo and site name across 26 Bootswatch themes. Custom CSS is also supported, with light and dark following the system preference. The admin dashboard is where instance management happens once the container is up. The repository documents an upgrade guide in UPGRADE-2.0.md for anyone moving a self-hosted instance to v2.0, and that guide is the first thing to read if you are already running an earlier major version, because the README explicitly flags configuration changes alongside the migration notes. Beyond the Compose path, the README lists Kubernetes, Helm and cloud deployment as supported, though it gives no manifests or chart names in the text available here, so those routes need the documentation site rather than the README.

Where Password Pusher is the wrong tool

The design assumes the server can see the secret. It is stored encrypted at rest, but the application holds the keys needed to decrypt it for the recipient, and the README claims no end-to-end or zero-knowledge property. If your threat model includes a compromised application server, Password Pusher does not address it: an attacker with database and application access can read unexpired pushes. A tool that encrypts in the browser and never transmits the key would be the right choice there. The second limitation is operational. This is a Rails application with a database, an admin UI, background expiry behaviour and a versioned migration path (the jump to v2.0 required configuration changes). A team without Ruby or Rails experience is taking on a release cycle it cannot debug. The stateless ephemeral image reduces the database burden but, by definition, cannot offer the persistent audit trail that is one of the main reasons to pick this project. The third limitation is that the README's maturity language is unverifiable from the outside. Statements about "15+ years in production" and use by "thousands of companies" come from the project itself, and nothing in the repository metadata lets an evaluator confirm them. Treat them as claims, not evidence.

How it differs from Bitwarden Send and from a plain secrets manager

Bitwarden Send is the closest well-known comparison, and the difference is architectural rather than cosmetic. Send is a feature of a password manager: the sender is a Bitwarden user, the recipient is often outside the organisation, and the vault, the account system and the audit record live with Bitwarden or with your self-hosted Bitwarden server. Password Pusher is a standalone application whose only job is the push, so an instance can be deployed for that purpose alone, with its own database, its own admin dashboard and its own audit log that does not depend on a password manager rollout. If your organisation already runs Vaultwarden or Bitwarden, Send is available without a new service to operate, and that is a real argument for using it. A general secrets manager such as Vault is a different category again: it is built for machine-readable secrets consumed by applications, with leases and dynamic credentials, not for a human-to-human link that a colleague clicks once. Password Pusher's JSON API v2 and its official CLI make it scriptable, but the unit of work is still a link with a view count, not a lease. The project also offers a Pro edition with features that the README says are periodically migrated back into the open source repository, which means the OSS feature set is a moving target rather than a frozen tier.

Maintenance load, licensing and what an upgrade actually costs

The release cadence visible in the supplied material is steady and mostly small: v2.11.4 fixed Devise validation errors after Turbo auth form submissions, v2.11.5 added pagination metadata headers to API list endpoints, and v2.11.6 was a dependency and security update. That pattern is the realistic maintenance picture. Most upgrades are dependency bumps, but v2.11.5 is a reminder that API responses can change between minor versions, so anything parsing /api/v2 list endpoints should be checked against the release notes before upgrading. The major version jump to v2.0 is the expensive one, with a dedicated upgrade guide and configuration changes. Budget for a staging instance and a rehearsal, not a drop-in image swap. On licensing, the repository is Apache-2.0, which permits commercial use and modification with the usual notice and attribution conditions. The README distinguishes the open source edition from a hosted Pro service and from a self-hosted Pro offering with licensing, and it states that Pro features are periodically moved into OSS. That means the licence on this repository is permissive, but the feature boundary between OSS and Pro is set by the maintainer and can shift. If a specific capability is the reason you are choosing Password Pusher, confirm it exists in the OSS code rather than in the Pro comparison matrix. Nothing here is legal advice; read the LICENSE file and the editions documentation for your own situation.

A concrete evaluation path before you commit

The fastest way to decide is to run the database-backed image on a throwaway host, set PWP__REQUIRE_MFA=true, create a push with both a view limit and a time limit, and then try to retrieve it one time past the limit. That single test tells you whether the expiry semantics match what your team expects, which is the behaviour everything else depends on. Next, exercise the audit log with a named account to confirm the identity attribution is granular enough for your reporting. Then read UPGRADE-2.0.md even if you are starting fresh, because it documents the configuration surface and will tell you which settings are stable. If you are migrating an existing instance, apply the guide's changes on staging first and check the /api/v2 endpoints your tooling uses, since v2.11.5 changed list response headers. If your requirement is a link a recipient can reopen, or a secret the server must never be able to read, stop here and pick a different tool; those are boundaries of this design, not gaps that configuration closes.

Editorial conclusion

Adopt Password Pusher if you need one-time secret links that expire by view count or duration and you want the audit records inside infrastructure you control, and if a Ruby on Rails application plus a database is a deployment shape your team already runs. Do not adopt it if you need a hosted service with a support contract, if you cannot operate Postgres or MySQL and a Rails release cycle, or if your threat model requires the server never to hold plaintext. Before rolling it out, verify three things on a staging instance: that your chosen storage backend keeps secrets encrypted at rest the way the documentation claims, that PWP__REQUIRE_MFA=true behaves as expected for every account type you have, and that the v2.0 upgrade guide's configuration changes have been applied if you are migrating from an earlier major version.

Official sources

  1. License: Apache-2.0
  2. pglombardo/PasswordPusher on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes