# Install Zero-Code on a cluster

Connect a Kubernetes cluster to your project with the command the console gives you, check that every node is covered, and upgrade or remove the install.

One Helm release puts Zero-Code on a cluster. It installs an operator, and the operator runs one _node agent_ on every node.

A new install runs in monitor mode: it records what happens and denies nothing. Use this guide to connect a cluster for the first time, and later to upgrade or remove the install.

## Before you begin

You need:

- A plan that includes Zero-Code.
- The `read:kubernetes` permission in your project. AuthFI permissions decide who can see a cluster in the console, not Kubernetes RBAC.
- `helm` and `kubectl`, with access to the cluster.

The cluster must meet these requirements.

| Requirement   | Value                                                                          |
| ------------- | ------------------------------------------------------------------------------ |
| Kubernetes    | 1.30 or newer                                                                  |
| Nodes         | Linux on x86-64, kernel 5.18 or newer. 6.6 or newer is best.                   |
| Service proxy | kube-proxy in iptables mode                                                    |
| Kernel        | The BPF security module enabled, for the rules on where a workload may connect |
| Network       | Outbound HTTPS from the nodes to your project's issuer, the project's URL      |

<Steps>

### Open the install command

In the AuthFI console, open **Zero-Code > Kubernetes** and choose **Install on a cluster**.

The **Install the node agent** dialog shows the command to run. You run one command per cluster, and there is nothing else to configure.

### Verify the chart and images

The chart and both images are signed. The signing identity is the AuthFI release workflow.

Verify them with `cosign` before you install, as your own supply-chain rules require.

### Run the command against the cluster

Copy the command from the dialog and run it in a shell that is connected to the cluster. Then choose **Done**.

</Steps>

## Check that it works

Open **Zero-Code > Kubernetes**. The cluster appears in the list when its first node checks in.

| Column        | Shows                                                                               |
| ------------- | ----------------------------------------------------------------------------------- |
| **Health**    | Healthy when every node is ready, no pod is failing and the node agent is reporting |
| **Nodes**     | The cluster's nodes                                                                 |
| **Pods**      | The cluster's pods                                                                  |
| **Protected** | The workloads whose every rule enforces                                             |
| **Node mode** | The mode the nodes run in                                                           |

Select the cluster's row to open it. Its **Workloads** and **Services** tabs fill in as the node agent discovers them.

You can also check from the cluster. List the install's `AgentRuntime`, the custom resource that describes it.

```bash
kubectl -n authfi-system get agentrt
```

```text
NAME                READY   DESIRED   DEGRADED   ENTITLED
authfi-ebpf-agent   3       3         0          true
```

When `READY` equals `DESIRED`, a node agent is running on every node.

## What the install creates

Everything is created in one namespace.

| Object                                  | Purpose                                               |
| --------------------------------------- | ----------------------------------------------------- |
| Namespace `authfi-system`               | Holds every object below                              |
| Deployment, the operator                | Keeps the node agents as the `AgentRuntime` describes |
| `AgentRuntime`, the one custom resource | What you want: the project, the mode, the features    |
| DaemonSet, the node agent               | One pod on every node                                 |
| Secret, the cluster's credential        | How the node agents authenticate to your project      |
| Secret, the session key                 | So a browser session works whichever node serves it   |

The cluster's credential belongs to this cluster alone. Secret values never leave the cluster.

The node agent runs privileged, on the host's network, because it loads programs into the node's kernel. Nothing is added to your own pods, and none of them is restarted.

## Change the install's settings

The `AgentRuntime` is the one object that describes the install. The Helm chart writes it for you.

```yaml
apiVersion: authfi.io/v1
kind: AgentRuntime
metadata:
  name: authfi-ebpf-agent
  namespace: authfi-system
spec:
  issuerUrl: https://acme.authfi.io
  credentialsSecret: authfi-ebpf-agent-credentials
  mode: observe
```

To change a setting, set it through Helm values. Do not edit the object.

| Field                                                           | Default   | Meaning                                                                  |
| --------------------------------------------------------------- | --------- | ------------------------------------------------------------------------ |
| `issuerUrl`                                                     |           | Your project's issuer                                                    |
| `credentialsSecret`                                             |           | The Secret holding this cluster's credential                             |
| `mode`                                                          | `observe` | `observe` is monitor mode. `enforce` lets the nodes deny.                |
| `enforcementInhibit`                                            | `false`   | [The brake](/zero-code/enforcement#the-brake), held by the cluster owner |
| `clusterName`                                                   |           | The name shown in the console                                            |
| `features.discovery`                                            | `true`    | List workloads and the routes they serve                                 |
| `features.ebpf`                                                 | `true`    | Sign-in and rules in front of services                                   |
| `features.pam`                                                  | `false`   | [Server access](/access/servers) on the nodes                            |
| `nodeSelector`, `tolerations`, `resources`, `priorityClassName` |           | As for any DaemonSet                                                     |

For what `mode` changes on the nodes, see [Monitor mode and enforce mode](/zero-code/enforcement#monitor-mode-and-enforce-mode).

## Upgrade Zero-Code

Run `helm upgrade` on the release you installed, with the new chart version.

Node agents are replaced one node at a time. Rules already in force stay in force while a node agent restarts.

## Remove Zero-Code

```bash
helm uninstall "$RELEASE"
```

`$RELEASE` is the release name in the command you ran to install.

Uninstalling hands every node back. On each node, before the release is gone:

1. Enforcement is switched off.
2. Every rule is cleared.
3. Every program is unloaded from the kernel.
4. Traffic redirection is removed.

The uninstall finishes only when every node has confirmed. If a node cannot be reached, the uninstall stops and names that node, so a node is never left enforcing rules nobody can change. For a node that is gone for good, set the annotation `authfi.io/skip-decommission: "true"` on the `AgentRuntime` to finish without it.

To hand back one service and keep the install, see [Hand a service back](/zero-code/protect-api#hand-a-service-back).

## Next steps

<Cards>
  <Card href="/zero-code/overview" title="How Zero-Code works">
    The three steps: Observe, Classify, Protect.
  </Card>
  <Card href="/zero-code/protect-ui" title="Protect a web app">
    Put sign-in in front of a service people open in a browser.
  </Card>
  <Card href="/zero-code/protect-api" title="Protect an API">
    Require an access token, and write a rule for each route.
  </Card>
  <Card href="/zero-code/enforcement" title="How enforcement works">
    What is decided on the node, and how monitor mode and enforce mode fit together.
  </Card>
</Cards>
