LastSignal: A Self-Hosted Dead Man's Switch with End-to-End Encryption
A self-hosted dead man's switch for delivering encrypted messages (E2EE) to your loved ones — when you're gone or unresponsive.
At a glance
- What is it?
- LastSignal is a Ruby on Rails application that delivers encrypted messages to your contacts when you stop responding to periodic email check-ins. The server stores only ciphertext, so neither the operator nor a database attacker can read message content without the recipient's passphrase.
- Who is it for?
- LastSignal fits technically capable individuals who want full control over their dead man's switch infrastructure and are prepared to run a Rails server with a reliable SMTP provider for the long term. It is not appropriate for anyone expecting a managed service: the project explicitly offers none, and any third-party instance claiming otherwise is unofficial.
- Can I use it commercially?
- Yes. MIT 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 2 days 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 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What LastSignal Does and Who It Serves
A dead man's switch is a mechanism that fires automatically when the person operating it stops responding. LastSignal applies this to personal communications: you write encrypted messages for people you want to reach after your death or incapacitation, and the application delivers them by email if you fail to respond to scheduled check-ins. The target user is an individual who considers message content sensitive enough for end-to-end encryption, is unwilling to trust a third-party service with that data, and can operate a Ruby on Rails server indefinitely.
The lastsignal.app homepage makes one point explicit: the authors do not run a hosted service. There is no SaaS tier, no paid subscription, and no official cloud instance. The README warns that any instance presented elsewhere as an official paid LastSignal service is not affiliated with the project. That constraint places the entire burden of reliability, SMTP configuration, and ongoing maintenance on the self-hoster.
The Four-Phase Check-In Sequence and Default Timing
The flow moves through four states. LastSignal sends a check-in email at a configurable interval, defaulting to 30 days. If you respond, the timer resets. If you do not, the system enters reminder mode, sending additional emails at 7-day intervals for three total attempts (including the first reminder). The final reminder also triggers a ping to a trusted contact you have designated.
That trusted contact then has 15 days to confirm your status. If neither you nor the trusted contact responds, LastSignal delivers your messages by email. Using the defaults from the README: a missed check-in on April 1 results in delivery on May 22. If a trusted contact confirms on May 16, delivery shifts to May 31, after which a new trusted contact ping and a further 7-day window run before delivery on June 7 unless you check in or the trusted contact confirms again.
All four timing defaults (check-in interval, attempt count, attempt interval, and trusted contact pause) are configurable per user in Account Settings. A user who travels frequently might extend the attempt interval; a user who checks email rarely might shorten the check-in interval. Changes apply to future check-in cycles without affecting a cycle already in progress.
A per-recipient delay setting adds a configurable number of days between delivery and when that recipient can decrypt the message. This is explicitly for staggered access: giving one contact immediate decryption capability while another must wait a set number of days before the content becomes readable.
For automated systems, the README documents an optional external keepalive token and a machine-to-machine check-in endpoint at /webhooks/keepalive. This is described as an add-on for automations, not a replacement for the default email-first model. A server that handles its own scheduled tasks, for instance a home automation hub, can send a keepalive signal periodically so that a brief absence from email does not trigger the reminder sequence.
Cryptographic Design and the Database Brute-Force Risk
LastSignal combines three algorithms. Key derivation uses Argon2id with a 256MB memory cost, making parallel brute-force expensive on commodity hardware. Symmetric encryption uses XChaCha20-Poly1305, which provides authenticated encryption. Key agreement uses X25519 elliptic-curve Diffie-Hellman.
The zero-knowledge property means the server never receives plaintext messages. The critical design tradeoff is in how the key derivation salt is stored. The server generates the salt and stores it alongside recipient public keys. This choice enables deterministic key regeneration from a passphrase alone, so a recipient can decrypt on any device using just their passphrase and the stored salt, with no prior key exchange required.
The cost is that anyone who reads the database, whether through a server breach, a malicious operator, or a legal request, also obtains the salt. With the salt in hand, an attacker can attempt offline brute-force against recipient passphrases with no rate limiting. A dictionary word, a short phrase, or any predictable pattern becomes practically vulnerable the moment the database is compromised. The README classifies passphrase strength as critical and directs readers to lastsignal.app/security for the full threat model.
Running LastSignal Locally for Development
The README lists Ruby 3.4+, SQLite 3 (sqlite3 gem >= 2.1), and Node.js (for Tailwind) as requirements. On a fresh Ubuntu host, the system package installation step is:
apt-get update && apt-get install -y \
git \
ruby \
bundler \
libyaml-devThen clone and boot the application:
git clone https://github.com/giovantenne/lastsignal.git
cd lastsignal
bundle install
cp .env.example .env
bin/setup
bin/devThe app starts on port 3000. The development environment uses letter_opener, which intercepts outgoing email and opens it in a browser tab rather than actually sending it, so no SMTP configuration is needed for local testing.
A Docker alternative using a Mailhog container for email capture starts with:
docker compose -f docker-compose.dev.yaml up --buildThe app runs on port 3000 and the Mailhog inbox on port 8025. A demo mode accelerates testing the full check-in sequence without waiting real days:
bin/rails demo:checkins:advance [email protected]Each invocation steps through the next email in the sequence: reminder, grace, cooldown, delivery. These demo helpers are restricted to development and test environments. The test suite runs via bin/test.
Deploying to Production with Kamal
The production path uses Kamal, which requires Docker on a Linux server, SSH access, and a reliable SMTP provider. The README recommends Ubuntu 22.04+, with ports 80 and 443 open and DNS records pointing to the server before starting.
Copy and fill the production environment template:
cp .env.production.example .env.productionRequired values include KAMAL_* settings for the Docker image registry and server address, APP_BASE_URL, APP_HOST, and SMTP_* credentials. An optional ALLOWED_EMAILS field restricts magic-link requests to a comma-separated allowlist, which is useful for a private family or team instance.
Generate the Rails master key, then set up and deploy:
bin/kamal setup
bin/kamal deployAfter the image is running, prepare the three databases separately:
bin/kamal app exec --interactive --reuse "bin/rails db:prepare"
bin/kamal app exec --interactive --reuse "bin/rails db:prepare DATABASE=cache"
bin/kamal app exec --interactive --reuse "bin/rails db:prepare DATABASE=queue"Logs are accessible via bin/kamal logs. The production Dockerfile targets Ruby 3.4.6 and includes libjemalloc2 for reduced memory use.
Environment Variables and the ALLOWED_EMAILS Allowlist
The .env.example file documents the configuration surface. APP_BASE_URL sets the base URL for link generation including protocol (for example http://localhost:3000 in development), while APP_HOST sets the hostname for DNS rebinding protection without a protocol prefix. SECRET_KEY_BASE encrypts sessions and is required for production. The README notes it can be generated with bin/rails secret.
SMTP_* variables supply the provider credentials. LastSignal does not ship with a built-in SMTP server, which means the operator must choose and configure an external provider. If the provider imposes sending limits or domain reputation requirements, that affects check-in reliability directly.
ALLOWED_EMAILS is an optional comma-separated allowlist. When set, only addresses on the list can request a magic link. This is the mechanism for running a private instance restricted to a specific family or small group, rather than an open registration where anyone who knows the URL could create an account.
The PROCESS_CHECKINS_INTERVAL_MINUTES variable controls how often the background job scans for due check-ins. The default is 60 minutes. Reducing it means the system reacts faster after a missed check-in deadline; increasing it adds latency between when a check-in becomes overdue and when the first reminder goes out.
When LastSignal Is the Wrong Tool
LastSignal places its entire reliability on two components: the server running the ProcessCheckinsJob and the SMTP provider delivering check-in emails reliably to your inbox. If either fails silently for an extended period, you could miss a check-in and trigger unintended delivery, or the system could stop sending check-ins altogether without any outward signal. The README does not document a health monitoring endpoint or a fallback notification channel.
There is no mobile application. Checking in requires responding to an email. If email is inaccessible during a hospital stay or a remote trip, the timer continues running. The keepalive webhook partially addresses this for technical users who can script a machine-to-machine call, but a non-technical user has no check-in path other than email.
The project has no releases on GitHub, meaning there is no tagged version history. Updates arrive only as commits to the master branch. Organizations with change-management requirements that mandate versioned deployments will find this inconvenient.
For users who need a dead man's switch without the infrastructure overhead, hosted services that handle timing and delivery without self-hosting are available. They typically do not offer end-to-end encryption of message content, which is the tradeoff: operational simplicity in exchange for trusting a third party with timing metadata and often message content. LastSignal's zero-knowledge architecture is its primary differentiating capability, and that capability requires accepting full operational ownership.
Editorial conclusion
LastSignal fits technically capable individuals who want full control over their dead man's switch infrastructure and are prepared to run a Rails server with a reliable SMTP provider for the long term. It is not appropriate for anyone expecting a managed service: the project explicitly offers none, and any third-party instance claiming otherwise is unofficial. Before going live, verify SMTP delivery end-to-end, run bin/test to confirm the suite passes on your deployment host, and ensure every recipient uses a passphrase that resists offline brute-force, since a stolen database gives an attacker the KDF salt and unlimited time to guess.
Frequently asked questions
How does LastSignal prevent the server operator from reading message content?
LastSignal encrypts all message content client-side using XChaCha20-Poly1305 before it reaches the server. The server stores only ciphertext and the KDF salt. Without the recipient's passphrase, the server and any operator cannot decrypt stored messages.
What is the risk if a LastSignal database is stolen or subpoenaed?
The README documents this directly: the server stores the KDF salt alongside recipient public keys. Anyone who obtains the database also obtains the salt and can attempt unlimited offline brute-force against recipient passphrases without rate limiting. Strong, unpredictable passphrases are the only mitigation the project documents.
Can the keepalive webhook replace email check-ins entirely?
No. The README describes the keepalive webhook at /webhooks/keepalive as an add-on for machine-to-machine automations, not a replacement for the email-first flow. The default check-in sequence, reminder emails, and trusted contact pings all run over email.
Official sources
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.
[](https://hysenlabs.com/projects/giovantenne-lastsignal)