Skip to content

Deploy Targets

Deploy targets let your tenants ship the apps Forginate builds to real infrastructure. Two mechanisms exist:

  1. Kubernetes deploy agent — the customer runs a small agent in their own cluster that connects outbound to your Forginate instance over WebSocket.
  2. AWS account vending — Forginate creates and manages dedicated AWS member accounts (ECS deploys) under your AWS Organization.

Both are optional. A control-plane-only install works fine without either.

Kubernetes deploy agent

How it connects

The agent (ghcr.io/the-pizza/forginate-deploy-agent, chart at deploy/helm/forginate-deploy-agent) opens an outbound WebSocket to the api-gateway at /agent/ws on your public domain. The customer's cluster needs no inbound access — your gateway pushes deploy commands down the socket (relayed from the orchestrator via Redis pub/sub on the deploy:cmd channel).

Customer installation

The tenant creates a deployment target in the Forginate UI, which shows an enrollment key once. Then, on their cluster:

bash
helm upgrade --install forginate-agent deploy/helm/forginate-deploy-agent \
  -n forginate-agent --create-namespace \
  --set forginateUrl=https://forginate.example.com \
  --set enrollmentKey=<key-shown-once>

Values reference:

KeyDefaultNotes
forginateUrl"" (required)Your Forginate base URL
enrollmentKey""Lands in a Secret either way; for GitOps prefer…
existingSecret""Name of a pre-created Secret with key enrollment-key
image.repository / tagghcr.io/the-pizza/forginate-deploy-agent / latest
imagePullSecrets[]docker-registry Secret names
rbac.scopeclustercluster or namespaces
rbac.namespaces[]Used when scope is namespaces; namespaces must pre-exist

Env consumed by the agent: FORGINATE_URL, ENROLLMENT_KEY, AGENT_VERSION, POD_NAMESPACE (self-protection: the agent refuses commands targeting its own namespace), HEALTH_PORT (default 8087), LOG_LEVEL.

Agent RBAC scope

  • rbac.scope: cluster (default): a ClusterRole allowing deploy/upgrade/teardown of a tight allowlist — Deployments/StatefulSets/ReplicaSets, Services/ConfigMaps/ Secrets/PVCs, Ingresses, HPAs, namespace create, plus read-only pods/logs/events/ nodes and pods/exec + nodes/proxy for the ops dashboards. Explicitly no RBAC objects, no ServiceAccounts, no DaemonSets, no webhooks, no CRDs.
  • rbac.scope: namespaces: the same allowlist as namespace-scoped Roles, restricted to rbac.namespaces (which must already exist).

The agent runs a single replica with strategy: Recreate — two live sockets would fight over state. Its liveness probe tolerates long disconnects (the reconnect loop handles them); it only restarts on a hung process.

Server-side requirements

Only that /agent/ws WebSockets survive your edge (see Ingress & Domains) and that Redis is up — the orchestrator publishes agent commands via Redis.

AWS account vending

The orchestrator can vend dedicated AWS member accounts for tenants and run ECS deploys into them, including cost readback. This requires an AWS Organizations management account you control.

IAM user

Create an IAM user in the management account with:

  • organizations:CreateAccount, organizations:DescribeAccount, organizations:ListAccounts — account vending
  • sts:AssumeRole on OrganizationAccountAccessRole in member accounts — the standard cross-account admin role AWS Organizations creates; all in-account work happens through it
  • ce:GetCostAndUsage — per-account cost readback shown to tenants

Secrets

bash
# Management-account IAM user credentials (orchestrator env:
# AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY, mounted optional:true)
kubectl -n forginate create secret generic forginate-aws \
  --from-literal=access-key-id="AKIA…" \
  --from-literal=secret-access-key="…"

# Private-registry pull credentials for ECS tasks (optional — public images
# pull anonymously without it). Mirrored into each customer account as a
# Secrets Manager secret named forginate/registry-pull and wired as
# repositoryCredentials on the task definitions.
kubectl -n forginate create secret generic forginate-registry-pull \
  --from-literal=username="<registry-user>" \
  --from-literal=password="<packages-read-token>"

kubectl -n forginate rollout restart deploy/orchestrator

Both secrets are optional: true — the orchestrator boots without them and AWS features stay dark until they exist.

Management-account credentials are crown jewels

This IAM user can create accounts and assume admin in every vended member account. Scope its policy to exactly the actions listed, rotate the access key on your normal cadence, and never reuse it for anything else. If you don't need AWS vending, simply don't create forginate-aws.

Choosing between the two

k8s deploy agentAWS vending
Customer prerequisiteany k8s cluster + Helmnone (you supply AWS)
Network modeloutbound WebSocket from customeryour orchestrator → AWS APIs
Isolationcustomer's own clusterdedicated AWS account per tenant
Your operational burdennone per-tenantAWS Org, billing, cost passthrough

Most self-hosters start with the deploy agent and add AWS vending only if they want to offer managed hosting.

Forginate — build software with an AI factory.