runtime command run¶
The Command Engine wraps approved CLI binaries. It is a thin deterministic wrapper: it never interprets a binary's output, it only executes the requested subcommand and returns whatever the binary printed.
runtime command run git status
runtime command run terraform plan
runtime command run kubectl get pods
runtime command run gh repo list --limit 5
Two ways the Command Engine is reached¶
- A provider chose it.
runtime github pr listdispatches to the GitHub provider, which decided that operation is best served bygh. The provider supplies the binary and arguments. - Directly, via
command run— the raw escape hatch for binaries no provider covers.
Both paths are gated by the same policy. When a provider picks the CLI
transport, allowed_binaries and command_policy are evaluated on top of
the provider's own rule. A provider can only reach binaries the installation
already permits, and cannot launder a denied binary through an operation.
Prefer a provider operation¶
command run is an escape hatch, not the default style. When a provider
already exposes what you need, use it:
runtime github repo list # preferred
runtime command run gh repo list # works, but bypasses the curated surface
A provider operation is a stable contract — the transport can change beneath it
without breaking you. A command run invocation is pinned to one tool's exact
CLI forever.
Allowed binaries¶
Only binaries in allowed_binaries may execute at all. The seeded policy ships
21:
| Category | Binaries |
|---|---|
| VCS / GitHub | git, gh |
| IaC | terraform, pulumi, packer |
| GCP | gcloud, gsutil, bq |
| AWS / Azure | aws, az |
| Kubernetes | kubectl, oc, helm, kustomize, flux, istioctl, argocd |
| Containers | docker, podman |
| Secrets | vault, sops |
Check what your install actually allows — new entries in a release do not
reach an existing policy-config.yaml:
That report also tells you which allowed binaries are actually installed on the machine.
See Command Engine Binaries for per-binary detail, and Policy to change the list.
Governance layers¶
1. Binary allow-list¶
A binary not in allowed_binaries can never run. Full stop.
2. Hard-denied binaries¶
Refused outright, independent of allowed_binaries — adding one to the
allow-list does not un-deny it.
3. Subcommand rules¶
| List | Matching |
|---|---|
denied |
A contiguous run of argument tokens anywhere in the command |
allowed |
Prefix match; when present, only matching prefixes may run |
Denials always win.
Because denied matches anywhere rather than as a prefix, leading flags cannot
bypass a rule:
runtime command run terraform destroy -auto-approve # denied
runtime command run git -C /tmp/wd push --force # denied
Evaluation order¶
Policy is evaluated before the Command Engine runs, against the raw arguments — before Runtime Context injection happens.
This ordering is deliberate: an injected flag can only ever narrow a command, never smuggle a denied operation past the policy check.
Authentication¶
Auth is resolved from config.yaml's command_providers map:
command_providers:
gh: github
gcloud: gcp
gsutil: gcp
bq: gcp
kubectl: kubernetes
oc: openshift
helm: kubernetes
flux: kubernetes
istioctl: kubernetes
A binary with no entry skips the Auth Engine entirely. There is no silent
fallback to a default provider — omission means "manages its own credentials"
(terraform's provider blocks, Docker's registry logins) or "no Auth Engine
provider exists for that platform yet" (aws, az, vault).
gh needs no gh auth login — the runtime forwards the validated token as
GH_TOKEN and GITHUB_TOKEN.
Runtime Context injection¶
Injection is narrow, on purpose — only two cases:
| Binary | Injected | From |
|---|---|---|
gcloud |
--project=<project> |
cloud.project |
kubectl, oc |
-n <namespace> |
kubernetes.namespace |
Nothing is injected when the field is empty or the flag is already present in
your arguments. Every other allowed binary receives its arguments
unchanged, however many are added to allowed_binaries over time.
Keeping the injection surface small keeps it auditable: a new binary does not silently gain context injection.
helm, flux and istioctl accept -n but don't receive it
They map to the kubernetes auth provider but have no injection case.
Pass -n <namespace> yourself where those tools need it.
Auditing¶
Every invocation — allowed, denied, or failed — is recorded. Nothing executes without a trace.
The transport field is empty for command run records, which is how you tell
a direct escape-hatch invocation apart from a provider operation that happened
to choose the CLI.
Deliberately excluded¶
ansible and ansible-playbook are not on the allow-list and should not be
added by the same pattern as everything else.
Their ad-hoc and playbook modules (ansible all -m shell -a '<opaque
payload>') are arbitrary remote command execution — the same risk category as
ssh, which is refused outright. The dangerous part is an opaque payload
argument, not a recognizable subcommand, so a denied: rule cannot
meaningfully cap it the way terraform destroy can be capped.
Revisit deliberately if a real need arises.
In capabilities¶
A binary: step is the same escape hatch inside a capability:
The binary must be in allowed_binaries or validation fails. Note that
runtime itself is not an allowed binary — a capability cannot invoke
another capability. See
Composing capabilities.