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

# Policies & Standards

> Advisory Kubernetes best-practice checks that run at build time, PR time, and runtime.

## Overview

Niro includes a built-in policy engine that checks your deployments against Kubernetes best practices. Findings are **advisory only** — they never block a deployment or PR merge — but they surface common misconfigurations before they become production incidents.

<Note>
  The [Security Posture](/features/security-posture) page combines these standards checks with external policy engine violations from OPA Gatekeeper and Kyverno, plus image vulnerability scanning — all in one view.
</Note>

Policy checks run at three points:

<CardGroup cols={3}>
  <Card title="Build time" icon="hammer">
    Inline warnings in the Visual Builder as you fill in the form.
  </Card>

  <Card title="PR time" icon="code-pull-request">
    Comment and check run posted to GitHub when a PR is opened against a linked repo.
  </Card>

  <Card title="Runtime" icon="circle-play">
    Findings on the deployment detail page, updated continuously from live cluster state.
  </Card>
</CardGroup>

## Severity levels

| Severity              | Meaning                                                                            |
| --------------------- | ---------------------------------------------------------------------------------- |
| <Badge>High</Badge>   | Significant reliability or security risk. Address before deploying to production.  |
| <Badge>Medium</Badge> | Best-practice violation. Should be resolved but won't immediately cause an outage. |
| <Badge>Low</Badge>    | Informational. Low immediate risk.                                                 |

Some rules escalate severity based on the cluster's [environment](/concepts/environments) — a single replica is informational on a dev cluster and high severity on a production cluster.

## Rules

<AccordionGroup>
  <Accordion title="Missing resource requests" icon="microchip">
    **Default severity:** Medium

    A container doesn't have CPU or memory `requests` set.

    Without requests, the Kubernetes scheduler can't make an informed placement decision. The pod may be scheduled onto a node that can't support its workload, leading to OOM kills or CPU throttling.

    **Fix:** Set `resources.requests.cpu` and `resources.requests.memory` on every container. A safe starting point: `100m` CPU and `128Mi` memory.
  </Accordion>

  <Accordion title="Missing resource limits" icon="gauge">
    **Default severity:** Medium

    A container doesn't have CPU or memory `limits` set.

    Without limits, a misbehaving container can consume all available resources on a node, starving other workloads.

    **Fix:** Set `resources.limits.cpu` and `resources.limits.memory` on every container.
  </Accordion>

  <Accordion title="Missing health probes" icon="heart-pulse">
    **Default severity:** Medium

    A container doesn't have a readiness or liveness probe configured.

    Without a readiness probe, Kubernetes routes traffic to a pod before it's ready. Without a liveness probe, a stuck pod won't be automatically restarted.

    **Fix:** Add at least a readiness probe. Liveness probes are recommended for long-running workloads.
  </Accordion>

  <Accordion title="Privileged container" icon="triangle-exclamation">
    **Default severity:** High (all environments)

    A container runs with `securityContext.privileged: true` or `securityContext.allowPrivilegeEscalation: true`.

    Privileged containers have full access to the host kernel and can escape the container boundary. This is rarely needed for application workloads.

    **Fix:** Remove the privileged flag. If you need specific elevated capabilities (e.g. `CAP_NET_ADMIN`), use `securityContext.capabilities.add` to grant only what's needed.
  </Accordion>

  <Accordion title="Mutable image tag (latest)" icon="tag">
    **Default severity:** Low (non-production) · High (production)

    The container image uses a mutable tag such as `:latest`, making deployments non-reproducible.

    Mutable tags mean the image that runs in production can change without a code change, making rollbacks harder and debugging more difficult.

    **Fix:** Pin to an explicit version tag (e.g. `v1.2.3`) or a digest. Use [Image Automation](/guides/image-automation) to automate image bumps via PRs.
  </Accordion>

  <Accordion title="Single replica" icon="circle-dot">
    **Default severity:** Info (non-production) · High (production)

    The Deployment has only one replica, providing zero redundancy.

    A single replica means any pod eviction, node reboot, or node failure will cause downtime.

    **Fix:** Set `replicas: 2` or more for production workloads. Consider adding a [Pod Disruption Budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) to prevent simultaneous eviction.
  </Accordion>

  <Accordion title="Private registry without credentials" icon="lock-open">
    **Default severity:** Medium

    A manifest references an image from a registry that requires authentication (GHCR, ECR, GCR, Quay.io) but no `imagePullSecret` is configured.

    Without credentials, the agent will fail to pull the image, resulting in `ImagePullBackOff`.

    **Fix:** Add credentials in [Registries](/guides/private-registries). Niro injects the `imagePullSecret` automatically in generated manifests.
  </Accordion>

  <Accordion title="Namespace mismatch" icon="arrows-left-right">
    **Default severity:** Medium

    The deployment is being applied to a different namespace than the one specified in the manifests.

    This usually indicates a misconfiguration — either the manifests have the wrong namespace, or the deployment is targeting the wrong cluster.

    **Fix:** Ensure the target namespace in the deployment settings matches the namespace in the manifest files.
  </Accordion>

  <Accordion title="No rollback history" icon="clock-rotate-left">
    **Default severity:** Low (non-production) · Medium (production)

    The deployment has never had a successful apply, so there's no previous version to roll back to.

    This is informational for newly created deployments. It resolves automatically after the first successful apply.
  </Accordion>
</AccordionGroup>

## Environment escalation

Clusters tagged as `production` trigger stricter severity on risk-relevant rules:

| Rule                  | Non-production | Production |
| --------------------- | -------------- | ---------- |
| Single replica        | Info           | High       |
| Mutable `:latest` tag | Low            | High       |
| No rollback history   | Low            | Medium     |
| All other rules       | Unchanged      | Unchanged  |

Set the environment on a cluster in its **Settings** tab. See [Environments](/concepts/environments) for details.

## Disabling findings

Individual findings can't be suppressed per-deployment — the engine evaluates all rules. Use the severity filter in the dashboard to focus on what matters. Findings on non-production clusters for rules like `single-replica` are kept at Info severity specifically to reduce noise.

## Related

<CardGroup cols={2}>
  <Card title="Security Posture" icon="shield-check" href="/features/security-posture">
    The unified security view — built-in standards, external policy engine violations, and image scanning.
  </Card>

  <Card title="Visual Builder" icon="wand-magic-sparkles" href="/features/visual-builder">
    See policy findings inline as you build — before deploying.
  </Card>

  <Card title="Set Up GitOps" icon="code-branch" href="/guides/gitops">
    Findings posted as PR comments on every manifest change.
  </Card>

  <Card title="Environments" icon="layer-group" href="/concepts/environments">
    How environment tagging affects severity escalation.
  </Card>
</CardGroup>
