diff --git a/docs/lamassu-future-peer-auth.md b/docs/lamassu-future-peer-auth.md new file mode 100644 index 0000000..88cc9fc --- /dev/null +++ b/docs/lamassu-future-peer-auth.md @@ -0,0 +1,167 @@ +# Lamassu Server: Future Peer Authentication Implementation + +This document describes how to implement PostgreSQL peer authentication (Unix socket) for the lamassu-server module in the future. + +## Current Limitation + +The lamassu-server's `constants.js` builds the database URL from individual environment variables: + +```javascript +const POSTGRES_USER = process.env.POSTGRES_USER +const POSTGRES_PASSWORD = process.env.POSTGRES_PASSWORD +const POSTGRES_HOST = process.env.POSTGRES_HOST +const POSTGRES_PORT = process.env.POSTGRES_PORT +const POSTGRES_DB = process.env.POSTGRES_DB + +const PSQL_URL = `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}` +``` + +This means: +- `DATABASE_URL` environment variable is **not supported** +- Unix socket connections are **not possible** (setting `POSTGRES_HOST=/run/postgresql` produces invalid URL syntax) +- Password authentication via TCP is **required** + +## Required Upstream Changes + +### 1. Modify `packages/server/lib/constants.js` + +Add support for `DATABASE_URL` environment variable: + +```javascript +const POSTGRES_USER = process.env.POSTGRES_USER +const POSTGRES_PASSWORD = process.env.POSTGRES_PASSWORD +const POSTGRES_HOST = process.env.POSTGRES_HOST +const POSTGRES_PORT = process.env.POSTGRES_PORT +const POSTGRES_DB = process.env.POSTGRES_DB + +// Support DATABASE_URL for Unix socket connections (peer auth) +const PSQL_URL = process.env.DATABASE_URL || + `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}` +``` + +### 2. Update nix-bitcoin module + +Once upstream supports `DATABASE_URL`, update `modules/lamassu-lnbits.nix`: + +#### Remove password secret + +```nix +nix-bitcoin.secrets = { + lamassu-key.user = cfg.user; + lamassu-cert = { + user = cfg.user; + permissions = "444"; + }; + # Remove: lamassu-db-password +}; + +nix-bitcoin.generateSecretsCmds.lamassu = '' + makeCert lamassu '${nbLib.mkCertExtraAltNames cfg.certificate}' + # Remove: makePasswordSecret lamassu-db-password +''; +``` + +#### Remove lamassu-postgres-setup service + +Delete the entire `systemd.services.lamassu-postgres-setup` block. + +#### Simplify PostgreSQL config + +```nix +services.postgresql = { + enable = true; + package = pkgs.postgresql_15; + ensureDatabases = [ cfg.database.name ]; + ensureUsers = [ + { + name = cfg.database.user; + ensureDBOwnership = true; + } + ]; + # No custom authentication needed - default peer auth works +}; +``` + +#### Update service wrapper scripts + +```nix +lamassuEnv = pkgs.writeShellScript "lamassu-env" '' + #!/bin/bash + set -euo pipefail + export PATH=${pkgs.nodejs_22}/bin:$PATH + # Use Unix socket for peer authentication (no password needed) + export DATABASE_URL="postgresql://${cfg.database.user}@/${cfg.database.name}?host=/run/postgresql" + export NODE_PATH=${cfg.package}/node_modules:${cfg.package}/packages/server/node_modules + cd ${cfg.package} + exec "$@" +''; +``` + +#### Remove password-related env vars + +Remove from service `environment` blocks: +- `POSTGRES_HOST` +- `POSTGRES_PORT` +- `POSTGRES_PASSWORD` + +## Benefits of Peer Authentication + +1. **No password to manage** - No secrets generation, storage, or rotation +2. **More secure** - Authentication handled by OS kernel, not application +3. **Simpler module** - ~55 fewer lines of code +4. **Consistent with btcpayserver** - Same pattern used by other nix-bitcoin modules + +## Architecture Comparison + +### Current (password auth via TCP) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ lamassu-server │ +│ └── connects to 127.0.0.1:5432 with password │ +│ │ │ +│ ▼ │ +│ PostgreSQL (TCP) │ +│ └── validates password via md5 auth │ +└─────────────────────────────────────────────────────────────┘ + +Requires: + - lamassu-db-password secret + - lamassu-postgres-setup service + - POSTGRES_HOST, POSTGRES_PORT, POSTGRES_PASSWORD env vars +``` + +### Future (peer auth via Unix socket) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ lamassu-server (runs as user: lamassu-server) │ +│ └── connects to /run/postgresql socket │ +│ │ │ +│ ▼ │ +│ PostgreSQL (Unix socket) │ +│ └── validates OS user matches DB user (peer auth) │ +└─────────────────────────────────────────────────────────────┘ + +Requires: + - Nothing extra! Default NixOS PostgreSQL config works. +``` + +## DATABASE_URL Format for Unix Socket + +The node-postgres library supports Unix sockets via the `host` query parameter: + +``` +postgresql://username@/database?host=/run/postgresql +``` + +Components: +- `username` - PostgreSQL user (must match OS user for peer auth) +- `database` - Database name +- `host=/run/postgresql` - Path to Unix socket directory + +## Reference + +- btcpayserver module uses peer auth: `postgres=User ID=btcpayserver;Host=/run/postgresql;Database=btcpaydb` +- node-postgres Unix socket docs: https://node-postgres.com/features/connecting +- pg-promise (used by lamassu): https://github.com/vitaly-t/pg-promise