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
Containerobjects defining the workload containers - volumes – A list of
Volumeobjects for storage and configuration injection - snapshotsConfig – Configuration for snapshot storage and resume behavior
- sandboxClass – The isolation runtime selector (
gvisorormicrovm) - resources – Compute limits (
cpuandmemory) 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 (useNET_BIND_SERVICE, notCAP_NET_BIND_SERVICE) - The special value
ALLis explicitly rejected for bothaddanddropoperations - 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:
pkg/api/v1alpha1/actortemplate_types.go– Core CRD Go types includingActorTemplateSpec,Container,Volume, andSecurityContextcmd/atecontroller/internal/controllers/actortemplate_controller.go– Admission and reconciliation logic that enforces validation rulesmanifests/ate-install/generated/ate.dev_actortemplates.yaml– Example manifests showing production usage patternscmd/ateapi/internal/controlapi/actor_template.go– Control-plane API implementation serving ActorTemplate objects to clients
Summary
- ActorTemplates use the
ActorTemplateSpecto 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 theALLmeta-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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →