How to Define an ActorTemplate with Specific Container Configurations in Agent Substrate

You define an ActorTemplate by authoring a YAML manifest with an ActorTemplateSpec that declares containers with pinned OCI images, volume mounts, and security contexts, ensuring all images contain "@" for digest pinning to maintain reproducible snapshots.

Agent Substrate uses a Kubernetes-style custom resource called ActorTemplate to declaratively describe the complete runtime layout of an actor. The specification is defined in pkg/api/v1alpha1/actortemplate_types.go and enforced by the admission controller at cmd/atecontroller/internal/controllers/actortemplate_controller.go. By configuring the ActorTemplateSpec, you control everything from container images and commands to persistent storage and Linux capabilities.

Understanding the ActorTemplateSpec Structure

The ActorTemplateSpec serves as the top-level configuration object for defining actor runtime behavior. According to the source code in pkg/api/v1alpha1/actortemplate_types.go, the spec contains five primary fields:

  • containers – An array of Container objects defining the workload containers
  • volumes – A list of Volume objects for storage and configuration injection
  • snapshotsConfig – Configuration for snapshot storage and resume behavior
  • sandboxClass – The isolation runtime selector (gvisor or microvm)
  • resources – Compute limits (cpu and memory) that drive sandbox sizing

The controller validates these fields using kubebuilder XValidation rules to ensure every volume is referenced by at least one container and that all naming conventions follow DNS-label patterns.

Configuring Containers with Specific Images and Commands

Each container in the containers array is a Container type that supports precise runtime configuration. The controller enforces strict validation on several fields:

Image requirements. The image field must contain an "@" symbol to specify a pinned digest (e.g., nginx@sha256:123abc...). This ensures snapshots remain reproducible across resume operations. Tags without digests are rejected during admission.

Entrypoint overrides. Use command to replace the image's ENTRYPOINT and args to replace CMD. Variable expansion is not performed on these values.

Environment variables. The env field accepts an array of EnvVar objects, but only literal values are permitted. The system does not support config map or secret references in this version.

Readiness probes. The optional readyz field defines an HTTP probe (ContainerReadyz). The actor status remains non-Ready until this endpoint returns HTTP 200. Configure httpGet.port, httpGet.path, and timeoutSeconds to control probe behavior.

Volume mounts. Bind declared volumes into the container using volumeMounts, which requires a name matching a defined volume and a mountPath that must be a clean absolute Unix path.

Security context. The securityContext field accepts a SecurityContext object that manages Linux capabilities through the capabilities sub-field.

Defining Volumes and Storage Sources

Volumes are declared in the volumes array as Volume objects, each requiring a unique name and exactly one VolumeSource. The source code defines four distinct volume types:

  • image – Mounts a read-only OCI image as a volume
  • externalVolumeTemplate – Dynamically provisions CSI-like storage with configurable capacity and storageClassName
  • systemInfo – Projects actor metadata and trust bundles into the filesystem
  • durableDir – Creates a persistent directory on the rootfs that survives resume operations and participates in snapshots

Validation rules require that every declared volume must be referenced by at least one container's volumeMounts, and volume names must follow DNS-label conventions.

Security Contexts and Linux Capabilities

The securityContext.capabilities field controls privilege escalation through capability addition or removal. Key constraints implemented in the controller include:

  • Capabilities must be specified without the CAP_ prefix (use NET_BIND_SERVICE, not CAP_NET_BIND_SERVICE)
  • The special value ALL is explicitly rejected for both add and drop operations
  • Allowed capability strings follow strict pattern validation defined in the CRD

SnapshotsConfig, SandboxClass, and Resource Limits

SnapshotsConfig determines where snapshots are stored via the location field (e.g., s3://my-bucket/snapshots) and controls onResume behavior, allowing selection between cold-boot or golden snapshot restores.

SandboxClass selects the isolation runtime. Valid values are gvisor or microvm. This choice impacts capability availability and snapshot support; for example, Golden snapshots are only supported when using the microvm sandbox class.

Resources accepts standard Kubernetes-style limits for cpu and memory. The system only respects limits; requests and claims fields are ignored. For microvm sandboxes, the memory limit must be at least 256 MiB to accommodate the 128 MiB host reserve plus 128 MiB guest minimum.

Complete ActorTemplate YAML Example

Below is a minimal yet complete manifest named demo-template that demonstrates multi-container configuration, external volume provisioning, durable directories, and capability management:

apiVersion: substrate.io/v1alpha1
kind: ActorTemplate
metadata:
  name: demo-template
spec:
  sandboxClass: gvisor               # Run on gVisor workers

  snapshotsConfig:
    location: s3://my-bucket/snapshots
  containers:
  - name: nginx
    image: docker.io/library/nginx@sha256:123abc...   # pinned image

    command: ["/usr/sbin/nginx"]
    args: ["-g", "daemon off;"]
    env:
    - name: ENV
      value: production
    readyz:
      httpGet:
        port: 80
        path: /readyz
      timeoutSeconds: 10
    volumeMounts:
    - name: static-content
      mountPath: /usr/share/nginx/html
    securityContext:
      capabilities:
        add: ["NET_BIND_SERVICE"]
  - name: sidecar
    image: ghcr.io/example/sidecar@sha256:abcdef...
    args: ["--log-level=info"]
    volumeMounts:
    - name: static-content
      mountPath: /data
  volumes:
  - name: static-content
    externalVolumeTemplate:
      capacity: 1Gi
      storageClassName: standard
  - name: config-dir
    durableDir: {}

To expose actor metadata inside containers, add a system information volume:

  volumes:
  - name: sysinfo
    systemInfo:
      dataSources:
      - actorMetadata:
          items:
          - field: name
            path: meta/name
          - field: uid
            path: meta/uid

This configuration creates files at /sysinfo/meta/name and /sysinfo/meta/uid inside any container mounting the sysinfo volume.

Key Source Files for ActorTemplate Development

The following files in the agent-substrate/substrate repository contain the authoritative definitions and logic:

Summary

  • ActorTemplates use the ActorTemplateSpec to declaratively define container runtime configurations in Agent Substrate.
  • Container images must use pinned digests containing "@" to ensure reproducible snapshots and successful admission.
  • Volumes support multiple backend types including external CSI-like storage, durable directories, and system information projection.
  • Security contexts manage Linux capabilities without the CAP_ prefix and reject the ALL meta-capability.
  • Validation rules enforce DNS-label naming, absolute mount paths, volume reference completeness, and minimum memory limits (256 MiB) for microvm sandboxes.

Frequently Asked Questions

What image format is required for ActorTemplate containers?

Container images must specify a pinned digest using the "@" symbol, such as docker.io/library/nginx@sha256:123abc.... The admission controller rejects images that use only tags without digests to ensure snapshot reproducibility across actor resumes.

How do I expose actor metadata to my containers?

Mount a systemInfo volume that contains an actorMetadata data source. The volume projects specific fields like name and uid as files into the container filesystem at your specified paths, accessible under the mount point you define in volumeMounts.

Why does my microvm sandbox fail to create with 128 MiB memory limits?

The microvm sandbox class reserves 128 MiB for the host side and requires a minimum of 128 MiB for the guest VM, totaling 256 MiB. The controller enforces this minimum through XValidation rules, so you must set resources.limits.memory to at least 256Mi when using the microvm sandbox class.

Can I use environment variables from ConfigMaps or Secrets in ActorTemplates?

No, the current implementation only supports literal values in the env field of container specifications. As defined in pkg/api/v1alpha1/actortemplate_types.go, the EnvVar type accepts only direct value assignments, and the controller does not perform variable expansion from external sources.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →