CarrierPony: a private OpenPGP messenger and your own relay

CarrierPony logo. Your own relay and OpenPGP Docker
A no-account OpenPGP messenger: how it differs from SimpleX, why there are no calls, and how to run your own relay.

CarrierPony is a messenger with no account, phone number, or email. Messages and files are sealed on your device with an OpenPGP key, and the server in between only carries an envelope it cannot open. This guide compares it with SimpleX Chat, explains why there are no calls, and shows how to run your own relay.

What CarrierPony is

It is a young messenger from one independent developer, in the same family as PGPony. Your identity is an OpenPGP key pair the app creates on the phone: Ed25519 for signatures and Curve25519 for encryption. Pairing shares the public half. The private half stays on the device, except inside an encrypted backup.

You pair by sending an invite or by scanning a code in person. Both sides then show the same safety number, derived from the two keys. Until you compare it, pairing is trust on first use. After it matches, a different key cannot pretend to be your contact.

Every message and every file is signed with your key and encrypted to theirs. The documented file limit is 50 MB. Groups are for people you have already paired with. Channels are broadcasts: one person publishes, subscribers read, and they do not reply into the channel. One device can hold several identities, each with its own keys and inbox. An existing OpenPGP key from GnuPG or PGPony can be imported.

Apps exist for iPhone, Android, and the desktop: macOS, Windows, and Linux, including ARM. The direct Android build, the one outside the store, can also carry envelopes over SMS or Nostr relays. Both stay off until you turn them on. The desktop app pairs with the phone by QR code. CarrierPony is not in the F-Droid catalog, so there is no F-Droid link. The published downloads:

While a phone is offline, the envelope waits on a relay and is deleted after delivery. The default relay is api.carrierpony.com. The docs say messages expire from devices after 30 days. On the same network, or when direct delivery can reach the other device, the envelope can skip the relay.

No calls

CarrierPony has no voice or video calls. The site, the docs, the desktop feature list, and the relay API do not describe them. The relay accepts an envelope, returns the inbox, and acknowledges delivery. The desktop page lists what the phone does: one-to-one chats, groups, channels, files, safety numbers, and sealed sender. Calls are not on that list.

SimpleX Chat does have calls, and a self-hosted setup can add a separate server for them. If you need voice on infrastructure you run, CarrierPony will not do it. It is messages and files.

CarrierPony and SimpleX

They look similar from the outside. No account, number, or email. Pairing by invite. The server does not get plaintext. You can run your own server. Both have groups and file transfer. The differences matter more.

  • SimpleX has no long-term user account for the server to keep. CarrierPony’s identity is an OpenPGP fingerprint. The relay routes envelopes by that fingerprint, so there is a stable cryptographic address.
  • In SimpleX, each person can use their own server, and you reach the recipient there. In CarrierPony a relay is its own world: you can only talk to people whose app points at the same address. A different relay, including the official one, will not exchange your envelopes.
  • SimpleX has calls. CarrierPony does not.
  • CarrierPony seals envelopes with OpenPGP, which you can check against GnuPG, and the PGPonyCore engine is Apache-2.0. SimpleX uses its own protocol. An open standard is a gain in transparency. It is not a sign that a young app has had an independent audit.
  • A CarrierPony relay you run cannot wake App Store or Google Play builds. Push needs the publisher’s credentials, which your server does not have. Messages arrive when the app is open and fetches the inbox. The self-host page says this before you start.
  • A CarrierPony file rides the same relay, up to 50 MB. SimpleX files go through a separate XFTP service.

SimpleX is older and already in use. CarrierPony’s public Android repository was created on 22 August 2026, and the relay repository has almost no community yet. Replacing SimpleX with CarrierPony only because both skip accounts is early. Running it beside SimpleX, because you want OpenPGP and you accept young code, is a real choice. How a SimpleX server is built is in that guide. Matrix is a different kind of system: rooms and history live on the server, not as a short-lived envelope. There is a Synapse install guide for that.

OpenPGP on a server you run

A message is encrypted on the phone before it reaches the server. The relay stores a sealed envelope and has no private keys. Renting the VPS does not hand the host the text of the chat. OpenPGP works the same on any machine you control.

That is not “the server learns nothing.” It sees the recipient fingerprint, an opaque message id, a size, and timestamps. With sealed sender, the sender is inside the encryption: the relay is not supposed to learn who sent the envelope, only which mailbox it belongs to. Contents stay sealed. Delivery metadata does not.

The project’s security page draws the same line. CarrierPony protects message and file confidentiality against the network and against the relay. It does not protect a compromised unlocked phone, or someone who can see the screen. Until you compare the safety number, pairing is trust on first use. There is no published independent audit. The developer’s own relay README still lists unfinished hardening: the auth signature currently covers only a one-time nonce, not the request body, and jobs that reap stale devices and expire old envelopes are not done yet. The relay still cannot read the conversation. A sealed envelope and a mature project are different claims.

What you need before installing

The relay is the only server-side piece. Clients stay on phones and computers. The official Docker path needs Linux, a domain, and free ports 80 and 443, because Caddy fetches the certificate. An A record to the public IPv4 must exist before you start, or the certificate will fail. Add an AAAA record if the server has IPv6.

Set the relay address in the app before you pair. After that, only people who use the same address can write to you. The VPS security checklist still applies: SSH keys, updates, and no extra services.

Install Docker Engine

The packages below are from Install Docker Engine on Ubuntu. This relay needs the engine and Compose, because the documented start is docker compose up -d. The set is docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, and docker-compose-plugin. Docker describes the get.docker.com script as a convenience for tests and development, not for a server that will hold messages.

sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world

hello-world should print a greeting and exit. The docker command does not work without sudo until you add a user to the docker group. On a VPS with one administrator, sudo is enough.

Ports that Docker publishes bypass ufw and firewalld. This relay publishes 80 and 443. Rules for published ports belong on the DOCKER-USER chain. See Packet filtering and firewalls.

Your own relay

The source is CarrierPony-Relay, Apache-2.0, and the page Run your own relay. It is a small PHP application: MySQL stores envelopes, and Caddy fetches the certificate. Message cryptography stays on the devices, in PGPonyCore.

git clone https://github.com/norsehorse-dev/CarrierPony-Relay.git
cd CarrierPony-Relay
cp .env.example .env

Open .env and change three things. DOMAIN is your domain. MYSQL_ROOT_PASSWORD and MYSQL_PASSWORD are long passwords of your own, not the sample strings in .env.example. MYSQL_DATABASE and MYSQL_USER can stay carrierpony.

docker compose up -d

The first start loads the database schema. The relay is then at https://your-domain. Ports 80 and 443 must be free, because Caddy binds them. An existing web server on the same machine will collide with this setup.

Without Docker, sudo ./install.sh targets a fresh Ubuntu or Debian server with Apache, MySQL, and PHP. INSTALL.md in the same repository is the manual path. The project recommends Docker when you do not want the relay mixed into the distribution packages.

Point the app at it

In the app, open Settings, then Relay, and enter your relay address. You can set the same thing during first-run setup, before pairing, which is the cleaner path. If you change the relay after you already have contacts, you pair with them again. The official relay and yours do not forward to each other.

This install will not send background notifications to App Store and Google Play builds. The app fetches envelopes while it is open. A build you ship yourself, with your own Apple and Google credentials, could wake the phone, but that is a separate app release, not a relay setting.

What the relay still sees

The README says the relay stores ciphertext and the minimum needed to deliver it: recipient fingerprint, an opaque message id, size, and timestamps. A device proves it holds the key by signing a one-time nonce. There is no name, phone number, or message text. An envelope is deleted once every registered device of the recipient has acknowledged it, or when its TTL passes.

Sealed sender hides the sender inside the envelope. Direct delivery on the same network removes the relay from the path. Neither one hides the recipient fingerprint from the server during the time an envelope is waiting there.

A young project

The openness is real, and the age is short. The relay, the Android client, and the desktop app are published under Apache-2.0. The crypto core is PGPonyCore, shared with PGPony, and described as interoperable with GnuPG. That is the transparency gain next to self-hosting: the format is OpenPGP, not a private envelope invented for one app, and the sealing code can be read.

The age is the other fact. The public Android repository was created on 22 August 2026. The relay has almost no stars, and there is one author. The README itself lists hardening that is not done. Read the code, and do not expect SimpleX’s track record. Where a mistake is expensive, mature SimpleX is the calmer choice. CarrierPony fits when OpenPGP is a deliberate choice.

Questions

Can I call?

No. The site, the docs, and the relay do not describe voice or video calls.

Does the host of my relay read the chat?

Not the text. The envelope is sealed with OpenPGP before it is sent, on any VPS you rent. Delivery metadata stays on that server. Compare the safety number, or you do not know whose key you hold.

Do I have to run a relay?

No. With no change, the app uses api.carrierpony.com. Your own relay is for when the envelopes should sit on your machine and everyone you write to will point at it.

Will I get notifications?

Not from a relay you run, if you use the store builds. Messages are fetched while the app is open.

Categories: Docker Security Web apps
Subscribe to new posts (RSS)

No email, no trackers — just the update feed.

Also available in Russian

Rate this article
Leave a comment