| name | livepeer-workload-pipeline |
| description | Deploy a complete Livepeer workload pipeline from first build to production-ready orchestrator/gateway, including remote signer, BYOC capabilities, and payment flow. |
Livepeer Workload Pipeline Deployment (Orchestrator + Gateway + Remote Signer)
Objective
Deploy and operate a Livepeer workload path with minimal ambiguity for another agent.
Decision: do we need remote signer and gateway?
Yes, for the common secure production pattern: separate Ethereum signing from media. Use remote signer + gateway pair.
- Run
-remoteSigner if you want private key isolation, hot-wallet isolation, or any host where signer keys should never touch transcoding paths.
- Run
-gateway if clients call the Livepeer HTTP API (/process/request, /process/stream/*) or if you want offchain request handling.
- For production BYOC with payments, this pair is the expected pattern.
- Do not run remote signer and gateway together in the same binary process.
Lifecycle map
- Build artifacts
- Stand up Ethereum-facing signer service (remote signer)
- Stand up orchestrator (AI or legacy transcoding mode)
- Register capability endpoints
- Stand up gateway (offchain mode with
-remoteSignerUrl)
- Smoke test request path
- Hardening + rollout/observability
Key interaction model (important)
- Gateway asks remote signer for a one-time orchestration identity signature:
POST /sign-orchestrator-info -> {address, signature}
- Gateway uses that signature in
GetOrchestratorInfo against the orchestrator.
- For each payment cycle, gateway asks remote signer to issue payment:
POST /generate-live-payment -> {payment, segCreds, state}
- Gateway forwards tickets to orchestrator:
POST {orch}/payment with headers Livepeer-Payment and Livepeer-Segment.
Remote signer and gateway behavior to remember
-remoteSigner=true is a standalone node mode.
- It requires on-chain mode (
-network not offchain).
- Gateway with
-remoteSignerUrl is offchain by default and should omit -network, -ethUrl, -ethPassword, etc.
- If
-remoteSignerUrl is set, gateway startup requires signer reachability and will fail fast if missing.
- In this branch, orchestrator discovery is not provided by remote signer discovery endpoint for orchestrator selection; use
-orchAddr or -orchWebhookUrl on gateway.
- Remote signer pricing controls happen via gateway-like PM knobs on the signer (e.g.,
-maxPricePerUnit, -pixelsPerUnit, -maxPricePerCapability, -maxTicketEV, -maxTotalEV).
- Pay attention to these status semantics:
480 from remote signer -> refresh orchestrator session info and retry.
481 from remote signer -> orchestrator price above configured cap, select alternate orchestrator.
Build/install prerequisites
- Go 1.20+ for
go-livepeer compile.
git, make, ffmpeg where needed.
- ETH JSON-RPC endpoint for signer/orchestrator chain mode.
- Keystore + password or equivalent Ethereum account source.
- TLS or private-network transport for signer/gateway control plane.
Repository and checkout
go-livepeer (core)
cd /opt
git clone https://github.com/livepeer/go-livepeer go-livepeer
cd go-livepeer
make livepeer
Optional python gateway
- Use only if you intentionally need the Python variant implementation.
- Install/build per project docs in that repo before configuring process supervisor/containers.
Port conventions (safe defaults)
- Orchestrator/gateway default HTTP RPC:
8935
- Gateway HTTP ingest API:
9935
- Use explicit host binds (
127.0.0.1 for private links, 0.0.0.0 for public)
- Keep signer and signer-gateway traffic private to VPC/private subnet.
Phase 1: remote signer setup (required for secure baseline)
mkdir -p /etc/livepeer/{signer,orch,gateway}
./livepeer \
-remoteSigner \
-network arbitrum-one-mainnet \
-ethUrl https://<rpc-endpoint> \
-ethKeystorePath /etc/livepeer/signer/keystore/UTC--... \
-ethPassword /etc/livepeer/signer/keystore-password.txt \
-httpAddr 127.0.0.1:7936 \
-maxPricePerUnit 0 \
-pixelsPerUnit 1000000 \
-maxTicketEV 3000000000000 \
-v 6
Operational checks before moving on
- Curl signer startup endpoint manually:
curl -s -X POST http://127.0.0.1:7936/sign-orchestrator-info | jq .
- Confirm JSON includes
address and signature.
- Confirm signer can derive ticket params from your on-chain orchestrator set (chain connectivity healthy).
Phase 2: orchestrator setup
Run your orchestrator node with chain flags and gateway compatibility.
./livepeer \
-orchestrator \
-network arbitrum-one-mainnet \
-ethUrl https://<rpc-endpoint> \
-ethKeystorePath /etc/livepeer/orch/keystore/UTC--... \
-ethPassword /etc/livepeer/orch/keystore-password.txt \
-ethOrchAddr 0xYourOrchestratorAddress \
-orchSecret <strong-shared-secret> \
-serviceAddr orch-public.example.com:8935 \
-pricePerUnit 1 \
-pixelsPerUnit 1000000 \
-httpAddr 0.0.0.0:8935 \
-v 6
BYOC worker mode extras
- Include AI/container fields only if needed for your workload.
- Expose container endpoints for capability registration and processing requests.
Register BYOC capability
After orchestrator starts, register each external capability:
curl -X POST https://byoc_orchestrator:8935/capability/register \
-H "Authorization: <orch-secret>" \
-H "Content-Type: application/json" \
-d '{"name":"text-reversal","url":"http://byoc_reverse_text:5000","capacity":1,"price_per_unit":0,"price_scaling":1,"currency":"wei"}'
Unregister via POST /capability/unregister with same payload shape and auth when needed.
Phase 3: gateway setup
./livepeer \
-gateway \
-httpAddr 0.0.0.0:9935 \
-httpIngest \
-orchAddr byoc_orchestrator:8935 \
-remoteSignerUrl http://127.0.0.1:7936 \
-gatewayHost gateway-public.example.com \
-v 6
Discovery options (choose one in production):
- Static:
-orchAddr <orch1>,<orch2>
- Dynamic:
-orchWebhookUrl https://orchestrator-webhook
Important: do not set -network on gateway in this model (offchain mode is used).
Phase 4: traffic tests
Synchronous BYOC request
- Build
Livepeer header (base64 of JSON request/capability/timeout).
CAP="$(python - <<'PY'
import base64, json
print(base64.b64encode(json.dumps({'request':'{"run":"echo"}','capability':'text-reversal','timeout_seconds':30}).encode()).decode())
PY)"
curl -X POST http://localhost:9935/process/request/text-reversal \
-H "Content-Type: application/json" \
-H "Livepeer: $CAP" \
-d '{"text":"Hello Livepeer"}'
Stream ingestion API (AI stream)
curl -X POST http://localhost:9935/process/stream/start \
-H "Content-Type: application/json" \
-H "Livepeer: <base64-livepeer-header>" \
-d '{"stream_name":"demo"}'
Then exercise one of:
POST /process/stream/{streamId}/whip
POST /process/stream/{streamId}/rtmp
GET /process/stream/{streamId}/status
GET /process/stream/{streamId}/data
POST /process/stream/{streamId}/stop
Payment/session health checks
- Observe logs for remote signer events:
HTTP 480 => refresh info and retry with new orchestrator info
HTTP 481 => pricing exceeds cap, switch candidate orchestrator
- If
numTickets ... exceeds maximum of 100, raise -maxTicketEV on remote signer or tune pipeline EV policy.
- Ensure signer and gateway are on compatible protobuf job type semantics for your workload.
Common pitfalls and fixes
- Remote signer returning connection refused on gateway startup: gateway will exit fast; check host/port, scheme, and
-remoteSignerUrl reachability.
- Gateway configured with on-chain flags and remote signer URL: chain config is ignored for signer tasks and can create confusion.
- Orchestrator selection fails: if no
-orchAddr and no -orchWebhookUrl, gateway has no sources.
- 481 loops: signed cap not enough for actual price. Increase signer cap settings or target a lower priced orchestrator.
- Missing capability requests: capability registration path must use orchestrator internal secret and runner visibility.
Minimal Compose topology (recommended)
Run signer and gateway on private subnet, orchestrator on workload subnet if needed. Keep signer private, require mTLS or ACL between gateway and signer, and keep signer unauthenticated only on loopback.
Production hardening checklist
- Separate keyrings (
datadir/keystore mounts) per role.
- Restrict
-httpAddr listeners to private networks where possible.
- Prefer service discovery webhook only from trusted infra.
- Add log shipping for payment failure codes and orchestration retries.
- Rotate secrets; do not keep passwords inline in command lines (use file-based or secret injection).
- Capture incident playbook:
- signer unavailable
- orchestrator unreachable
- payment too many tickets
- manifest id mismatch/refresh cycle
Final decision criteria before “go-live”
curl against signer returns valid signature payload.
- Orchestrator exposes and maintains
/capability/register and processing endpoints.
- Gateway accepts orchestrator info and successfully completes at least one
/process/request and one /process/stream/start flow.
- 24h steady-state runs without 480/481 spikes under expected load.
References and branch notes
- Your research snapshot path:
/Users/geo/Projects/artifacts/_archive/research for embody future features(pass somehow to head engineer when we are ready for this)/research/livepeer-remote-signer-2026-02-11
- PRs to cross-check when integrating upstream: