> ## Documentation Index
> Fetch the complete documentation index at: https://docs.komodor.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Declaring resources

> Declare KAOP resources as Kubernetes custom resources, read their status, and understand how deletion and secrets work.

Declaring a resource for the Komodor Agentic Operation Platform (KAOP) means applying a Kubernetes
custom resource — a `Credential`, an `McpServer`, or one of the other supported kinds — to a cluster
running the operator described in
[Configuration clusters](/security-and-governance/identity-and-access/configuration-clusters). The
operator reconciles what you declare through the KAOP API and writes the result back onto the
resource's own `status`, so the manifest is the source of truth without a separate API call of your
own.

## How a declaration maps to KAOP

* Every kind is in the `agentops.komodor.io/v1alpha1` API group, and every resource is namespaced.
* The namespace binds the resource to one account: the cluster install running in that namespace is
  tied to a single KAOP account.
* `spec.name` is the resource's name in KAOP and defaults to `metadata.name`. Changing `spec.name`
  does not rename anything — it points the declaration at a different name, so the old resource is
  left behind.
* A field you set in `spec` is reapplied on every resync (`operator.resyncInterval`, default `5m`),
  so an out-of-band change to it is corrected back. A field you leave unset stays under KAOP's own
  control.
* KAOP remains the validator. A spec the CRD's schema accepts can still be rejected — the reason
  appears on the resource's `Synced` condition.

## Supported kinds

| Kind | Declares | Related page |
| - | - | - |
| `Credential` | A stored value, delivered from a referenced Secret. | [Credentials & secrets](/security-and-governance/identity-and-access/credentials-secrets) |
| `EvalFlow` | An evaluation that grades a set of agents' runs against criteria, through one evaluator agent. | [Evaluations](/manage-your-agents/optimize/evaluations) |
| `GoldenScenario` | A single scored test case, tagged by domain. | — |
| `GoldenSuite` | A group of golden scenarios under one runner agent. | — |
| `Guardrail` | A rule that blocks, holds, redacts, or records a matched action for a set of agents. | [Standards & Guardrails](/security-and-governance/controls/standards-guardrails) |
| `HostedAgent` | A hosted agent's model, image, MCP servers, skills, and tools. | [Build — how it works](/manage-your-agents/build/how-it-works) |
| `IncidentPipeline` | Routes an alert source to an orchestrator and specialist agents as an incident pipeline. | [Incident management & troubleshooting](/modules-and-workflows/sre/incidents) |
| `IntegrationConnection` | A connection to a built-in integration provider, authenticated from a referenced Secret. | [Integrations list](/manage-your-agents/build/built-in-integrations) |
| `KnowledgeBase` | A knowledge base agents retrieve from and cite. | [Knowledge base](/manage-your-agents/build/knowledge-base) |
| `McpGroup` | A named bundle of MCP servers with its own allow/deny rules. | [Integration groups](/manage-your-agents/build/integration-groups) |
| `McpPolicy` | A tool-call policy enforced on one or more MCP targets. | [MCP Gateway](/security-and-governance/architecture-considerations/mcp-gateway) |
| `McpServer` | An upstream MCP server, its transport, and the credential it authenticates with. | [MCP Gateway](/security-and-governance/architecture-considerations/mcp-gateway) |
| `Module` | Turns on a module and holds its settings. | [Modules & workflows](/modules-and-workflows/overview) |
| `ModuleWorkflowTemplate` | A reusable workflow template published under a module. | [Modules & workflows](/modules-and-workflows/overview) |
| `NotificationSink` | A destination — a channel or your own endpoint — that receives KAOP's events. | [Outbound webhooks](/manage-your-agents/run/outbound-webhooks) |
| `ReviewWorkflow` | Binds a set of repositories and reviewer agents for automated code review. | — |
| `Schedule` | Runs one agent on a recurring cron expression. | [Triggers & schedules](/manage-your-agents/build/triggers-schedules) |
| `SelfHostedAgentSettings` | Settings for an agent that runs in your own infrastructure instead of KAOP's. | [Deployment methods](/get-started/deployment-methods) |
| `Skill` | A versioned runbook or procedure agents can use. | [Skills](/manage-your-agents/build/skills) |
| `WebhookTrigger` | An inbound endpoint that starts an agent run from an HTTP request. | [Integrations list](/manage-your-agents/build/built-in-integrations) |

Every kind shares the same `spec`/`status` contract above. For the full set of fields a kind
accepts, run `kubectl explain <kind>.spec` against a cluster that has the CRDs installed — each
field carries its own description.

## Annotated example

A `Credential` resolves its value from a Kubernetes `Secret` in its own namespace rather than
holding it inline:

```yaml theme={null}
apiVersion: v1
kind: Secret
metadata:
  name: datadog-api-key
  namespace: agentops
type: Opaque
stringData:
  api-key: "<your Datadog API key>"
---
apiVersion: agentops.komodor.io/v1alpha1
kind: Credential
metadata:
  name: datadog-api
  namespace: agentops
spec:
  name: datadog-api
  valueSecretRef:
    name: datadog-api-key
    key: api-key
```

An `McpServer` then references that credential by name, alongside the fields that reach the
upstream server itself:

```yaml theme={null}
apiVersion: agentops.komodor.io/v1alpha1
kind: McpServer
metadata:
  name: datadog-mcp
  namespace: agentops
spec:
  name: datadog-mcp
  url: https://mcp.datadoghq.com
  transport: http
  credentialRef: datadog-api
  deletionPolicy: orphan
```

Apply both and read back the result. `SYNCED` is a default-visible column; `RESOURCE` needs
`-o wide`:

```bash theme={null}
kubectl apply -f secret.yaml -f credential.yaml -f mcpserver.yaml

kubectl -n agentops get mcpservers -o wide
# NAME          SYNCED   RESOURCE             AGE
# datadog-mcp   True     mcp_server_01h...    14s
```

## References between resources

A field ending in `Ref` — `credentialRef`, `agentRef`, `mcpGroupRef`, and the rest — resolves by
the KAOP name of the resource it points at, not by the Kubernetes object name.

* A reference naming something that does not exist yet reports `WaitingForDependency` on the
  `Synced` condition, and is retried on every resync rather than treated as a standing error.
* A reference naming something that already exists but that this cluster does not declare reports
  `Conflict`. The existing resource is never taken over.

## Secrets

Values are read from Secrets in the same namespace as the resource that references them, and the
value never appears in the spec a cluster can read, nor in status.

Rotation is detected through `status.secretHashes` — a per-field fingerprint of the last value
pushed, so an unrotated Secret is a no-op resync rather than a repeated write.

<Warning>
  Applying manifests with ArgoCD, Flux, or `helm template` rather than installing with Helm against a
  live cluster means the operator cannot read its own rotation-key Secret back on each upgrade. Create
  that Secret yourself and name it in `rotationKey.existingSecret`, or a fresh key is generated on
  every sync.
</Warning>

## Reading status

The `Synced` condition reports whether KAOP matches the declared spec, with one of eight reasons:

| Reason | Meaning | What to do |
| - | - | - |
| `Applied` | KAOP matches the spec. | Nothing — this is the steady state. |
| `Rejected` | KAOP's own validator refused the declaration. | Read the condition's `message` for the control plane's reason, and fix the spec. |
| `Conflict` | The name is already claimed by another cluster's resource, by a resource no cluster declares, or by an install whose claim this one may not take. | Resolve ownership at the resource or cluster named in the message. |
| `SecretMissing` | A referenced Secret or key is not in the resource's namespace. | Create the Secret or key, or fix the reference. |
| `InstallPaused` | This cluster install is paused. | Resume the install to reapply the declaration. |
| `Error` | The operator could not attribute the failure to the declaration itself — an authentication failure, an exhausted retry, or a field role this build does not implement yet. | Check the operator's logs and the cluster install's credential. |
| `SecretRotated` | A referenced Secret's value changed and was pushed again. | Nothing — this is a successful rotation, reported as its own event. |
| `WaitingForDependency` | A `*Ref` field names a resource that does not exist yet. | Create the referenced resource; the operator retries every resync. |

`status.resourceId` is the KAOP id of the managed resource. For the control plane's own wording on
a failure, read the condition's message with `kubectl describe` on the resource.

## Deleting a declaration

<Warning>
  The default `deletionPolicy` is `delete`: deleting the Kubernetes object removes the resource from
  KAOP too. Set `deletionPolicy: orphan` to leave the KAOP resource in place and release only the
  operator's claim, so it can be managed elsewhere afterwards. Deletion still goes through while the
  cluster install is paused — a pause stops reassertion, not an explicit delete. `kubectl delete --cascade=orphan` is about Kubernetes-owned objects and does not reach the KAOP resource either way.
</Warning>

## Operator scope and lifecycle

* The operator watches only the namespace it is released into. Covering a second namespace means
  installing the chart again there with `crds.install=false`, since the CRDs are cluster-scoped and
  already belong to the first release.
* Its permissions are namespace-scoped and narrow: no `create` or `delete` on the custom resources
  it reconciles, and `get` only on Secrets.
* `helm uninstall` leaves the CRDs and your declared resources in place rather than deleting them.
* A control plane behind an internal certificate authority needs `caBundle.existingConfigMap`
  pointed at a ConfigMap of PEM certificates, or the operator never becomes ready.
* To check which build is running, read the image tag on the operator's pod — it is distroless, so
  there is no shell to exec into instead.

## Next steps

<CardGroup cols={2}>
  <Card title="Configuration clusters" href="/security-and-governance/identity-and-access/configuration-clusters">
    Connect a cluster and read its sync status.
  </Card>

  <Card title="Credentials & secrets" href="/security-and-governance/identity-and-access/credentials-secrets">
    Manage credentials declared through this interface alongside the ones created in KAOP.
  </Card>

  <Card title="MCP Gateway" href="/security-and-governance/architecture-considerations/mcp-gateway">
    Configure governed access to the MCP servers a cluster can declare.
  </Card>
</CardGroup>


## Related topics

- [Configuration clusters](/security-and-governance/identity-and-access/configuration-clusters.md)
- [What's new](/reference/changelog.md)
- [Kubernetes](/manage-your-agents/build/catalog/kubernetes.md)
- [Roles & permissions](/security-and-governance/identity-and-access/roles-permissions.md)
- [Agent isolation & tenancy](/security-and-governance/architecture-considerations/agent-isolation-tenancy.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.