Skip to main content

openbox-backend

Purpose

openbox-backend is the control-plane REST API for the OpenBox platform. It exposes endpoints for user management, agent CRUD, workflow triggers, audit log retrieval, and admin operations. The openbox-fe frontend and any external integrations talk to it directly.

Plane: Control plane.

Ports & endpoints

PortProtocolPurposeExposed via
3000HTTP/RESTPlatform APIIstio Gateway / ALB / NGINX Ingress
9464HTTPPrometheus /metrics scrapeCluster-internal only (not routed via ingress)
3000/healthHTTPLiveness probeK8s kubelet
3000/readyzHTTPReadiness probeK8s kubelet

Public endpoints follow /api/v1/* naming. Full OpenAPI spec at /api/v1/openapi.json (once running).

Runtime

PropertyValue
Container count per pod1
Resource requests500m CPU / 1 Gi RAM
Resource limits1500m CPU / 2 Gi RAM
HPA min → max replicas1 → 8 (target CPU 70%)
Node placementGeneral-purpose CPU pool (no GPU / DB / memory taint)
StatefulSet?No — stateless Deployment (all state in Postgres + Redis)

Bin-packs cleanly on m6i.large and larger. On dev clusters, minReplicas: 1 is safe.

Configuration

Chart values keys (top-level openbox-backend.*)

Authoritative reference: values-reference. Most-configured keys:

KeyPurpose
image.repository / image.tagContainer image + pinned version
replicaCountStatic replica count (ignored when HPA is on)
autoscaling.{enabled,minReplicas,maxReplicas,targetCPUUtilizationPercentage}HPA tuning
resourcesRequests/limits
serviceAccount.annotationsIRSA / Workload Identity annotations
env.KMS_KEY_ARNAWS KMS CMK ARN for envelope encryption
env.OPA_BUNDLE_BUCKETS3 bucket holding OPA policy bundles
db.host / db.port / db.name / db.userSecretRefExternal DB (overrides in-cluster Bitnami PG)

Runtime env vars (populated by chart from values)

  • DATABASE_URL — computed from db.* values or in-cluster Postgres service
  • KEYCLOAK_URL — points at identity-service.<ns>.svc:8080
  • OPA_URL — points at opa-app.<ns>.svc:8181
  • GUARDRAILS_URL — points at guardrails-api.<ns>.svc:8000
  • KMS_KEY_ARN, OPA_BUNDLE_BUCKET — from values
  • NODE_ENV=production

IRSA / IAM permissions required (AWS)

If deploying on EKS, the ServiceAccount must be annotated with an IAM role that grants:

  • kms:Encrypt / kms:Decrypt / kms:GenerateDataKey / kms:DescribeKey on your KMS CMK
  • s3:GetObject / s3:PutObject / s3:DeleteObject / s3:ListBucket on your OPA bundles bucket

See Terraform snippet 04-iam-irsa-roles.tf or the CloudFormation BackendIrsaRole in openbox-infra.yaml.

Dependencies

Downstream (what openbox-backend calls)

TargetProtocolPurpose
identity-service (Keycloak)HTTPS OIDCUser authentication + JWT verification
opa-appHTTP/JSON :8181Authorization decisions
guardrails-apiHTTP/REST :8000ML guardrail checks
openbox-postgresqlJDBC :5432App transactional storage
AWS KMSHTTPS AWS APIEnvelope encryption
AWS S3HTTPS AWS APIOccasional bundle reads

Upstream (what calls openbox-backend)

  • openbox-fe (via ingress) — frontend UI
  • openbox-core-server (cluster-internal) — for admin operations
  • External customer integrations (via ingress) — B2B APIs

Deployment guidelines

Prod

  • Set autoscaling.minReplicas: 2 (never single-pod in prod — avoid single-pod restart downtime)
  • Enable PodDisruptionBudget with maxUnavailable: 1
  • Pin image.tag explicitly (no :latest)
  • Wire IRSA — do NOT bake AWS static credentials into the pod
  • Use external RDS/Aurora for DB — not in-cluster Bitnami PG

Local PoC (S8)

  • autoscaling.minReplicas: 1, maxReplicas: 1 — laptops don't need scale
  • In-cluster Bitnami PG is fine
  • Skip IRSA — chart uses default ServiceAccount

Troubleshooting

Pod CrashLoopBackOff with AccessDeniedException in logs → IRSA missing / wrong. Verify SA annotation: kubectl get sa openbox-backend -n openbox -o yaml | grep eks.amazonaws.com

Backend returns 401 for all requests → Keycloak realm/client mismatch. Log into Keycloak admin → verify realm openbox exists and has a openbox-backend client with correct redirect URIs.

HPA reports <unknown> target CPUmetrics-server not installed. Deploy from official manifests.

High p99 latency on /api/v1/* → Check downstream latency: OPA + Keycloak + guardrails-api. See Data flows → latency targets. Backend has minimal own logic — most latency is external.

Pod Ready but request returns 502 through ingress → Istio sidecar not injected. Verify namespace label: kubectl get ns openbox -o yaml | grep istio-injection. Restart pods after adding the label.