EvoHub DocsEvoHub Docs Sign in

What the agent sends

Use with AI
View as MarkdownThis page as plain text, for pasting into an AI tool Open in ClaudeAsk Claude questions about this page Open in ChatGPTAsk ChatGPT questions about this page
Connect to Cursor / VS Code / ClaudeSearch and read these docs from your AI tool (MCP server)

MCP server URL

https://docs.evohub.io/mcp

Claude Code

claude mcp add --transport http evohub-docs https://docs.evohub.io/mcp

Claude (claude.ai and Claude Desktop): Settings → Connectors → Add custom connector, and paste the URL above.

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "evohub-docs": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://docs.evohub.io/mcp"
      ]
    }
  }
}

Cursor — ~/.cursor/mcp.json

{
  "mcpServers": {
    "evohub-docs": {
      "url": "https://docs.evohub.io/mcp"
    }
  }
}

VS Code — .vscode/mcp.json

{
  "servers": {
    "evohub-docs": {
      "type": "http",
      "url": "https://docs.evohub.io/mcp"
    }
  }
}

This page is the contract for what leaves your cluster: what the agent sends, how it removes secrets before sending, and what it never sends. It is written for the people who approve installing it. What the agent sends from a VM is on Install on a VM. If the agent ever does something not described here, that is a bug; please report it.

Requests

Request When Body
POST /api/v1/agent-enroll Until enrolled The public key, the hostname (the pod's name, or the VM's under systemd), the agent's version and platform, and its name if you set one
POST /api/v1/catalog/ingest/heartbeat Every minute Its version and uptime
POST /api/v1/catalog/ingest/sweeps At the start of each sweep, every 5 minutes Empty
POST /api/v1/catalog/ingest/sweeps/{id}/resources Per batch of up to 1000 objects The objects, below
POST /api/v1/catalog/ingest/sweeps/{id}/complete At the end of a sweep Whether it is complete, and the kinds it could not list
POST /api/v1/catalog/ingest/live Every minute Live state, below

Every request carries User-Agent: evohub-agent/<version>. Every request after enrollment is signed; the enrollment request carries the token instead. EvoHub also sees the address the requests come from.

Each object

For every object of the kinds it may list (see What it is allowed to do), the agent sends three things:

  • An identity, as a path: k8s://<cluster id>/<apiVersion>/<Kind>/<namespace>/<name>. The cluster ID is the uid of your kube-system namespace.
  • A content hash: the SHA-256 of the redacted content. When EvoHub already holds that content, only the hash is sent.
  • The redacted content: the object as the Kubernetes API returns it, redacted as below, with resourceVersion, generation, managedFields and selfLink removed from metadata, spec kept in full (redacted), and status removed except for these fields:
Kind status kept
Node nodeInfo (machine ID, system UUID, boot ID, kernel version, OS image, architecture, kubelet and container runtime versions), addresses, capacity
Service, Ingress loadBalancer: assigned IPs and hostnames
Namespace phase
PersistentVolumeClaim phase, capacity

In practice EvoHub receives, for example: container names, images, ports, resource requests and limits; the non-secret parts of commands and arguments; probe paths and ports; the names of environment variables, volumes, Secrets, ConfigMaps, ServiceAccounts and image pull secrets; volume sources such as an NFS server or a host path; labels, and annotations that pass the rules below; Service cluster IPs and load balancer ranges; Ingress hosts, paths and TLS Secret names; a Node's provider ID, pod CIDR and taints; HPA targets; and PVC storage classes and sizes.

An object larger than 256 KiB after redaction is sent with only its name, namespace, uid, labels, owner references and creation time.

Live state

Every minute the agent reports how each Deployment, StatefulSet, DaemonSet and CronJob is running now: replicas wanted, ready, available and updated; its pods counted by phase; their restarts; and how many containers are in each failing state, by the state's name only (CrashLoopBackOff, ImagePullBackOff, OOMKilled and a few others; anything else is sent as Other). For the service map it adds one line per pod, at most 200 per workload: the pod's name, ReplicaSet, node, phase, readiness, restarts, start time and failing state's name.

No pod spec, no environment, no messages, nothing a container printed. EvoHub keeps only the latest report, to show health, and treats one older than ten minutes as unknown. Set catalog.liveState.enabled=false in the chart to send none, and the agent then has no access to pods at all.

Redaction

The agent applies these rules inside your cluster, before an object is hashed or sent. Rules 1 to 6 are structural: they apply wherever the field is, whatever it holds.

  1. Environment variable values. Every value is removed, whatever the variable is called, in containers, init containers and ephemeral containers. The variable's name stays, and so does what a valueFrom points at, such as the name and key of a secretKeyRef.
  2. Command lines: a container's command and args, and any probe's or lifecycle hook's exec.
    • --password=x, PASSWORD=x and -px lose their value.
    • The argument after a bare --password (or --token, --secret, …) is replaced.
    • The whole program after an interpreter's script flag is replaced: -c, -ec, -lc and similar, -e, --eval and -Command.
  3. Probe headers. Every probe httpHeaders value is replaced.
  4. Volume drivers. Every volume driver options and volumeAttributes value is replaced.
  5. Annotations, in every annotations map including pod templates:
    • kubectl.kubernetes.io/last-applied-configuration is removed.
    • Annotations under evohub.io/, app.kubernetes.io/, meta.helm.sh/release-, prometheus.io/ and deployment.kubernetes.io/revision are kept as they are.
    • Any other annotation keeps its value only if the value is at most 256 bytes, one line, not JSON, and the key does not end in snippet.
  6. Secrets and ConfigMaps. A Secret's data and stringData would be removed and a ConfigMap reduced to its key names. The agent does not list either; this rule is there for safety only.
  7. A final check on every remaining string. A string is replaced if:
    • its key ends in a word such as password, secret, token, apikey, credentials, auth, dsn or _key
    • it looks like a credential: an AWS key ID, a Stripe, GitHub, GitLab, Slack or Google key, a JWT, a private key, an Authorization: header, a bearer or basic credential, a URL with a password or a token in its query, or an EvoHub token
    • it looks like random key material: 24 or more characters with no spaces, mixing upper case, lower case and digits, with high entropy

Replaced values read [REDACTED]. The hash is computed after redaction, so a rotated secret is not a change.

What the rules guarantee, and what they do not

Rules 1 to 6 are structural, so whatever a field they cover holds is removed. Rule 7 is pattern-based and catches common forms only. It can miss, for example:

  • a short password passed as a positional argument (redis-cli -a x)
  • a token that is all lower case or hex
  • a secret written into a label or an unlisted spec field

Where a value is in an environment variable, a mounted Secret or a secretKeyRef, it is never sent. EvoHub runs a scanner of the same kind again when data arrives, and never logs request bodies.

What it never sends

  • the value of any environment variable, secret or not
  • the contents of any Secret or ConfigMap
  • kubectl's last-applied configuration, and the values of annotations that fail the rules above
  • the scripts given to sh -c and similar
  • pod specs, logs, events, metrics, or anything from inside a container
  • its own private key
  • the enrollment token, once it has enrolled

The agent's own log records counts, IDs (agent, cluster, sweep), its public key, and error messages from EvoHub and Kubernetes. It never records any object's content.

Last updated Powered by