Deploy Targets
Deploy targets let your tenants ship the apps Forginate builds to real infrastructure. Two mechanisms exist:
- Kubernetes deploy agent — the customer runs a small agent in their own cluster that connects outbound to your Forginate instance over WebSocket.
- 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:
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:
| Key | Default | Notes |
|---|---|---|
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 / tag | ghcr.io/the-pizza/forginate-deploy-agent / latest | |
imagePullSecrets | [] | docker-registry Secret names |
rbac.scope | cluster | cluster 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 andpods/exec+nodes/proxyfor 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 torbac.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 vendingsts:AssumeRoleonOrganizationAccountAccessRolein member accounts — the standard cross-account admin role AWS Organizations creates; all in-account work happens through itce:GetCostAndUsage— per-account cost readback shown to tenants
Secrets
# 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/orchestratorBoth 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 agent | AWS vending | |
|---|---|---|
| Customer prerequisite | any k8s cluster + Helm | none (you supply AWS) |
| Network model | outbound WebSocket from customer | your orchestrator → AWS APIs |
| Isolation | customer's own cluster | dedicated AWS account per tenant |
| Your operational burden | none per-tenant | AWS Org, billing, cost passthrough |
Most self-hosters start with the deploy agent and add AWS vending only if they want to offer managed hosting.