Skip to main content

What is the Niro agent?

The Niro agent is a lightweight daemon that runs as a Kubernetes Deployment inside your cluster, in the niro-system namespace. It’s the only component you install — everything else is managed by Niro. The agent is:
  • Stateless — cluster state is reconstructed from the Kubernetes API on every heartbeat
  • NAT-friendly — all traffic is outbound HTTPS; no inbound ports or VPN required
  • Non-invasive — read-only by default; write access requires explicit opt-in
  • Self-updating — can roll itself to the latest version if you enable the self-update capability

How the agent works

Enrollment

The agent runs the enrollment flow exactly once when first installed:
  1. Reads the enrollment token from the NIRO_TOKEN environment variable
  2. Contacts Niro to exchange the token for a long-lived key
  3. Stores the key in a Kubernetes Secret in niro-system
  4. The enrollment token is invalid after this point — the agent uses its key for all future requests

Heartbeat

Every ~15 seconds the agent collects a snapshot and sends it to Niro:
Nodes
  ├── name, status, roles, Kubernetes version
  └── CPU/memory: capacity, allocatable, usage (from metrics-server if present)

Pods
  ├── name, namespace, phase, restarts, owner (Deployment/StatefulSet/DaemonSet)
  ├── containers: image, resource requests/limits, liveness/readiness probes
  ├── privileged flag, imagePullSecrets
  └── CPU/memory usage (from metrics-server if present)

Kubernetes Events
  └── Warning-type only, recent window

Capabilities
  └── logs_enabled, apply_enabled, self_update_enabled
Niro processes the heartbeat to update fleet state, evaluate policies, detect incidents, and determine if an agent update should be delivered.

Command channel

The agent maintains a persistent connection to Niro. When Niro has a command ready (apply, delete, stream logs, ping), it delivers it over this connection. The agent processes the command, reports the result, and immediately re-establishes the connection. This creates a persistent, low-latency channel with no inbound connectivity requirements.

Default RBAC

The agent’s default role is read-only:
# What the agent can do by default
- apiGroups: [""]
  resources: ["nodes", "pods", "namespaces", "events"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "statefulsets", "daemonsets", "replicasets"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["metrics.k8s.io"]
  resources: ["nodes", "pods"]
  verbs: ["get", "list"]
Write access and log access are granted separately per cluster by re-running the installer with capability flags.

Capabilities

Capabilities are opt-in, additive, and reversible. Each capability grants additional RBAC permissions and unlocks corresponding features in the Niro dashboard.
FlagRBAC grantedDashboard feature
NIRO_ENABLE_PODS=1list pods (default on)Pod inventory
NIRO_ENABLE_LOGS=1pods/logView logs button on pods
NIRO_ENABLE_APPLY=1create/update/patch/delete on managed resourcesApply to cluster, config management
NIRO_ENABLE_SELF_UPDATE=1patch own DeploymentAgent auto-update
To enable a capability, re-run the installer (no new token needed — the agent reuses its existing key):
curl -fsSL https://get.niro.cx/install.sh | NIRO_ENABLE_LOGS=1 NIRO_ENABLE_APPLY=1 sh
To revoke a capability, set the flag to 0:
curl -fsSL https://get.niro.cx/install.sh | NIRO_ENABLE_LOGS=0 sh
The capability appears in the dashboard within ~15 seconds (the next heartbeat reports the updated capability state).
Setting NIRO_ENABLE_APPLY=1 grants delete only for managed namespaced resources. Niro never deletes namespaces.

Log streaming

When you click View logs in the dashboard, Niro:
  1. Sends a log stream command to the agent with the target pod/container
  2. The agent streams the container logs and forwards them to Niro in batches
  3. The dashboard subscribes to the stream and renders lines in real time
Log streams are coordinated through Niro so they work reliably regardless of which backend instance you’re connected to.

Self-update

If NIRO_ENABLE_SELF_UPDATE=1, the agent can roll itself to a new version when Niro signals an update is available. The agent patches its own Deployment’s image tag, the new pod starts up, and Niro reflects the updated version within one status cycle.

Protocol versioning

The agent protocol is versioned and backward compatible — older agents continue to heartbeat and receive commands, they just don’t report capabilities or features added in newer versions. You can update agents at any time without coordination.
Last modified on June 12, 2026