This guide starts the Proofline backend locally and runs the simulator against it.
- Go 1.26.5
- 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. For an established account with active TOTP, provide the current
short-lived code to the simulator through PROOFLINE_SIM_TOTP_CODE; the code is
used only to verify the new session and is not printed.
In another terminal from the repository root:
read -rsp 'Current simulator TOTP code: ' PROOFLINE_SIM_TOTP_CODE
export PROOFLINE_SIM_TOTP_CODE
PROOFLINE_SIM_USERNAME=admin \
PROOFLINE_SIM_PASSWORD='replace-with-a-long-local-password' \
go run ./cmd/simclient --chunks 5 --interval 1s --download-bundle
unset PROOFLINE_SIM_TOTP_CODEThe 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.