Commit Graph
27 Commits
Author SHA1 Message Date
zeekay 16b4d2b91e k8s: probe /healthz (v1.10.0 renamed /health → /healthz)
The internal API now exposes /healthz returning JSON readiness state.
/health returns 404.
2025-12-28 15:47:33 -08:00
zeekay 0ed4567a90 k8s: rename env LUX_MPC_PASSWORD → MPC_PASSWORD (v1.10.0)
HSM provider reads MPC_PASSWORD by default. Legacy LUX_MPC_PASSWORD
was the old prefix-style env name.
2025-12-28 15:40:56 -08:00
zeekay ab1fec5d1f neutral: drop 'Lux'/'Hanzo' brand prefixes in user-facing strings
MPC and KMS are protocols, not products. The Go module path
github.com/luxfi/mpc remains canonical (location), but user-facing
strings (--help, README, comments, banners) are brand-neutral.
'Lux MPC' → 'MPC', 'Lux KMS' → 'KMS', 'Hanzo MPC' → 'MPC'.
2025-12-28 15:34:18 -08:00
zeekay 6155ebd0c6 k8s: drop --mode consensus, --api-db, --api-kv (v1.10.0 removed these)
mpcd v1.10.0 supports only consensus mode (legacy NATS+Consul removed).
Dashboard API moved to separate mpc-api deployment.
2025-12-28 15:27:41 -08:00
zeekay d42ef84688 k8s: pin StatefulSet to ghcr.io/luxfi/mpc:v1.10.0 (was mpc-api:latest)
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).
2025-12-28 15:21:04 -08:00
zeekay 1dc9a9e6f2 feat(zap): adopt canonical port 9999 across MPC + transport
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.
2025-12-28 15:07:49 -08:00
zeekay 68959865c1 security: harden internal MPC API, enforce TLS-only transport, restrict egress
- 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.
2025-12-28 02:52:46 -08:00
zeekay 6857bdfbda feat: Base framework + consensus default + minimal ops
- Mount chi handlers on Hanzo Base (lifecycle, health, auth framework)
- Default mode: consensus (ZAP p2p) — NATS/Consul deprecated
- compose.yml: 2 services (api + dashboard), SQLite, no external DB
- config.yaml: consensus mode, SQLite-first
- Makefile: simplified build targets, docker compose format
- K8s: kustomization.yaml for idempotent deploys
- Removed listenAddr from NewServer (Base handles listening)
- Legacy NATS/Consul preserved but not default
2025-12-28 02:32:54 -08:00
zeekay 6f4b0d52bb fix: remove all tenant-specific data from MPC infrastructure
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
2025-12-28 02:19:39 -08:00
zeekay 522b59b1a8 fix: remove /api/ prefix from all routes — use /v1/ only
Subdomain routing (mpc.lux.network/v1/) not path prefix (/api/v1/).
Updated: server routes, KMS routes, main.go forwarding, compose,
K8s dashboard config, ingressroute, landing page HTML.
2025-12-28 02:13:02 -08:00
zeekay d81a5c46f7 security: convert secrets.yaml to KMSSecret CRD, remove hardcoded ZapDB password 2025-12-28 00:27:05 -08:00
zeekay 57c0e70099 fix: sign keygen/sign messages in consensus mode, fix API proxy paths
- 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
2025-12-27 11:32:18 -08:00
zeekay 62b1591a23 security: add NetworkPolicies, pod hardening (non-root, read-only rootfs)
- Add NetworkPolicies for lux-mpc namespace (mpc-node, mpc-api, dashboard)
- Add securityContext: runAsNonRoot(uid=1000), readOnlyRootFilesystem,
  drop ALL capabilities, seccomp RuntimeDefault
- Add /tmp emptyDir for read-only rootfs compatibility
2025-12-27 11:05:49 -08:00
zeekay 0232b7df72 feat: standalone mpc-api deployment, implicit OAuth flow, E2E tests
- 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
2025-12-27 10:59:11 -08:00
zeekay a11334d45a feat: OIDC login via Lux ID, fix ingress routing, deploy to lux-k8s
- 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
2025-12-27 10:52:34 -08:00
zeekay d902266df9 fix: remove standalone mpc-api deploy, add imagePullPolicy Always
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.
2025-12-27 10:39:19 -08:00
zeekay 2febb591a4 fix: dashboard deploy, 5-of-3 MPC cluster, pnpm migration
- Dockerfile: use pnpm exclusively (was falling back to npm)
- StatefulSet: 5 replicas with threshold 3 (was 3 replicas, threshold 2)
- deploy.yml: fix namespace typo (lux-bridge -> lux-mpc), add mpc-api restart
- Migrate dashboard from npm to pnpm (pnpm-lock.yaml replaces package-lock.json)

Deploying latest code fixes auth (middleware.ts enforces lux_mpc_session),
dynamic data fetching (dashboard/page.tsx calls API), and Geist font loading
(font files are included in the Next.js build output).
2025-12-27 10:32:42 -08:00
zeekay a8ab0814bc unify all sql images to :latest (PG18)
Single version policy: ghcr.io/hanzoai/sql:latest everywhere.
No version pinning, no backwards compat, always latest stable.
2025-12-27 17:56:23 -08:00
zeekay c5ce6124d9 unify on hanzoai/sql:17-alpine, IngressClass ingress
Standardize all postgres images to ghcr.io/hanzoai/sql:17-alpine
and IngressClass to 'ingress' for white-label portability.
2025-12-27 17:49:45 -08:00
zeekay 7fd512051e feat: replace BadgerDB with ZapDB, remove local replace directives, vendor mode CI/CD
- 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)
2025-12-27 15:30:42 -08:00
zeekay c2537e7cd1 feat: require lux.id OIDC login + Next.js middleware auth guard on dashboard
- 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
2025-12-27 15:24:04 -08:00
zeekay 4413675f33 feat: deploy 3-node MPC consensus cluster with Dashboard API
- 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
2025-12-27 14:04:36 -08:00
zeekay dd20303641 fix: add /healthz to API IngressRoute rule 2025-12-27 13:57:59 -08:00
zeekay 392469a838 feat: add standalone api subcommand for dashboard-only deployment
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.
2025-12-27 13:38:07 -08:00
zeekay 75a30ce8ca fix: go.mod deps, white-label branding, cleanup stale workflows
- 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
2025-12-27 13:24:52 -08:00
zeekay 34b0b1fc29 fix: Dockerfile Go version, public health endpoint, K8s probes
- 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
2025-12-27 13:18:15 -08:00
zeekay 6b38df60a4 feat: MPC wallet dashboard - full-stack implementation
Complete MPC wallet management platform rivaling Fireblocks/Utila/Fordefi:

Backend (Go):
- REST API with 60+ endpoints on chi router (pkg/api/)
- PostgreSQL schema with 13 tables (pkg/db/)
- JWT + MFA auth, bcrypt passwords, API key management
- Policy engine (deny/approve/require_approval)
- Transaction signing flow with approval workflow
- Subscription scheduler for recurring payments
- Payment requests with public pay pages
- Safe + ERC-4337 smart wallet integration (pkg/smart/)
- Rate limiting, webhook delivery (HMAC-SHA256), audit logging
- 27 passing tests (auth, policy engine, middleware)

Frontend (Next.js 14):
- 27 routes with monochrome dark theme (Tailwind + Geist fonts)
- Full API client with JWT auto-refresh
- React Query hooks for all resources
- Pages: dashboard, vaults, wallets, transactions, policies,
  whitelist, team, settings, API keys, webhooks, audit,
  subscriptions, payments, smart wallets

Infrastructure:
- Dockerfiles for API (Go) and dashboard (Next.js standalone)
- compose.yml for local development (PostgreSQL + API + dashboard)
- K8s manifests for mpc.lux.network + cloud.lux.network
- GitHub Actions deploy workflow (build → push GHCR → kubectl apply)
- TLS via cert-manager, Traefik IngressRoute for both domains
2025-12-27 13:11:38 -08:00