Skip to main content
The agent is a single container image that runs inside your perimeter. It extracts from your sources, builds canonical models, and writes to your destinations. It connects outbound to op-data’s control plane and Temporal cluster — no inbound ports need to be opened.

What the agent is

A NestJS app that embeds a Temporal worker and a small HTTP server. It depends on two things you provide:
  1. An agent Postgres database for its own state (connector credentials, migration tracking). One database per deployment. Small — tens of MB is typical.
  2. Outbound HTTPS (443) to the URLs printed during deployment provisioning. In most environments, no additional egress rules are needed.
The agent does not require Redis, a cloud secret manager, or an inbound load balancer.

Prerequisites

  • Docker 24+ (or any OCI runtime — Kubernetes, ECS, Nomad, Fly, Railway all work).
  • A Postgres 14+ database the agent can reach. A 1 vCPU / 1 GB instance is ample for v1.
  • Outbound 443 to *.op-data.com and your Temporal address.
  • An agent deployment provisioned in the op-data UI (see Quickstart → Provision an agent deployment).

Environment variables

Required:
VariablePurpose
OP_TENANT_IDYour org ID. Also used as the Temporal task-queue suffix (tenant-{orgId}).
OP_CONVEX_URLURL of the op-data control plane. Provided during provisioning.
OP_WORKOS_AUTHKIT_BASE_URLWorkOS AuthKit base URL. Provided during provisioning.
OP_WORKOS_CLIENT_IDWorkOS M2M client ID for this deployment.
OP_WORKOS_CLIENT_SECRETWorkOS M2M client secret for this deployment.
OP_AGENT_DATABASE_URLPostgres connection string for the agent’s own state database.
Optional:
VariableDefaultPurpose
OP_TEMPORAL_ADDRESSlocalhost:7233Temporal frontend address. Set to the value shown during provisioning.
OP_TEMPORAL_NAMESPACEdefaultTemporal namespace.
OP_TEMPORAL_TLS_CERTBase64-encoded client certificate for mTLS to Temporal. Must be set together with OP_TEMPORAL_TLS_KEY.
OP_TEMPORAL_TLS_KEYBase64-encoded client private key.
OP_HEALTH_PORT8080Port the HTTP server listens on (/healthz, /metrics).
OP_CANONICAL_OUTPUT_BASE_URIBase URI for canonical model output (e.g. s3://my-bucket/canonical/). Required before the first sync.
AWS_REGION / AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN / AWS_ENDPOINT_URL_S3Standard AWS SDK variables. Needed only if the canonical sink writes to S3. IAM roles on the host are also supported.
The agent validates its environment on boot and refuses to start with a detailed error listing every missing or malformed variable.

Docker

docker run --detach --restart=always \
  --name op-data-agent \
  -e OP_TENANT_ID=org_... \
  -e OP_CONVEX_URL=https://api.op-data.com \
  -e OP_WORKOS_AUTHKIT_BASE_URL=https://auth.op-data.com \
  -e OP_WORKOS_CLIENT_ID=client_... \
  -e OP_WORKOS_CLIENT_SECRET=sk_... \
  -e OP_TEMPORAL_ADDRESS=temporal.op-data.com:7233 \
  -e OP_AGENT_DATABASE_URL=postgres://op_agent:***@db:5432/op_agent \
  -p 8080:8080 \
  ghcr.io/op-data/agent:latest

Kubernetes

A minimal Deployment. Mount the WorkOS secret and the agent database URL from a Secret; keep non-secret config in a ConfigMap.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: op-data-agent
spec:
  replicas: 1
  selector:
    matchLabels: { app: op-data-agent }
  template:
    metadata:
      labels: { app: op-data-agent }
    spec:
      containers:
        - name: agent
          image: ghcr.io/op-data/agent:latest
          ports:
            - containerPort: 8080
          envFrom:
            - configMapRef: { name: op-data-agent-config }
            - secretRef: { name: op-data-agent-secrets }
          livenessProbe:
            httpGet: { path: /healthz, port: 8080 }
            periodSeconds: 10
          readinessProbe:
            httpGet: { path: /healthz, port: 8080 }
            periodSeconds: 5
Run a single replica per deployment. The Temporal worker is horizontally scalable, but v1 is sized for a single agent per tenant; contact us if you need to scale out.

Health checks

  • GET /healthz returns 200 ok once the Temporal worker has connected. Use it for liveness and readiness probes.
  • GET /metrics is reserved for a Prometheus endpoint — no metrics are exposed yet.

Upgrading

Upgrades are image-tag swaps. The control plane cannot execute code on your agent remotely; you control the rollout by changing the image tag in your Deployment / Docker run command. Workflow definitions are versioned so in-flight executions replay safely across agent upgrades. We recommend pinning to a specific tag (e.g. ghcr.io/op-data/agent:2026.4.2) rather than latest in production.

Troubleshooting

Agent stays on “Pending” in the UI. Check the agent’s logs for temporal-worker connected and convex authed. The most common causes are a mistyped OP_TEMPORAL_ADDRESS or a WorkOS client secret that has been revoked. Reprovision the deployment and relaunch with the new values. Invalid agent environment on boot. The container exits with a list of every invalid variable. Fix them and restart — the agent does not partially start. OP_TEMPORAL_TLS_CERT and OP_TEMPORAL_TLS_KEY must be set together. If you enable mTLS, you must provide both. They must be base64-encoded PEM blobs (including headers). Preview queries fail with connection refused. The agent runs the query — not the control plane. The source database must be reachable from the agent’s host, not from op-data’s network. connection is not found when running a sync. Credentials live on the agent. If you rebuilt the agent’s Postgres database without restoring it, recreate the connections from the UI — the Convex metadata remains but the secret payload was lost.