Skip to main content

Runners, Isolated Execution and Controlled Environments

🌟 Objective​

Ensure that all containers are executed in isolated, controlled and auditable environments, especially in the context of CI/CD pipelines and automated execution, mitigating process risks and technical compromise risks, namely:

  • Compromise of the host or of other jobs;
  • Privilege escalation;
  • Undue persistence of sensitive data between executions;
  • Execution of unassessed artefacts in shared environments;
  • Implicit acceptance of risk by way of automation.

In a modern SSDLC, runners are not merely infrastructure:
they are points where trust materialises, where artefacts move from “built” to “executed”.


🧬 What runners and execution environments are​

Runners are execution agents responsible for running CI/CD tasks or container workloads, typically on platforms such as:

  • GitHub Actions (runners)
  • GitLab CI (runners)
  • Azure DevOps (agents)
  • Jenkins (executors)
  • Kubernetes Jobs, CronJobs or temporary pods

Regardless of the platform, a runner always represents an environment where implicit decisions occur:
which image is executed, with which permissions, in which context and with what impact.

An isolated execution environment must ensure, at a minimum:

  • Separation of namespaces (process, network, filesystem);
  • No persistence between executions;
  • Execution with a non-root user and minimal permissions;
  • Explicit limitation of resources (CPU, memory, storage);
  • Inability to affect parallel or future executions.

⚠️ Shared and generic runners are critical points of process risk, because a successful execution may be interpreted, wrongly, as implicit authorisation.


📘 Types of runners and risk levels​

TypeExamplesAssociated riskOperational notes
Shared (multi-tenant)GitHub hosted, GitLab sharedHigh – common surfaceAvoid in L2/L3 pipelines
Self-managedAzure DevOps agent, on-prem runnersModerate – depends on hardeningAcceptable if isolated and auditable
Ephemeral and dedicatedK8s Jobs, temporary runnersLow – strong isolationPreferred: recreated per execution

The choice of runner type is a risk decision, not merely one of operational convenience.


🛠️ How to apply isolated execution​

Secure execution requires that the runner does not introduce implicit trust nor amplify upstream errors:

  1. Avoid shared runners in critical or regulated projects (L3);
  2. Run containers in ephemeral environments, destroyed after each execution;
  3. Prohibit privileged execution (--privileged, --cap-add, access to /var/run/docker.sock);
  4. Apply explicit resource limits (CPU, RAM, storage);
  5. Ensure that the execution user has no administrative permissions;
  6. Apply additional sandboxing (e.g. gVisor, Kata Containers) when the risk justifies it;
  7. Restrict the images allowed on the runner (see 01-imagens-base.md);
  8. Control and justify any access to the network or external storage;
  9. Record and monitor executions, including isolation failures and evasion attempts.

These controls do not replace human decision, but they reduce the impact of wrong or implicit decisions.


📂 Where and how to configure​

PlatformRecommended isolation practice
GitHub ActionsSelf-hosted runners in ephemeral environments (e.g. Kubernetes)
Azure DevOpsAgents in dedicated containers; no access to the host
GitLab CIDocker/Kubernetes runners with a strict isolation policy
JenkinsExecution in ephemeral containers with a read-only filesystem
KubernetesTemporary pods with securityContext, PSA and quotas

Regardless of the platform, the rule is invariable:
the runner must not outlive the execution.


🔍 Runners as a point of implicit decision​

Whenever a runner executes a container:

  • an image has been implicitly accepted;
  • a permissions context has been implicitly authorised;
  • a potential impact has been implicitly assumed.

Therefore:

  • the execution must be traceable;
  • the context must be reproducible;
  • the decision must be justifiable a posteriori.

Without these elements, automation turns into systemic risk.


✅ Good practices​

  • Isolate runners by project, domain or namespace;
  • Recreate runners on each execution (no persistent cache);
  • Monitor resource usage and execution anomalies;
  • Prohibit access to the internal network by default;
  • Use labels and restrictions to enforce secure execution;
  • Integrate technical enforcement (OPA/Kyverno) without replacing governance.

📎 Cross-references​

DocumentRelation to runners and execution
01-imagens-base.mdImages allowed in execution environments
05-policies-runtime-opa.mdTechnical enforcement of policies
06-inventario-sbom.mdInventory of the execution environment
09-riscos-processo-imagens.mdSeparation between automatic execution and decision
15-aplicacao-lifecycle.mdOperational application in the lifecycle

🧱 Pipeline security starts at execution.
An insecure runner is not merely a technical risk - it is a mechanism for implicit acceptance of risk.