Skip to main content

Security

What protects your data, the settings that affect security, what you should check on your installation, what our licence server receives and what happens when it is down.

The gateway is installed on your server. Your SMS, your contacts, your conversations and your logs are stored there and nowhere else: we have no copy, no access and no way to read them. That also means part of the security is in your hands: the machine, its network, its updates and its backups.

This page explains what the gateway does to protect your data, which settings affect it, and what you should check yourself.

Your data stays on your server

Data Where it lives Leaves your server?
SMS sent and received, conversations The gateway's database, on your machine Only towards your phones, which send and receive them
Contacts, groups, templates, rules, campaigns Same database Never
Activity log and technical logs Same database, and the gateway's own output Never
Webhook notifications Sent by the gateway Only to the addresses you configured, and without SMS text or full number
Alerts (Settings, Notifications) Sent by the gateway By SMS through your SIMs, by e-mail through your SMTP server, and to the push service of the browsers your users subscribed. Never an SMS text nor a full number
Licence information Sent by the gateway To our licence server, limited to what is listed below

The gateway makes only a few kinds of outgoing connections on its own: to our licence server, to the webhook addresses you created, and, if you switch the alerts on, to your SMTP server and to the push service of the subscribed browsers. Everything else is incoming: your browser, your phones and your applications connect to it. The API reference and the dashboard load nothing from the internet.

How the gateway protects your data

Accounts and sign-in

  • Passwords are stored as a salted, deliberately slow fingerprint (argon2id), never in clear text. They need at least 12 characters, with no composition rule: a long sentence is stronger than a short word with a symbol.
  • Brute force. After 5 failed sign-ins for the same address or the same account, sign-in is locked for 30 seconds, then twice as long after each further failure, up to 15 minutes. A wrong email and a wrong password get the same answer, so no one can test which accounts exist.
  • The first account can only be created with the setup code shown at the end of the installation (sms-gateway setup-code shows it again). A bot that finds your gateway on the internet before you cannot create the administrator account in your place.
  • Changing your email or password asks for the current password. Changing the password signs out every other session of the account.

Sessions

The dashboard keeps you signed in with a cookie that scripts cannot read, valid for 7 days and extended while you use it. Signing out ends the session immediately on the server. Disabling an account or resetting its password ends all its sessions at once. Every change made from the dashboard is protected against forged requests from other websites.

Roles

Each dashboard account has one of three roles, set in Settings > Users and roles:

Role What it can do
Superadmin Everything, including accounts, licence, settings, API keys, backups, phone pairing and routing rules
Operator Send, reply, and manage contacts, templates, rules, campaigns and webhooks. No accounts, settings, keys or backups
Read only See everything, change nothing

The role is checked by the gateway on every request, not only hidden in the interface. The last active superadmin cannot be demoted, disabled or deleted, so the installation always keeps an administrator. Give the superadmin role to as few people as possible. See Users and roles.

API keys

Applications use API keys, never a dashboard account. Each key has a scope (read, send, admin), an optional list of allowed addresses and optional limits per minute and per day. Only a fingerprint of the key is kept, so a copy of the database does not reveal it. Revocation is immediate. See API keys.

Phones

  • A phone is paired by scanning a QR code that is valid for 5 minutes and usable once. A QR code caught in a screenshot is useless afterwards. The manual code offered to phones without a camera follows the same rules, and repeated wrong codes are blocked.
  • Each phone receives its own secret at pairing. Every message exchanged between the phone and the gateway is signed with it and dated, so a message captured on the network cannot be replayed.
  • Unpairing a phone from the Devices page cuts its connection at once.
  • The dashboard shows the SHA-256 fingerprint of the Android app it offers for download, so you can compare it with the one given in your customer area.

Secrets stored by the gateway

Some secrets must be readable again by the gateway: the phones' secrets, the webhook secrets and your licence key. They are encrypted (AES-256-GCM) with a master key that is kept outside the database, in the file secret.key of the data directory (or in GATEWAY_SECRET_KEY if you set it). A copy of the database alone, a backup for example, therefore does not reveal them.

Everything that only needs to be recognised is kept as a fingerprint that cannot be reversed: passwords, sessions, API keys, pairing codes.

The master key is precious. Without it, a restored database loses its phones (to pair again), its webhook secrets and its licence key. Back it up, separately from the database backups: see Backups.

Webhooks

Every webhook call is signed with a secret that only you and the gateway know, and dated, so your application can refuse a forged or replayed call. It carries identifiers, never the text of an SMS or a full number. The gateway refuses to call its own machine or cloud metadata addresses. See Webhooks.

Alerts

Alerts carry a short text only: the phone as you named it, the SIM by its slot, counts. Never the text of an SMS, never a full phone number. Changing where they go is reserved for a superadmin.

  • E-mail goes through the SMTP server you configure. Its password is encrypted like the other secrets and never shown again. With the security set to None, the gateway refuses to send the password to a server that is not on the same machine: choose STARTTLS or TLS for a remote server.
  • Browser notifications (Web Push) travel through the push service of the browser vendor (Google for Chrome and Edge, Mozilla for Firefox, Apple for Safari): that is how a browser receives a notification while the page is closed. Each message is encrypted end to end between your gateway and the browser; the vendor relays bytes it cannot read, and only learns that a notification was sent to that browser. The gateway identifies itself with a key pair generated on your server the first time it is needed; the private half is stored encrypted and never leaves it. The gateway refuses push addresses that point to its own machine or local network.
  • Each user manages the browsers they subscribed, and can unsubscribe one from Settings, Notifications. A deleted account loses its subscriptions.

Logs

Neither the technical logs nor the Activity log ever contain the text of an SMS, a full phone number (they show +261******89), a key, a token or a password. Search terms and numbers typed in URLs are hidden before a request is logged. The HTTPS front end installed with the gateway also strips keys and cookies from its access log. The technical view of the logs is reserved for superadmins.

The connection

  • With a domain name, the installer puts an HTTPS server (Caddy) in front of the gateway, with a free certificate renewed automatically. The gateway itself only listens on the machine's internal address, and is not reachable from outside without HTTPS.
  • The gateway refuses to start with a public http:// address: over plain HTTP on the internet, passwords and sessions would cross the network in clear text.
  • The container runs with a read-only file system, without privileges, and only writes to its data directory.

Settings that affect security

Option Where Default Effect
Installation mode --domain or --lan Installer asked at installation --domain: HTTPS with a certificate, gateway reachable only through it. --lan: plain HTTP on your local network. See below
GATEWAY_PUBLIC_URL .env of the installation set by the installer The address users and phones use. Must be https://, unless it is a local name (.local, localhost)
GATEWAY_INSECURE_COOKIES .env false (domain), true (local network) true lets the browser keep your session over plain HTTP. The session then crosses the local network unencrypted. Changes nothing else
GATEWAY_SECRET_KEY .env empty: secret.key is drawn at first start The master key that encrypts stored secrets. Changing it makes everything encrypted with the old one unreadable
GATEWAY_TRUSTED_PROXIES .env the address of the built-in HTTPS server Which proxies may report the visitor's real address. The address is used by sign-in locks, API key address lists and limits. Too wide a value lets anyone pretend to be any address
GATEWAY_WEBHOOKS_ALLOW_PRIVATE_NETWORKS .env true false forbids webhooks towards your private network, leaving only public addresses
GATEWAY_LOG_RETENTION_DAYS .env 30 How long the Activity log is kept (sign-ins, key changes, failures). Longer helps an investigation, shorter keeps less history
GATEWAY_LOG_LEVEL .env info Detail of the technical logs. No level ever writes SMS text or a full number
Roles of each account Settings > Users and roles the role chosen at creation What each person can do. See Roles
Scope, allowed addresses, limits of a key System > API keys Read, any address, no limit What each application can do, from where and how often
Webhook secret and destination Webhooks page, API secret drawn by the gateway Who receives notifications and how they prove their origin

All the environment variables are described in the installation guide. A variable is changed in the .env file of the installation, then applied by restarting the gateway.

Domain or local network

Mode Address Encryption For whom
--domain (recommended) https://sms.example.com HTTPS end to end Any installation reachable from the internet, or used from outside
--lan http://<machine>.local:8080 None: passwords and sessions travel in clear text on the local network A closed network you trust entirely (office, home), with no access from outside

Never make a --lan installation reachable from the internet (port forwarding on your router, for example). If you need access from outside, reinstall in --domain mode.

What you should do

A checklist to go through after installation, then from time to time.

At installation

  • Install in --domain mode as soon as the gateway is used outside a closed local network.
  • Create the first account right after installation, with the setup code, and a password of at least 12 characters that you use nowhere else.
  • Copy secret.key somewhere safe, away from the server (see Backups).

The server

  • Firewall: in domain mode, open only ports 80 and 443 (plus SSH for you, ideally limited to your address). The gateway's port 8080 must not be reachable from outside. In local network mode, open 8080 on the local network only.
  • Apply the system's security updates, and update the gateway when a new version is published.
  • Keep the server's clock on time (NTP): the signatures of phones and webhooks depend on it.
  • Limit who has administrator access to the machine: whoever is root on the server can read everything, whatever the gateway does.

Accounts and keys

  • One account per person, never shared. The Read only role for those who only consult.
  • As few superadmins as possible, at least two if you want a replacement.
  • Disable the account of someone who leaves: their sessions end at once.
  • One API key per application, with the narrowest scope, allowed addresses when possible and a daily limit.
  • Revoke the keys nobody uses (column Last used of API keys).

Phones

  • Lock the phones with a code and keep them in a place only your team can access: whoever holds a paired phone can read the SMS it receives.
  • Unpair a phone that is lost, replaced or sold, from the Devices page.

Backups

  • Enable scheduled backups and copy them off the server regularly.
  • Protect the copies: a backup contains all your data (messages, contacts, accounts), without encryption. Store it encrypted, or in a place with restricted access.
  • Test a restore from time to time.

Watch

  • Read the Activity log now and then: sign-ins, failed sign-ins, key creations and revocations, phones going offline.
  • Subscribe to device.offline and backup.failed by webhook if you want to be alerted.

What our licence server receives

The gateway contacts our licence server to activate your licence, then about once a day to renew it. Each contact sends exactly this, and nothing else:

Information What it is
The licence key Sent over HTTPS so that we can check it. Our server only stores a fingerprint of it
The version line The major version of the gateway, to check that the key is valid for it
The exact version The build number of your gateway
The machine fingerprint A fingerprint computed on your server. The information it is computed from never leaves
The number of phones How many phones are paired
A counter A number that only increases, to detect a clock moved backwards

No phone number, no message, no contact, no name, no account email and no log is ever sent: the request has no field for them. Our answer is a licence token signed by us, which your gateway verifies with a public key built into it.

If our servers are down

Nothing stops. Your gateway does not depend on us to send or receive a single SMS.

  • An unreachable licence server, a timeout, an error page or an unsigned answer are all treated as "our side is down", and never as a problem with your licence. The dashboard shows an information notice, and the gateway keeps trying: after 15 minutes, 1 hour, 6 hours, then once a day.
  • A licence stays valid 90 days after its last renewal. Beyond that, a banner appears for 30 days, then a lasting warning: sending is never cut because our server did not answer.
  • A licence held for 12 months or more works with no time limit, whether our server answers or not.
  • Only an explicit withdrawal of your licence, signed by us and verified by your gateway, can restrict it. Even then, you keep reading and exporting all your data: only new changes are refused.

The details, and what to do in each situation, are in Licence.

Known limits

We prefer to tell you what the gateway does not do yet:

Subject Today
Two-factor authentication Not available. Use long, unique passwords and limit the number of superadmins
Encryption of the database The database file is not encrypted on disk. It is protected by the server's permissions, and the secrets inside are encrypted separately. Use disk encryption on the server if you need it
Encryption of backups Backups are not encrypted. Protect the copies yourself
Local network mode Plain HTTP: suitable only for a network you trust
Changing the master key No automatic procedure: changing it makes the stored secrets unreadable (phones to pair again, webhook secrets to set again, licence key to enter again)

Search the documentation

Type a few words, then pick a page.