Self-contained payment clearinghouse: Keycloak, control plane, Apache DMZ, remote signer, Kafka, and Postgres.
Check out these repositories next to lpclearinghouse (same parent directory):
| Repo | Purpose |
|---|---|
| builder-sdk | @pymthouse/builder-sdk — control plane signer/OIDC helpers |
| go-livepeer | Remote signer image (scripts/build-remote-signer.sh) |
| pymthouse | Default SIGNER_DATA_DIR keystore (../pymthouse/data) |
| dashboard | Device exchange facade (/api/signer/device/exchange) |
| Role | Auth | Capabilities |
|---|---|---|
| Administrator | CLEARINGHOUSE_ADMIN_CLIENT_ID + secret |
Register apps, issue grants, disable apps, rotate M2M secrets |
| Application owner | Per-app m2m_* client + secret |
Bootstrap signer JWTs, read own balance |
| Application user | Public app_* client login / device flow |
Supplies subjectToken to app M2M bootstrap |
1. Build the remote signer image (once; go-livepeer mainnet,experimental tags for Arbitrum):
cd lpclearinghouse
bash scripts/build-remote-signer.sh2. Build Keycloak SPI (after Java changes):
bash scripts/build-keycloak-spi.sh3. Dev TLS (self-signed DMZ cert):
bash scripts/generate-dev-tls.sh4. Start the stack:
cp .env.example .env # edit ETH_RPC_URL, SIGNER_DATA_DIR as needed
# Root admin API credential (no default); persist it in .env if you prefer.
export CLEARINGHOUSE_ADMIN_CLIENT_SECRET="$(openssl rand -base64 32)"
docker compose up --build -dControl plane + Keycloak start without the hot-path profile. Python/SDK streaming needs hot path — without it, Apache returns 404 on POST /sign-orchestrator-info.
docker compose --profile hot-path up -d5. Apply device-flow realm settings (after Keycloak is up; idempotent):
bash scripts/apply-keycloak-device-flow.shVerify:
bash scripts/verify-compose.sh
docker compose ps remote-signer
docker logs lpclearinghouse-remote-signer-1 2>&1 | tail -5- DMZ:
https://127.0.0.1:8080(TLS; useLIVEPEER_ALLOW_INSECURE_TLS=1in the SDK) - Admin API:
https://localhost:8080/api/clearinghouse/admin/*— see docs/admin-api.md - Dev realm:
keycloak/realm-clearinghouse.json(demo-user/app_demo) - Production baseline:
realm-clearinghouse.base.jsonviaCLEARINGHOUSE_REALM_IMPORT=realm-clearinghouse.base.json
cd control-plane
pnpm install
export CLEARINGHOUSE_DATABASE_URL=postgres://signer:signer_dev_password@127.0.0.1:5432/signer
export CLEARINGHOUSE_ADMIN_CLIENT_SECRET="$(openssl rand -base64 32)"
pnpm serveDashboard uses M2M credentials only (no direct Postgres access):
CLEARINGHOUSE_API_URL=https://localhost:8080
CLEARINGHOUSE_M2M_CLIENT_ID=m2m_...
CLEARINGHOUSE_M2M_CLIENT_SECRET=...Seed on startup when CLEARINGHOUSE_SEED_DASHBOARD_APP=true logs the generated M2M secret once.
Use the prod overrides; compose refuses to start until every secret is set explicitly (no dev defaults):
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -dRequired: KEYCLOAK_ADMIN_PASSWORD, KEYCLOAK_POSTGRES_PASSWORD, SIGNER_POSTGRES_PASSWORD,
CLEARINGHOUSE_ADMIN_CLIENT_SECRET, CLEARINGHOUSE_CREDENTIAL_ENCRYPTION_KEY (openssl rand -hex 32),
SIGNER_OIDC_CLIENT_SECRET, SIGNER_OIDC_CRYPTO_PASSPHRASE. The DMZ validates the JWKS TLS chain
(SIGNER_OIDC_SSL_VALIDATE=On), so use a real certificate — not the dev self-signed chain.