This guide starts the Proofline backend locally and runs the simulator against it.
- Go 1.26.4
- SQLite through the bundled Go SQLite driver dependency
- TOTP generation and validation through the bundled Go OTP dependency
- WebAuthn/FIDO2 ceremony validation through the bundled go-webauthn dependency
- PostgreSQL only when explicitly setting
[metadata].backend = "postgresql"in TOML, or using the equivalentSAFE_METADATA_BACKEND=postgresqlenvironment override - Local disk storage for encrypted uploaded blobs
From the repository root:
For repeatable local configuration, set the bootstrap secret through a private secret file referenced by TOML:
[auth]
bootstrap_secret_file = "/path/to/local-bootstrap-secret"Then run:
go run ./cmd/api --config /path/to/proofline.tomlFor a one-off local shell, an environment override remains supported:
SAFE_AUTH_BOOTSTRAP_SECRET='replace-with-local-bootstrap-secret' \
go run ./cmd/apiDefault listeners:
| Listener | Default address |
|---|---|
| Main API and incident viewer | 127.0.0.1:8080 |
| Private admin dashboard | 127.0.0.1:8081 |
The repository root proofline.toml is a safe local-first example loaded
automatically when running from the repository root. It matches the built-in
defaults and does not include a bootstrap secret.
The private admin web surface is available at
http://127.0.0.1:8081/admin. When a bootstrap secret is configured and no
admin exists, that page shows the first-admin bootstrap screen; after an admin
exists, it shows the admin login screen. Admin accounts must complete
second-factor setup before the local account password workflows or JSON admin
actions are available.
The backend writes local data under ./data by default:
data/
proofline.db
tmp/
incidents/{incident_id}/streams/{stream_id}/{media_type}_{zero_padded_chunk_index}.enc
incidents/{incident_id}/{media_type}_{zero_padded_chunk_index}.enc
The default database file name uses the Proofline data-layout identifier
proofline.db.
Uploads are staged in tmp/, hashed while streaming, and then hard-linked into the final incident path without overwriting existing chunk files. Streamed uploads use the stream-scoped path; the incident-level path remains for legacy unstreamed chunks.
For a new local database, create the first admin account before running the simulator:
curl -sS -X POST http://127.0.0.1:8081/admin/bootstrap \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'bootstrap_secret=replace-with-local-bootstrap-secret' \
--data-urlencode 'username=admin' \
--data-urlencode 'password=replace-with-a-long-local-password'Then restart the server without the bootstrap secret in TOML, the environment, or the secret mount. Complete second-factor setup for the bootstrapped admin before running private admin actions or simulator flows that depend on admin account access.
In another terminal from the repository root:
PROOFLINE_SIM_USERNAME=admin \
PROOFLINE_SIM_PASSWORD='replace-with-a-long-local-password' \
go run ./cmd/simclient --chunks 5 --interval 1s --download-bundleThe simulator:
- logs in with a local account session
- creates an incident
- creates an incident viewer token using the current incident-token route
- creates an audio media stream
- encrypts fake chunk plaintext and uploads the ciphertext envelope with
stream_id - sends periodic checkins
- marks the stream complete
- downloads the completed encrypted stream bundle through the incident viewer when requested
- verifies local decryption of the downloaded bundle when encryption is enabled
The simulator exercises the current generic incident API. It does not set the optional incident-mode metadata fields for emergency incidents, interaction records, safety checks, or evidence notes. It uploads directly to the main API; it does not exercise the separate regional stream-ingress relay.