luxfi/mpc CI publishes ghcr.io/luxfi/mpc; the legacy mpc-api image
is gone. Pinning the SHA-tagged release ensures rollouts are
deterministic (matches operator pattern).
ZAP is the binary protocol — like HTTP=80 and HTTPS=443, ZAP=9999
across the Lux ecosystem. The DNS name (e.g. zap.kms.svc, zap.mpc.svc,
mpc-node-headless.lux-mpc.svc) disambiguates the service; the port is
always the same.
Changes:
- mpcd --listen default :9651 → :9999
- pkg/transport/{transport,factory}.go: comments and examples
- k8s/mpc-statefulset.yaml: ports + peer template
- k8s/network-policy.yaml: ingress/egress allow rules
- cloudbuild.yaml: EXPOSE
- deployments/customer-3of5/{compose.yml,k8s/*,topology.yaml}: full
template sweep — every peer hostname is distinct, port is uniform 9999
- README.md / LLM.md: example commands
luxd validator P2P (9631 mainnet, 9641 testnet, 9651 devnet) is a
DIFFERENT protocol on a DIFFERENT pod and is unchanged.
- Add bearer token auth to internal MPC API (port 9800): /keygen, /keys,
/backup now require Authorization header. Token from MPC_INTERNAL_API_KEY
env (KMS-synced) or derived from Ed25519 node identity.
- Replace DualModeListener with TLSOnlyListener: plaintext peer connections
are rejected. TLS 1.3 with PQ key exchange is mandatory.
- Add dedicated 20 RPM rate limiter on bridge signing and intent signing
endpoints (separate from global 100 RPM).
- Add body size limit (1MB), read/write timeouts, and 10 RPM rate limiter
to internal MPC API server.
- Restrict K8s NetworkPolicy egress for MPC nodes to peers, postgres,
valkey, DNS, and HTTPS only (was unrestricted).
- Wire cluster-api-key in api-deployment for authenticated proxy to
internal MPC API. Forward as Authorization: Bearer header.
- Remove hardcoded dev JWT_SECRET default from compose.yml (now required).
- Add internal-api-key to KMSSecret CRD and StatefulSet env.
MPC is generic infrastructure — no hardcoded tenant URLs.
- Remove pars.network, zoo.network from OIDC issuers, ingress, TLS
- Remove redacted.com, redacted from CORS, WebAuthn, tests
- CORS/WebAuthn origins now env-driven: MPC_CORS_ORIGINS, MPC_WEBAUTHN_ORIGINS
- Ingress: mpc.lux.network only — tenants route through their own ingress
- Tests updated to match infrastructure-only origin lists
- ConsensusIdentityStore now uses node's own key as initiator key when
no explicit event_initiator_pubkey is configured (consensus mode)
- /keygen HTTP endpoint signs GenerateKeyMessage with node's Ed25519 key
- ConsensusMPCBackend.TriggerKeygen/TriggerSign sign messages before publish
- apiOnlyMPCBackend forwards to /keygen and /health (internal API paths)
instead of /api/v1/keygen and /api/v1/status (dashboard API paths)
- mpc-api deployment points to port 9800 (internal API, no auth required)
instead of port 8081 (dashboard API, auth required)
- /health response uses snake_case keys matching ClusterStatus JSON tags
- Separate mpc-api into its own Deployment with --cluster-url proxy to mpc-node-0
- Switch OAuth from authorization code flow to implicit flow (response_type=token)
- Add Playwright E2E tests for Lux ID login flow and OIDC discovery
- Update CI to apply api-deployment.yaml and wait for mpc-api rollout
- Add OIDC token exchange endpoint (POST /api/v1/auth/oidc) that
validates Lux ID access tokens and issues local MPC API JWTs
- Update dashboard auth callback to do 2-step exchange: get Lux ID
token, then exchange for MPC API JWT via OIDC endpoint
- Fix IngressRoute to use path-based routing (/api/v1 → API, / → dashboard)
- Fix deploy.yml to target lux-k8s cluster (not hanzo-k8s)
- Fix wallet creation page to use api client instead of raw fetch
- Add /api and /healthz to dashboard middleware public paths
The API runs on node-0 of the MPC StatefulSet (--api-db, --api-listen flags).
The standalone mpc-api deployment was broken (missing --node-id in consensus
mode) and unnecessary. Removed from deploy workflow.
Added imagePullPolicy: Always to ensure :latest tag pulls fresh images.
- Replace github.com/dgraph-io/badger/v4 with github.com/luxfi/zapdb/v4 v4.9.2
throughout pkg/kvstore/, pkg/transport/, cmd/mpcd/, e2e/, scripts/
- Rename BadgerPath/BadgerPassword → ZapDBPath/ZapDBPassword in FactoryConfig
- Remove local replace directives from go.mod:
- hanzoai/orm: now uses published v0.3.2 (tagged on GitHub)
- hanzoai/kv-go/v9: now uses published v9.17.2-hanzo.1
- Only remaining replace: agl/ed25519 → luxfi/edwards25519
- Add vendor/ directory (GOWORK=off go mod vendor) for reproducible builds
- Update Dockerfile to golang:1.26-alpine + -mod=vendor build flag
- Update CI/CD to use self-hosted linux/amd64 runners (no cross-compilation)
- Add k8s/valkey.yaml for session KV store
- Update k8s manifests: api-kv support, ZapDB password env, fresh secrets
- Dashboard API and MPC nodes all tested running on cluster (3/3 nodes healthy)
- layout.tsx: fix font loading — use Geist Sans/Mono from geist package
matching tailwind.config.ts CSS variable names (was loading Inter)
- login/page.tsx: replace email/password form with "Continue with Lux ID"
button that redirects to lux.id OIDC authorization endpoint
- auth/callback/page.tsx: new OIDC callback page — validates state param,
exchanges authorization code for tokens at lux.id/oauth/token, stores
JWT in localStorage, redirects to /
- middleware.ts: Next.js edge middleware that checks lux_mpc_session cookie
and redirects unauthenticated requests to /login before page renders
- lib/auth.ts: set lux_mpc_session cookie on setTokens() so middleware can
detect auth state; clear it on clearTokens() (logout)
- k8s/dashboard-deployment.yaml: add NEXT_PUBLIC_IAM_URL and
NEXT_PUBLIC_IAM_CLIENT_ID env vars for lux.id OIDC integration
- Add mpc-statefulset.yaml: 3-node StatefulSet with parallel pod management
- Node 0 serves Dashboard API on :8081 alongside MPC transport
- Auto-generates Ed25519 identity keys per node
- Headless service with publishNotReadyAddresses for peer discovery
- 10Gi PVCs for BadgerDB key share storage per node
- S3 backup + KMS master key env vars (optional)
- Update api-service.yaml to target mpc-node-0 pod
- Update deploy.yml: StatefulSet rollout instead of Deployment
- Replaces old api-only Deployment with full MPC consensus mode
mpcd api --db $DATABASE_URL --jwt-secret $JWT_SECRET --listen :8081
Runs the Dashboard API server without MPC transport, suitable for
cloud dashboard deployments where MPC operations are handled by
separate MPC nodes.
- Fix go.mod: move chi, cors, jwt, pgx from indirect to direct deps
- Add jackc/puddle/v2 and golang.org/x/sync as indirect deps
- Add Dockerfile ARG TARGETARCH for multi-arch builds
- Add white-label hostname branding (mpc.lux.network vs cloud.lux.network)
- Add imagePullSecrets to K8s deployments
- Remove stale docker-publish.yml and docker.yml workflows
- Remove Dockerfile.go123 placeholder
- Fix release.yml Go version to 1.25.5
- Update Dockerfile from golang:1.23-alpine to golang:1.25-alpine
matching go.mod requirement (go 1.25.5)
- Add public /healthz endpoint for K8s liveness/readiness probes
- Update api-deployment.yaml probes to use /healthz instead of
JWT-protected /api/v1/status
- Run go mod tidy to fix missing go.sum entries