In-Cluster Runner
Remediation is only useful if it can reach the thing that needs fixing. Exposing your services' operational endpoints to the internet so a SaaS control plane can call them is the wrong trade, and in practice it fails in all the boring ways: NAT asymmetry, security-group drift, egress policies. The runner inverts the direction.
The InfraSage runner is a small agent you deploy inside your cluster. It is outbound-only:
- It enrolls with your tenant credential and a cluster name.
- It long-polls the control plane for runbook steps that a human has already approved.
- It executes them against cluster-local endpoints: Service DNS, private IPs, anything your network can see and the internet can't.
- It reports the result back into the same execution audit trail.
No inbound ports. No public exposure of /ops endpoints. No firewall or security-group changes.
If your cluster can make HTTPS requests out, remediation works.
Deterministic targeting
Runbook steps that use the runner name where they run with an explicit cluster selector, so the platform never guesses:
- step_id: reset-pool
name: Recycle the connection pool
skill_id: legacy:runner_http
params:
cluster: "prod-mumbai" # target selector → an enrolled runner
url: "http://payment-service.shop.svc.cluster.local:8080/ops/reset-pool"
method: "POST"
wait_seconds: "120"
on_failure: stop
At dispatch, the selector resolves against enrolled, live runners (a runner is live if it polled
within the last two minutes). If no live runner covers the cluster, the step fails immediately
with a named gap, "no live runner enrolled for cluster prod-mumbai", instead of a cryptic
timeout. Ambiguity is a human decision, never a model's.
The step still goes through the full approval flow: it is queued to a runner only after the runbook's tier gate is satisfied and an operator has approved the action.
Deploying the runner
The runner is a single static binary with one capability today (http). A minimal Kubernetes
deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: infrasage-runner
namespace: infrasage
spec:
replicas: 1
selector:
matchLabels: { app: infrasage-runner }
template:
metadata:
labels: { app: infrasage-runner }
spec:
containers:
- name: runner
image: ghcr.io/infrasagedev/infrasage-runner:latest
env:
- name: INFRASAGE_BASE_URL
value: "https://api.infrasage.dev"
- name: INFRASAGE_API_TOKEN
valueFrom:
secretKeyRef: { name: infrasage-runner-token, key: token }
- name: RUNNER_CLUSTER
value: "prod-mumbai" # must match your runbook selectors
- name: RUNNER_NAMESPACES
value: "shop,payments" # informational, for the target map
The runner re-enrolls automatically if its registration is lost, and backs off politely when the control plane is unreachable (a rolling deploy of InfraSage is invisible to it beyond a one-poll hiccup).
Security posture
The runner can only execute what the control plane hands it, and the control plane only hands it steps from human-approved runbook executions in its own tenant. Enrollment, polling, and results are all tenant-scoped.
The runner authenticates with a tenant API token that you issue. Revoke the token and it goes inert.
Every step lease and result lands in the execution audit trail with the runner's identity, alongside the approval that authorized it.
The one capability today is HTTP requests to cluster-local endpoints. Kubernetes verbs (rollout restart, scale) ship as a follow-up capability with runner-side allowlists: the runner declares what it may do, and the control plane cannot exceed it.
When to use runner steps vs. plain HTTP steps
legacy:http | legacy:runner_http | |
|---|---|---|
| Executes from | InfraSage control plane | Your cluster |
| Target must be | Reachable from InfraSage (public or allowlisted) | Reachable from inside your cluster |
| Network setup | Egress/ingress rules on both sides | None |
| Best for | Webhooks, SaaS APIs, public endpoints | Internal ops endpoints, anything on cluster DNS |
If you have found yourself opening a NodePort or a security-group hole so a runbook could reach a service, that's the signal to switch the step to the runner.