Documentation
¶
Overview ¶
Package podbuilder provides a single codepath for constructing agent pods. All controllers that need to create agent pods or pod templates use Build() to produce a *corev1.Pod with the agent container, model-router sidecar, volumes, and security hardening applied consistently.
Index ¶
- Constants
- Variables
- func Build(cfg PodConfig) *corev1.Pod
- func BuildAgentOnly(cfg PodConfig) *corev1.Pod
- func BuildRouterOnly(cfg PodConfig) *corev1.Pod
- func FrameworkEnvVars(fw string, routerBaseURL string) []corev1.EnvVar
- func OAuthCredsMountDir(toolName, secretName string) string
- func ResolveAgentSecretRefs(agent *agentorcav1alpha1.Agent) ([]corev1.Volume, []corev1.VolumeMount)
- func ResolveMCPSidecarVolumes(ctx context.Context, reader client.Reader, namespace string, ...) ([]corev1.Volume, []corev1.VolumeMount, map[string]string, error)
- func ResolveProviderVolumes(ctx context.Context, reader client.Reader, namespace string, ...) ([]corev1.Volume, []corev1.VolumeMount, error)
- func ResolveToolSecretVolumes(ctx context.Context, reader client.Reader, namespace string, ...) ([]corev1.Volume, []corev1.VolumeMount, error)
- func SanitizeVolumeName(name string) string
- func ToolSecretFilePath(toolName, secretName, key string) string
- type PodConfig
Constants ¶
const ( // RouterConfigKey is the key within the router config ConfigMap. RouterConfigKey = "router-config.json" // RouterConfigVolume is the volume name for the router config ConfigMap. RouterConfigVolume = "agentorca-router-config" // RouterConfigDir is the mount path for the router config directory. RouterConfigDir = "/etc/agentorca" // TokenSecretSuffix is appended to resource names for token secrets. TokenSecretSuffix = "-token" // TokenVolumeName is the volume name for the token env secret. TokenVolumeName = "agentorca-env" // TokenEnvDir is the mount path for the token env secret. TokenEnvDir = "/etc/agentorca-env" // RedisSecretSuffix is appended to resource names for the Secret holding the // Redis password the model-router authenticates with. RedisSecretSuffix = "-redis" // RedisSecretKey is the key within the Redis password Secret. RedisSecretKey = "password" // RedisSecretVolume is the volume name for the Redis password Secret. RedisSecretVolume = "agentorca-redis" // RedisSecretDir is the mount path for the Redis password Secret. Must NOT // be under RouterConfigDir for the same reason as ProviderSecretsDir. RedisSecretDir = "/etc/agentorca-redis" // RedisPasswordFile is the path the model-router reads the password from. RedisPasswordFile = RedisSecretDir + "/" + RedisSecretKey // ProviderVolPrefix is the volume name prefix for provider API key secrets. ProviderVolPrefix = "provider-" // ProviderSecretsDir is the mount path for provider secret directories. // Must NOT be under RouterConfigDir — the ConfigMap volume is read-only and // the kubelet cannot create intermediate directories inside it. ProviderSecretsDir = "/etc/agentorca-providers" // ToolSecretsDir is the base mount path for tool secret volumes. // Must NOT be under RouterConfigDir for the same reason as ProviderSecretsDir. ToolSecretsDir = "/etc/agentorca-tool-secrets" // ToolSecretVolPrefix is the volume name prefix for tool secret volumes. ToolSecretVolPrefix = "tool-secret-" // AgentSecretVolPrefix is the volume name prefix for agent-runtime secret volumes // (Agent.spec.runtime.secretRefs). Mounted into the agent container only. AgentSecretVolPrefix = "agent-secret-" // AgentSecretMountDir is the default mount path used for an agent secret ref when // MountPath is empty (keys are injected as files under this directory). AgentSecretMountDir = "/etc/agentorca-secrets" // MCPBinDir is the base mount path for MCP sidecar tool image volumes. // Each tool image is mounted at MCPBinDir/<toolName>/ via a Kubernetes // image volume (see ResolveMCPSidecarVolumes). MCPBinDir = "/mcp-img" // WarmCacheVolName is the volume name for the disk-backed emptyDir used as a // local L1 checkpoint cache on warm pods (see WarmLocalCacheEnabled in PodConfig). WarmCacheVolName = "agentorca-warm-cache" // WarmCacheMountDir is the in-container path the model-router mirrors warm-pod // checkpoints to. Mounted into the model-router sidecar only. WarmCacheMountDir = "/var/lib/agentorca/warm-cache" )
Variables ¶
var DefaultRouterResources = corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("100m"), corev1.ResourceMemory: resource.MustParse("128Mi"), }, Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("500m"), corev1.ResourceMemory: resource.MustParse("256Mi"), }, }
DefaultRouterResources are the resource requirements applied to the model-router sidecar when PodConfig.RouterResources is nil.
Functions ¶
func Build ¶
Build constructs a *corev1.Pod from the given config. The returned pod has:
- An agent container with the configured image, command, env, and resources
- A model-router native sidecar (init container with restartPolicy=Always)
- All provider, tool secret, and MCP binary volumes
- Framework injection (tier 1/2/3) applied
- Security hardening (PSA restricted + projected SA token + /tmp emptyDir) applied
The caller is responsible for setting OwnerReferences on the returned pod.
func BuildAgentOnly ¶
BuildAgentOnly constructs a *corev1.Pod containing only the agent container. Used in split-pod topology where the model-router runs in a separate pod. The agent reaches the router via the router Service URL in RouterBaseURL. The caller is responsible for setting OwnerReferences on the returned pod.
func BuildRouterOnly ¶
BuildRouterOnly constructs a *corev1.Pod containing only the model-router container. Used in split-pod topology where the agent runs in a separate pod and reaches the router via a Kubernetes Service. The router runs as a regular (non-sidecar) container. The caller is responsible for setting OwnerReferences on the returned pod.
func FrameworkEnvVars ¶
FrameworkEnvVars returns additional env vars for specific agent frameworks. routerBaseURL is the HTTP base URL to the model-router (e.g. "http://localhost:8080" for combined-pod topology; the router Service URL for split-pod topology). The framework adoption layer (tier 1/2/3) adds further per-framework config; this covers the common openai-compatible tier-1 defaults.
func OAuthCredsMountDir ¶
OAuthCredsMountDir returns the directory at which an MCP tool's OAuth credentials Secret (MCPOAuthConfig.Credentials) is mounted as files for the model-router's MCP client to read (client_id, client_secret, redirect_uri, refresh_token).
func ResolveAgentSecretRefs ¶
func ResolveAgentSecretRefs(agent *agentorcav1alpha1.Agent) ([]corev1.Volume, []corev1.VolumeMount)
ResolveAgentSecretRefs builds volumes and mounts for secrets referenced by an Agent's runtime (Agent.spec.runtime.secretRefs). These are mounted read-only into the agent container only — not the model-router sidecar. Each entry with a MountPath becomes a whole-secret volume mounted at that path; an empty MountPath defaults to /etc/agentorca-secrets/<secret-name> (keys as files). This is a pure transform: the kubelet resolves the secret at pod start.
Use case: a red-team pwnbox mounting an HTB OpenVPN .ovpn config directly into the agent container so the entrypoint can bring up the tunnel.
func ResolveMCPSidecarVolumes ¶
func ResolveMCPSidecarVolumes( ctx context.Context, reader client.Reader, namespace string, agent *agentorcav1alpha1.Agent, ) ([]corev1.Volume, []corev1.VolumeMount, map[string]string, error)
ResolveMCPSidecarVolumes inspects the agent's MCP tools and builds image volumes + mounts to inject MCP server binaries into the model-router.
For each MCP tool with executionMode=sidecar, ociRef set, and stdio transport with args, the function uses a Kubernetes image volume (GA since 1.33) to mount the tool's OCI image filesystem directly. The model-router can then fork/exec the binary at its original path inside the mounted image.
This avoids init containers entirely -- no cp, no busybox, no emptyDir. Works even with scratch/distroless images since the kubelet mounts the image layers directly as a read-only filesystem.
func ResolveProviderVolumes ¶
func ResolveProviderVolumes( ctx context.Context, reader client.Reader, namespace string, agent *agentorcav1alpha1.Agent, ) ([]corev1.Volume, []corev1.VolumeMount, error)
ResolveProviderVolumes builds volume + mount lists for provider API key secrets.
func ResolveToolSecretVolumes ¶
func ResolveToolSecretVolumes( ctx context.Context, reader client.Reader, namespace string, agent *agentorcav1alpha1.Agent, ) ([]corev1.Volume, []corev1.VolumeMount, error)
ResolveToolSecretVolumes builds volumes and mounts for secrets referenced by MCP tools (envFrom, auth, and secretRefs). These are mounted on the model-router sidecar.
func SanitizeVolumeName ¶
SanitizeVolumeName converts an arbitrary string to a valid Kubernetes volume name.
func ToolSecretFilePath ¶
ToolSecretFilePath returns the mount path for a secret key used by a tool.
Types ¶
type PodConfig ¶
type PodConfig struct {
// PodName is set for AgentRun pods (e.g. "agentorca-run-<name>").
// Empty for Deployment templates and warm pods that use GenerateName.
PodName string
// GenerateName is set for warm pods (e.g. "warm-<deploy>-").
// Mutually exclusive with PodName.
GenerateName string
Namespace string
Labels map[string]string
Annotations map[string]string
// Agent is the Agent CRD that defines the runtime image, framework, tools, etc.
Agent *agentorcav1alpha1.Agent
// AgentEnv holds caller-specific env vars (e.g. AGENTORC_RUN_ID for runs,
// AGENTORC_AGENT for deployments). FrameworkEnvVars are appended automatically.
AgentEnv []corev1.EnvVar
// TokenSecretName is the Secret containing OPENAI_BASE_URL and OPENAI_API_KEY,
// injected via EnvFrom on the agent container.
TokenSecretName string
ServiceAccount string
RestartPolicy corev1.RestartPolicy // Never (runs/warm) or Always (deployments)
ModelRouterImage string
// RouterConfigName is the ConfigMap name containing the router config JSON.
RouterConfigName string
// RedisSecretName is the Secret holding the Redis password, mounted read-only
// at RedisPasswordFile in the model-router container only. Empty when Redis
// needs no password.
RedisSecretName string
// RouterExtraPorts are additional ports on the model-router container
// (e.g. warm-mgmt:9090 for warm pods).
RouterExtraPorts []corev1.ContainerPort
// RouterProbePort is the port for the model-router startup probe.
// Defaults to 8080 if zero.
RouterProbePort int
// RouterResources overrides the default model-router resource requirements.
// If nil, DefaultRouterResources is used.
RouterResources *corev1.ResourceRequirements
// WebhookNotifySecretRef, when set, mounts the referenced Secret key as the
// WEBHOOK_URL env var into the model-router sidecar so the _webhook_notify
// builtin tool can POST to a Slack incoming webhook. Not mounted to the agent
// container. +optional
WebhookNotifySecretRef *corev1.SecretKeySelector
// HindsightURL is the configured hindsight API endpoint (e.g. http://hindsight.local).
// Used to generate ipBlock egress rules in the per-run NetworkPolicies when the cluster has a default-deny egress policy.
HindsightURL string
// HindsightAPIKeySecretRef, when set, injects the hindsight API key into the
// model-router container as HINDSIGHT_API_KEY so it can authenticate to a
// hindsight API that requires a tenant API key. Never mounted to the agent
// container. +optional
HindsightAPIKeySecretRef *corev1.SecretKeySelector
// AgentReadinessProbe is set for http-mode AgentRun pods.
// If nil, no readiness probe is added to the agent container.
AgentReadinessProbe *corev1.Probe
ProviderVolumes []corev1.Volume
ProviderMounts []corev1.VolumeMount
ToolSecretVolumes []corev1.Volume
ToolSecretMounts []corev1.VolumeMount
MCPBinVolumes []corev1.Volume
MCPBinMounts []corev1.VolumeMount
// AgentSecretVolumes and AgentSecretMounts carry secrets referenced by
// Agent.spec.runtime.secretRefs. They are mounted into the agent container only
// (not the model-router sidecar). Use ResolveAgentSecretRefs to build them.
AgentSecretVolumes []corev1.Volume
AgentSecretMounts []corev1.VolumeMount
// WarmLocalCacheEnabled attaches a disk-backed emptyDir to the model-router
// sidecar as a local checkpoint cache that supplements Redis. Only set true
// for warm pods (buildWarmPod); one-shot AgentRun pods leave it false so their
// specs are unchanged.
WarmLocalCacheEnabled bool
// WarmLocalCacheSizeLimit is the SizeLimit for the warm-cache emptyDir.
// May be nil for "no limit" (bounded by node ephemeral storage).
WarmLocalCacheSizeLimit *resource.Quantity
// RouterBaseURL is the base URL the agent uses to reach the model-router.
// Defaults to "http://localhost:8080" when empty (combined-pod sidecar topology).
// Set to the router Service URL (e.g. "http://agentorca-router-<run>.<ns>:8080") in
// split-pod topology so framework env vars point at the correct endpoint.
RouterBaseURL string
// CloudProvider is used for Azure Workload Identity pod labeling.
CloudProvider security.CloudProvider
}
PodConfig holds all inputs needed to build an agent pod spec. Controllers populate this struct with their specific configuration and call Build().