Skip to content

The image

The RootPilot Agent ships as a container image. This page describes what it contains — the material for a security review before you hand it credentials.

Janela do terminal
# AWS (ECR)
docker pull <rootpilot-account>.dkr.ecr.<region>.amazonaws.com/rootpilot-agent:<version>
# GCP (Artifact Registry)
docker pull <region>-docker.pkg.dev/<rootpilot-project>/rootpilot/rootpilot-agent:<version>

Access is granted to your AWS account or GCP project: the pull uses your cloud’s identity, and there is no RootPilot credential for you to store or rotate.

The registry is private, so a docker pull without authentication fails with no basic auth credentials. Authenticate with your credentials — it is the authorization we granted to them that unlocks the pull.

AWS (ECR) — the token comes from your account; the login targets RootPilot’s registry:

Janela do terminal
aws ecr get-login-password --region <region> \
| docker login --username AWS --password-stdin <rootpilot-account>.dkr.ecr.<region>.amazonaws.com

Use the same <region> as the image address. Your principal needs ecr:GetAuthorizationToken; read permissions on the repository were already granted to your account on our side.

GCP (Artifact Registry) — register the credential helper once:

Janela do terminal
gcloud auth configure-docker <region>-docker.pkg.dev

Your principal needs roles/artifactregistry.reader on the repository, already granted to the project you gave us.

Property Value
Architectures linux/amd64 and linux/arm64
Base node:22-alpine
User node (uid 1000) — non-root
Entrypoint loads the PEMs from /certs and runs the Agent process
Exposed ports none

Only what the process opens at runtime: the compiled JavaScript artifacts (dist/), the package manifests, and production dependencies.

By construction, the final build stage does not copy the development tree:

  • no source code (src/);
  • no tests and no test fixtures;
  • no build toolchain — python3, make, and g++ exist only in an intermediate stage and never reach the runtime;
  • no secrets. The image is identical for every customer; what varies is the certificate and the credentials you mount at runtime.

Excluding fixtures is deliberate and matters to you: without it, one customer’s test data would travel into another customer’s infrastructure.

In production, reference the image by digest rather than tag:

<address>/rootpilot-agent@sha256:<digest>

The Agent is ephemeral and pulls often. A moving tag lets different replicas run different builds without anyone noticing. The digest is immutable.

To find the digest behind a tag:

Janela do terminal
docker buildx imagetools inspect <address>/rootpilot-agent:<version>

The same command lists the architectures present in the multi-platform index.

The image is signed at publish time, without a key: the workflow that builds it exchanges its own identity for an ephemeral certificate, and the signature is recorded in a public transparency log. What this proves is not “someone holding a key signed this” — it is which workflow, from which repository, at which tag produced that digest.

Requires cosign:

Janela do terminal
cosign verify \
--certificate-identity https://github.com/sunnysystems/rootpilot-edge/.github/workflows/release-image.yml@refs/tags/v<version> \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
<address>/rootpilot-agent@sha256:<digest>

The --certificate-identity flag is the one that matters, and that is why it carries the version: without pinning the identity, cosign verify would accept any valid Sigstore signature — including one from a repository that is not ours. Verifying without it is close to not verifying at all.

If you enforce admission policy on your cluster (Kyverno, policy-controller), that same identity is what goes into the rule. Recommended, but your call: we publish the signature, we do not require verification.

No special privileges: no --privileged, no added capabilities, no Docker socket access, no host filesystem mounts. The only volume needed is /certs, read-only.

Memory and CPU: 0.5 vCPU and 512 MB cover most installations. RUNNER_LEARNED_STORE_PATH defaults to :memory:, so nothing is written to disk — point it at a volume and the container starts writing there, with the permissions being yours to own.