evertap

Security

evertap is for development data, not production. It still holds the root keys of every database and bucket service it runs, and it takes sign-ins over the network, so this page sets out what it exposes and what it trusts. To report a vulnerability, follow SECURITY.md.

What listens where

On the machine running evertap:

Whatnetwork and cloudflarelocalBefore setup
The UI and API (EVERTAP_PORT, 8080)The address chosen in setup127.77.0.1127.0.0.1
Database and bucket entries127.0.0.1: 6432, 3306, 6379, 9000, 3900127.77.0.1: 5432, 3306, 6379, 9000, 3900127.0.0.1
The services in Docker127.0.0.1, on ports Docker picksThe sameThe same
The CLI's socketevertap.sock in the data directoryThe sameThe same
Buckets reached from anywhere (9900)Beside the UI, once buckets have an addressNoneNone
  • Only the UI ever listens where other machines can connect, and only in network mode when you choose such an address. In cloudflare mode, other machines reach it through your tunnel. Databases and buckets are reached from other machines only through the UI's address, by a signed-in evertap connect.
  • The one exception is a bucket you make reachable from anywhere, through the address you give buckets (Signed links that work anywhere). Its entry listens beside the UI, on its own port, so evertap tells its requests apart by where they arrive, not by a Host header anyone can send. It answers only for those buckets, and each request still needs a signature made with that bucket's key. It listens on another address of the machine only when you chose one for the UI; for every interface it stays on 127.0.0.1.
  • evertap never asks Docker to publish on 0.0.0.0. Docker's firewall rules bypass ufw, so a port Docker published there would be open whatever ufw says.
  • Docker Engine before 28.0, and 28.2 to 28.3.2 once firewalld reloads, lets other machines on the same network reach what Docker publishes on 127.0.0.1. The Doctor warns about it; update Docker.
  • Listening on every interface of a machine with an address the internet routes to opens the sign-in page to the internet over plain HTTP. Setup, Settings, and the log warn about it.
  • The engines' own consoles and admin APIs, such as RustFS's console and Garage's admin API, are never published. evertap alone holds their keys.

On a laptop, evertap connect listens on 127.77.0.1 alone unless you pass --host.

Signing in

Every request that arrives over the network needs a sign-in, in every mode and from every address, including 127.0.0.1: a tunnel or proxy on the same machine arrives from there too. Only two things skip it:

  • The CLI on the machine running evertap, over evertap.sock. The data directory is readable by the user running evertap alone, and so is the socket in it.
  • Demo mode (EVERTAP_DEMO=1), which has no real data and no sign-in.

evertap has no passwords. There are two kinds of sign-in:

WhoHow it signs inWhat it sends
A browserA signed-in browser approves the code it shows, or a one-time link from evertap signin-link or evertap setupA session cookie
A paired CLI, or a scriptevertap login, approved in a signed-in browser; or an API key created in the UIAuthorization: Bearer <token>
  • A cookie works only on the UI's API, which also needs a header that only evertap's own pages send, so another site cannot act as you. A token works only on the CLI's API. Neither works on the other's.
  • The session cookie is HttpOnly and SameSite=Strict, and Secure over HTTPS. A browser stays signed in for 30 days after its last request.
  • Codes and sign-in links expire after 10 minutes, and a link works once. The approval page shows the request's address, the machine's name, and when it was made: approve only a code you just saw yourself.
  • Approving sign-ins, creating API keys, and revoking are for a person in the UI. A paired CLI or an API key can do everything else, but cannot add or remove clients, so a leaked token cannot grant itself more access.
  • A protected resource cannot be deleted. From the CLI or the API, protection has to be turned off first, as a separate step (evertap unprotect).
  • evertap keeps tokens and API keys only as SHA-256 hashes. An API key is shown once, when it is created.
  • Clients in the UI lists every browser, CLI, and API key, with where it was last used from. Revoking one ends it at once; its open database connections close within about a minute.
  • While sign-ins wait for approval, each address can hold 5 of them, so one caller cannot keep everyone else from signing in. evertap signin-link is never limited.

The CLI saves its token in ~/.config/evertap/config.json, readable by your user alone. Anyone with that file acts as you. evertap logout revokes it.

Addresses and names evertap trusts

  • evertap never trusts a request because of where it comes from.
  • It answers only to requests that name its own address, localhost, an IP address, or in network mode its name on your network. A web page that points its own hostname at your machine is turned away.
  • In network and cloudflare mode, a request from loopback or from a Docker bridge network comes from a proxy, a tunnel, or a container on this machine, so evertap takes the caller's address from the last entry of X-Forwarded-For. From anywhere else, and in local mode, it takes the connection's own address. A proxy on this machine must add the address it saw to X-Forwarded-For, not pass on what the caller sent, or callers can pretend to be someone else (Reverse proxies).

Plain HTTP

evertap serves plain HTTP and leaves HTTPS to a proxy or a tunnel. Over plain HTTP, anyone who can watch the traffic can read sign-in cookies and tokens and act as you. Use plain HTTP only on a network you trust, or one Tailscale encrypts. evertap login warns when the address is http:// and not on loopback.

What the data directory holds

The data directory, ~/.local/share/evertap unless EVERTAP_DATA_DIR says otherwise, is readable by the user running evertap alone (mode 0700). Inside, in plain text:

  • evertap.db: every database password and bucket key evertap handed out, the root and admin keys of every service, the token hashes, and the settings. Before an upgrade changes its format, a copy is kept beside it as evertap.db.v<version>-<time>.bak, with the same contents.
  • postgresql/pgbouncer/userlist.txt and pgbouncer.ini: each PostgreSQL database's password, for PgBouncer. These files are readable by others (0644) so that PgBouncer can read them; the directory above keeps other users out.
  • mysql/proxysql.cnf: ProxySQL's admin password.
  • garage/garage.toml: Garage's admin token and secret.

Treat a backup or a copy of the data directory as you would those passwords. The data itself is in Docker volumes whose names start with evertap, which a backup of the data directory does not include.

Anyone who can use Docker on that machine can read the same secrets from the containers, and can do anything else as root. Add to the docker group only users you would trust with root.

Data stays on one machine

evertap sends nothing to anyone else: no telemetry, and no account. It downloads the engines' images from Docker Hub the first time it needs them, pinned by digest.

Edit on GitHub

The evertap name and logo are not licensed with the code (section 6 of the license). You may use them to refer to evertap, but not to name or brand your own product or service, or in a way that suggests evertap made or endorses it, without permission.

evertap is an independent project. It is not affiliated with, endorsed, sponsored, supported, or certified by the owners of the software it runs, and it uses their names only to say which software that is.

  • Postgres, PostgreSQL and the Slonik Logo are trademarks or registered trademarks of the PostgreSQL Community Association of Canada, and used with their permission.
  • MySQL is a registered trademark of Oracle and/or its affiliates.
  • Redis is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd.
  • RustFS is a trademark of RustFS, Inc.
  • Other names, including Garage, may be trademarks of their respective owners.

On this page