Agent
Agent (maqpna.com/v1alpha1): every field, type, default and validation rule, generated from the CRD schema.
Agent is a governed AI agent definition.
At a glance#
| Property | Value |
|---|---|
| API version | maqpna.com/v1alpha1 |
| Kind | Agent |
| Scope | Namespaced |
| Plural | agents |
| Short names | mqagent, ag |
| Categories | maqpna |
| Status subresource | yes |
kubectl get agents -A
kubectl get mqagent <name> -o yaml
kubectl explain agents.spec
Columns in kubectl get#
| Column | Type | From |
|---|---|---|
| Tier | string | .spec.tier |
| Profile | string | .spec.profile |
| Ready | string | .status.conditions[?(@.type=="Ready")].status |
| Sovereign | string | .status.conditions[?(@.type=="SovereigntyCompliant")].status |
| Policy | string | .spec.policyRef |
| Image | string | .spec.image |
| Sessions | integer | .status.activeSessions |
| Age | date | .metadata.creationTimestamp |
Example#
From config/samples/agent-browser.yaml:
# Browser / computer-use agent (F-19): Chromium sidecar with CDP on
# 127.0.0.1:9222 only, all browser egress through the gateway egress proxy
# limited to spec.browser.allowedDomains, optional noVNC live view for HITL.
apiVersion: maqpna.com/v1alpha1
kind: Agent
metadata:
name: kyc-browser
namespace: team-a
spec:
image: registry.acme.eu/agents/kyc-browser:1.0.0
tier: tier-1-microvm
profile: browser
model:
provider: vllm
endpoint: http://vllm.models.svc:8000/v1
name: qwen3-coder-30b
browser:
allowedDomains: [".handelsregister.de", "www.unternehmensregister.de"]
liveView: true
web:
deniedDomains: ["*.facebook.com"]
# scopes: tools:maqpna-egress is added by the browser profile
idleTimeout: 10m
maxSessionTTL: 2h
From config/samples/agent-code-interpreter.yaml:
# Code-interpreter agent (F-20): maqpna-exec sidecar and a per-session
# workspace PVC; the agent (and admins) run code through the gateway's
# POST /v1/sessions/{id}/exec (policy server maqpna-exec, audited by hash).
apiVersion: maqpna.com/v1alpha1
kind: Agent
metadata:
name: analyst
namespace: team-a
spec:
image: registry.acme.eu/agents/analyst:1.0.0
tier: tier-0-gvisor
profile: codeInterpreter
model:
provider: vllm
endpoint: http://vllm.models.svc:8000/v1
name: qwen3-coder-30b
codeInterpreter:
workspaceSize: 2Gi
# scopes: tools:maqpna-exec is added by the codeInterpreter profile
idleTimeout: 15m
Spec fields#
AgentSpec defines an agent workload.
| Field | Type | Required | Description |
|---|---|---|---|
a2a |
object | a2a exposes this agent to other agents through the gateway's A2A v1.0 proxy (POST /a2a/ |
|
a2a.allowedCallers |
[]string | allowedCallers lists the agents that may call this one: " |
|
a2a.description |
string | ||
a2a.endpoint |
string | endpoint is the agent's A2A JSON-RPC URL inside the cluster (a Service in front of the process serving A2A). Only the gateway calls it. Pattern: ^https?://. |
|
a2a.expose |
boolean | yes | expose publishes the agent at the gateway's /a2a/ |
a2a.skills |
[]object | skills advertised on the card; when set, a requested skill outside this list is denied (unknown_skill). | |
a2a.skills[].description |
string | ||
a2a.skills[].examples |
[]string | ||
a2a.skills[].id |
string | yes | id is the skill id; callers select it with message.metadata.skillId and policies match it as tool "skill:^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$. |
a2a.skills[].name |
string | yes | Min length: 1. |
a2a.skills[].tags |
[]string | ||
a2a.streaming |
boolean | streaming advertises SendStreamingMessage support on the card. | |
a2a.timeoutSeconds |
integer (int32) | Minimum: 0. Maximum: 3600. |
|
a2a.trust |
string | trust of this agent's answers for callers (default trusted). One of: trusted, untrusted. |
|
a2a.version |
string | version of the agent's card (default "1.0.0"). | |
args |
[]string | ||
browser |
object | browser configures the browser profile (F-19). | |
browser.allowedDomains |
[]string | allowedDomains is the browser's egress allow-list, enforced by the gateway egress proxy together with spec.web.deniedDomains and the gateway's global/namespace lists (same patterns as spec.web). Max items: 256. |
|
browser.liveView |
boolean | liveView runs Chromium headful on Xvfb with a noVNC endpoint (port 6080) that admins reach through the gateway for human-in-the-loop. | |
budget |
object | budget caps the agent's spend per session, day and month (enforced by the gateway on tool and model calls). | |
budget.currency |
string | currency is the ISO 4217 code of the perUSD amounts (default USD; the USD field names are legacy, see docs/api-conventions.md). It must equal the gateway's budgetCurrency: amounts are never converted and the gateway rejects budgets in another currency. Pattern: ^[A-Z]{3}$. |
|
budget.perDayUSD |
int or string | perDayUSD caps the agent's spend (all sessions) per day. Pattern: ^(\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))(([KMGTPE]i)\|[numkMGTPE]\|([eE](\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))))?$. |
|
budget.perMonthUSD |
int or string | perMonthUSD caps the agent's spend (all sessions) per month. Pattern: ^(\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))(([KMGTPE]i)\|[numkMGTPE]\|([eE](\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))))?$. |
|
budget.perSessionUSD |
int or string | perSessionUSD caps the spend of each session of the agent. Pattern: ^(\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))(([KMGTPE]i)\|[numkMGTPE]\|([eE](\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))))?$. |
|
codeInterpreter |
object | codeInterpreter configures the codeInterpreter profile (F-20). | |
codeInterpreter.workspaceSize |
int or string | workspaceSize is the size of the session workspace PVC (default: the operator's --workspace-size). Pattern: ^(\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))(([KMGTPE]i)\|[numkMGTPE]\|([eE](\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))))?$. |
|
command |
[]string | ||
env |
[]object | ||
env[].name |
string | yes | Name of the environment variable. May consist of any printable ASCII characters except '='. |
env[].value |
string | Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "". | |
env[].valueFrom |
object | Source for the environment variable's value. Cannot be used if value is not empty. | |
env[].valueFrom.configMapKeyRef |
object | Selects a key of a ConfigMap. | |
env[].valueFrom.configMapKeyRef.key |
string | yes | The key to select from the ConfigMap's Data field. Keys in the BinaryData field are not currently propagated to container env vars. |
env[].valueFrom.configMapKeyRef.name |
string | Name of the referent. This field is effectively required, but due to backwards compatibility is allowed to be empty. Instances of this type with an empty value here are almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Default: "". |
|
env[].valueFrom.configMapKeyRef.optional |
boolean | Specify whether the ConfigMap or its key must be defined | |
env[].valueFrom.fieldRef |
object | Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels['<KEY>'], metadata.annotations['<KEY>'], spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. |
|
env[].valueFrom.fieldRef.apiVersion |
string | Version of the schema the FieldPath is written in terms of, defaults to "v1". | |
env[].valueFrom.fieldRef.fieldPath |
string | yes | Path of the field to select in the specified API version. |
env[].valueFrom.fileKeyRef |
object | FileKeyRef selects a key of the env file. Requires the EnvFiles feature gate to be enabled. | |
env[].valueFrom.fileKeyRef.key |
string | yes | The key within the env file. An invalid key will prevent the pod from starting. The keys defined within a source may consist of any printable ASCII characters except '='. During Alpha stage of the EnvFiles feature gate, the key size is limited to 128 characters. |
env[].valueFrom.fileKeyRef.optional |
boolean | Specify whether the file or its key must be defined. If the file or key does not exist, then the env var is not published. If optional is set to true and the specified key does not exist, the environment variable will not be set in the Pod's containers. If optional is set to false and the specified key does not exist, an error will be returned during Pod creation. Default: false. |
|
env[].valueFrom.fileKeyRef.path |
string | yes | The path within the volume from which to select the file. Must be relative and may not contain the '..' path or start with '..'. |
env[].valueFrom.fileKeyRef.volumeName |
string | yes | The name of the volume mount containing the env file. |
env[].valueFrom.resourceFieldRef |
object | Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported. | |
env[].valueFrom.resourceFieldRef.containerName |
string | Container name: required for volumes, optional for env vars | |
env[].valueFrom.resourceFieldRef.divisor |
int or string | Specifies the output format of the exposed resources, defaults to "1" Pattern: ^(\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))(([KMGTPE]i)\|[numkMGTPE]\|([eE](\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))))?$. |
|
env[].valueFrom.resourceFieldRef.resource |
string | yes | Required: resource to select |
env[].valueFrom.secretKeyRef |
object | Selects a key of a secret in the pod's namespace | |
env[].valueFrom.secretKeyRef.key |
string | yes | The key of the secret to select from. Must be a valid secret key. |
env[].valueFrom.secretKeyRef.name |
string | Name of the referent. This field is effectively required, but due to backwards compatibility is allowed to be empty. Instances of this type with an empty value here are almost certainly wrong. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names Default: "". |
|
env[].valueFrom.secretKeyRef.optional |
boolean | Specify whether the Secret or its key must be defined | |
idleTimeout |
string | idleTimeout after which an idle session is suspended. Default: "15m". |
|
image |
string | yes | image is the agent container image. Min length: 1. |
maxConcurrentSessions |
integer (int32) | maxConcurrentSessions caps the agent's admitted, non-terminal sessions; extra sessions stay Pending with condition QuotaExceeded (0 = unlimited). Minimum: 0. |
|
maxSessionTTL |
string | maxSessionTTL caps the lifetime of sessions of this agent. | |
model |
object | ModelSpec identifies the LLM the agent talks to (via the gateway). Rule: provider llamay is OpenAI-compatible: adapter must be unset or openai. | |
model.adapter |
string | adapter selects the gateway's model provider adapter for this endpoint: openai (default; any OpenAI-compatible API), azure-openai, bedrock, vertex, gemini, anthropic or oci-genai. Unlike provider (informational), it changes the wire format and authentication the gateway uses upstream; the agent always speaks OpenAI (or native Anthropic Messages) to the gateway. One of: openai, azure-openai, bedrock, vertex, gemini, anthropic, oci-genai. |
|
model.adapterMode |
string | adapterMode selects the provider API: azure-openai v1 | deployments, bedrock converse | openai, vertex native | openai, anthropic direct | vertex | bedrock (default: the first). One of: v1, deployments, converse, openai, native, direct, vertex, bedrock. |
|
model.aliases |
map[string]string | aliases map model names the agent sends (e.g. "fast") to the provider's model IDs, so a provider retiring a model is an Agent change, not an image change. | |
model.apiKeySecretRef |
object | apiKeySecretRef selects the API key (a Secret key in the Agent's namespace) the gateway presents to the endpoint as "Authorization: Bearer |
|
model.apiKeySecretRef.key |
string | yes | Min length: 1. Max length: 253. Pattern: ^[-._a-zA-Z0-9]+$. |
model.apiKeySecretRef.name |
string | yes | Min length: 1. Max length: 253. |
model.apiVersion |
string | apiVersion is the Azure OpenAI api-version (adapterMode deployments) or the anthropic-version header. Pattern: ^[A-Za-z0-9._-]{1,40}$. |
|
model.dlpProfile |
string | dlpProfile names a gateway DLP profile (gateway config dlpProfiles) applied to this agent's model traffic; "none" disables DLP for it. Pattern: ^[a-z0-9][a-z0-9-]{0,62}$. |
|
model.endpoint |
string | endpoint is the upstream model's OpenAI-compatible base URL, e.g. http://vllm.models.svc:8000/v1. Only the gateway talks to it: sandboxes get MAQPNA_MODEL_ENDPOINT={gateway}/llm/^https?://[^/?#@]+. |
|
model.fallbacks |
[]object | fallbacks are ordered alternative OpenAI-compatible endpoints the gateway fails over to when the endpoint errors, times out, answers 5xx/429, has an open circuit or exhausted its requestsPerMinute. Each is checked against the SovereigntyPolicy like the endpoint (F-26). Max items: 8. |
|
model.fallbacks[].adapter |
string | adapter selects the gateway's model provider adapter for this endpoint: openai (default; any OpenAI-compatible API), azure-openai, bedrock, vertex, gemini, anthropic or oci-genai. Unlike provider (informational), it changes the wire format and authentication the gateway uses upstream; the agent always speaks OpenAI (or native Anthropic Messages) to the gateway. One of: openai, azure-openai, bedrock, vertex, gemini, anthropic, oci-genai. |
|
model.fallbacks[].adapterMode |
string | adapterMode selects the provider API: azure-openai v1 | deployments, bedrock converse | openai, vertex native | openai, anthropic direct | vertex | bedrock (default: the first). One of: v1, deployments, converse, openai, native, direct, vertex, bedrock. |
|
model.fallbacks[].apiKeySecretRef |
object | apiKeySecretRef selects this endpoint's own API key (a Secret key in the Agent's namespace); the primary endpoint's key is never sent here. | |
model.fallbacks[].apiKeySecretRef.key |
string | yes | Min length: 1. Max length: 253. Pattern: ^[-._a-zA-Z0-9]+$. |
model.fallbacks[].apiKeySecretRef.name |
string | yes | Min length: 1. Max length: 253. |
model.fallbacks[].apiVersion |
string | apiVersion is the Azure OpenAI api-version (adapterMode deployments) or the anthropic-version header. Pattern: ^[A-Za-z0-9._-]{1,40}$. |
|
model.fallbacks[].endpoint |
string | yes | endpoint is the OpenAI-compatible base URL (same normalisation as spec.model.endpoint). Min length: 1. Pattern: ^https?://[^/?#@]+. |
model.fallbacks[].jurisdiction |
string | jurisdiction where the endpoint runs (e.g. EU-FR). Pattern: ^[A-Za-z]{2}(-[A-Za-z0-9]{1,8})*$. |
|
model.fallbacks[].name |
string | name of the model at this endpoint (default: spec.model.name). | |
model.fallbacks[].project |
string | project is the Google Cloud project of a Vertex AI endpoint. Pattern: ^[a-z0-9][a-z0-9-]{2,62}$. |
|
model.fallbacks[].region |
string | region of the provider (Bedrock region, Vertex AI location such as europe-west3 or global, OCI region); it sets the endpoint's residency jurisdiction checked against the SovereigntyPolicy. Pattern: ^[a-z][a-z0-9-]{1,40}$. |
|
model.fallbacks[].requestsPerMinute |
integer (int32) | requestsPerMinute caps calls to this endpoint (0 = unlimited). Rate unit: HTTP requests (docs/api-conventions.md, "Rates"). Minimum: 0. |
|
model.jurisdiction |
string | jurisdiction where the endpoint runs (e.g. EU-DE); the gateway prefers endpoints in the session tier's jurisdiction (F-26). Pattern: ^[A-Za-z]{2}(-[A-Za-z0-9]{1,8})*$. |
|
model.maxTokensPerRequest |
integer (int64) | maxTokensPerRequest caps max_tokens of each model request; larger or missing values are clamped by the gateway (0 = unlimited). Minimum: 0. |
|
model.name |
string | name of the model. | |
model.project |
string | project is the Google Cloud project of a Vertex AI endpoint. Pattern: ^[a-z0-9][a-z0-9-]{2,62}$. |
|
model.provider |
string | provider, e.g. anthropic, openai, vllm, llamay. "llamay" makes the gateway bind each session to its own llamay inference context and fork it with the session (docs/integrations/llamay.md); it is OpenAI-compatible, so adapter must be unset or openai. Max length: 128. |
|
model.providerTools |
[]string | providerTools allow-lists provider-hosted server tools on this Agent's model route (all endpoints): web_search, web_fetch, code_execution, file_search, code_interpreter, computer_use, image_generation, google_search, url_context, system_tool, or a versioned type such as web_search_20250305. They search, fetch and execute at the provider, outside the gateway's egress, DLP and audit; unlisted ones are refused (403 provider_hosted_tool). Capped by the TrustTier's allowedProviderTools: entries it does not allow are dropped from the route (condition ProviderToolsAllowed=False). Provider-hosted MCP is never allowed. Max items: 16. |
|
model.reasoning |
boolean | reasoning marks the model as an OpenAI-style reasoning model that takes max_completion_tokens (default: detected from o-series and gpt-5 model IDs). | |
model.region |
string | region of the provider (Bedrock region, Vertex AI location such as europe-west3 or global, OCI region); it sets the endpoint's residency jurisdiction checked against the SovereigntyPolicy. Pattern: ^[a-z][a-z0-9-]{1,40}$. |
|
model.requestsPerMinute |
integer (int32) | requestsPerMinute caps calls to the endpoint across all sessions of the agent (0 = unlimited); an exhausted endpoint fails over. Rate unit: HTTP requests to the model endpoint (docs/api-conventions.md). Minimum: 0. |
|
model.tokensPerMinute |
integer (int64) | tokensPerMinute caps the model tokens (prompt + completion) each session of the agent may use per minute at the gateway (0 = unlimited). Rate unit: tokens (docs/api-conventions.md, "Rates"). Minimum: 0. |
|
policyRef |
string | policyRef names the ToolPolicy (same namespace) governing this agent. | |
profile |
string | profile selects the sandbox pod profile (F-19/F-20): default (agent container only), browser (headless Chromium sidecar with CDP on localhost and gateway-governed egress) or codeInterpreter (exec server sidecar and a session workspace volume). One of: default, browser, codeInterpreter. |
|
resources |
object | ResourceRequirements describes the compute resource requirements. | |
resources.claims |
[]object | Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. This field depends on the DynamicResourceAllocation feature gate. This field is immutable. It can only be set for containers. | |
resources.claims[].name |
string | yes | Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. |
resources.claims[].request |
string | Request is the name chosen for a request in the referenced claim. If empty, everything from the claim is made available, otherwise only the result of this request. | |
resources.limits |
map[string]int or string | Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | |
resources.requests |
map[string]int or string | Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. Requests cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | |
scopes |
[]string | scopes the agent may be granted. Defaults to tools: |
|
tier |
string | yes | tier is the name of the TrustTier this agent runs in. Min length: 1. |
tools |
[]object | tools are MCP servers reached via the gateway. | |
tools[].name |
string | yes | name of the tool server; must be a DNS-label-like identifier. Max length: 63. Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$. |
tools[].serverRef |
object | serverRef binds this tool to an MCPServer (same namespace unless namespace is set; a cross-namespace server must be shared with this Agent's namespace). | |
tools[].serverRef.name |
string | yes | Max length: 63. Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$. |
tools[].serverRef.namespace |
string | Max length: 63. Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$. |
|
tools[].upstreamURL |
string | upstreamURL is the real MCP server URL; only the gateway talks to it. Deprecated: register an MCPServer and use serverRef. The operator publishes it as an implicit server " |
|
web |
object | web governs the gateway's built-in maqpna-web tool (fetch/search) for this agent (F-21). | |
web.allowedDomains |
[]string | Max items: 256. |
|
web.deniedDomains |
[]string | Max items: 256. |
|
workspace |
object | workspace gives each session a persistent workspace volume (a PVC mounted into the agent container): the state that VolumeSnapshot snapshots and forks carry (F-22). Sandbox mode only (SandboxClaim warm pools cannot add volumes). | |
workspace.mountPath |
string | mountPath in the agent container (default /workspace). Pattern: ^/[^:]*$. |
|
workspace.size |
int or string | yes | size of the PVC, e.g. 1Gi. Pattern: ^(\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))(([KMGTPE]i)\|[numkMGTPE]\|([eE](\+\|-)?(([0-9]+(\.[0-9]*)?)\|(\.[0-9]+))))?$. |
workspace.storageClassName |
string | storageClassName of the PVC (a CSI class with snapshot support for VolumeSnapshot forks); the default class when unset. | |
workspace.volumeSnapshotClassName |
string | volumeSnapshotClassName used for snapshots of the workspace. |
Status fields#
AgentStatus is the observed state of an Agent.
The operator writes status; do not set it yourself.
| Field | Type | Required | Description |
|---|---|---|---|
activeSessions |
integer (int32) | activeSessions counts sessions not in a terminal phase. | |
conditions |
[]object | ||
conditions[].lastTransitionTime |
string (date-time) | yes | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. |
conditions[].message |
string | yes | message is a human readable message indicating details about the transition. This may be an empty string. Max length: 32768. |
conditions[].observedGeneration |
integer (int64) | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. Minimum: 0. |
|
conditions[].reason |
string | yes | reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. Min length: 1. Max length: 1024. Pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$. |
conditions[].status |
string | yes | status of the condition, one of True, False, Unknown. One of: True, False, Unknown. |
conditions[].type |
string | yes | type of condition in CamelCase or in foo.example.com/CamelCase. Max length: 316. Pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$. |
observedGeneration |
integer (int64) |