Skip to content

Commit

Permalink
docs: add agent policy and genpolicy docs
Browse files Browse the repository at this point in the history
Add docs for the Agent Policy and for the genpolicy tool.

Signed-off-by: Dan Mihai <dmihai@microsoft.com>
  • Loading branch information
danmihai1 committed Dec 6, 2023
1 parent 4b438c3 commit 4e2fce2
Show file tree
Hide file tree
Showing 6 changed files with 822 additions and 12 deletions.
4 changes: 4 additions & 0 deletions docs/how-to/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
Refer to the following guides for additional configuration steps:
- [Kata Containers with ACRN Hypervisor](how-to-use-kata-containers-with-acrn.md)

## Confidential Containers Policy

- [How to auto-generate policy](../../src/tools/genpolicy/README.md)

## Advanced Topics

- [How to use Kata Containers with virtio-fs](how-to-use-virtio-fs-with-kata.md)
Expand Down
129 changes: 128 additions & 1 deletion docs/how-to/how-to-use-the-kata-agent-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ When compiled with default settings, the Kata Containers code doesn't include th

1. The Kata Agent gets built using `AGENT_POLICY=yes`, and therefore includes Policy support. If the `AGENT_INIT=yes` build parameter was specified in addition to `AGENT_POLICY=yes`, the Kata Agent will start `OPA` during the Kata Containers sandbox creation.

# Policy format

The Policy document is a text file using the [`Rego` policy language](https://www.openpolicyagent.org/docs/latest/policy-language/). See [Creating the Policy document](#creating-the-policy-document) for information related to creating Policy files.

# Providing the Policy to the Kata Agent

There are two methods for providing the Policy document to the Kata Agent:
Expand Down Expand Up @@ -66,4 +70,127 @@ While creating the Pod sandbox, the Kata Shim will notice the `io.katacontainers

# How is the Policy being enforced?

The Kata Agent is responsible for enforcing the Policy, working together with `OPA`. The Agent checks the Policy for each [ttRPC API](../../src/libs/protocols/protos/agent.proto) request. Before carrying out the actions corresponding to the request, the Agent uses the [`OPA REST API`](https://www.openpolicyagent.org/docs/latest/rest-api/) to check if the Policy allows or blocks the call. The Agent rejects requests that are not allowed by the Policy.
The Kata Agent is responsible for enforcing the Policy, working together with [`OPA`](https://www.openpolicyagent.org/). The Agent checks the Policy for each [ttRPC API](../../src/libs/protocols/protos/agent.proto) request. Before carrying out the actions corresponding to the request, the Agent uses the [`OPA REST API`](https://www.openpolicyagent.org/docs/latest/rest-api/) to check if the Policy allows or blocks the request. The Agent rejects requests that are not allowed by the Policy.

# Creating the Policy document

## Creating the Policy document manually

For relatively simple uses cases, users can write the Policy text using the [`Rego` policy language documentation](https://www.openpolicyagent.org/docs/latest/policy-language/) as reference.

See [Policy contents](#policy-contents) for additional information.

## Using auto-generated Policy

The [`genpolicy`](../../src/tools/genpolicy/) application can be used to generate automatically a Policy matching an input Kubernetes `YAML` file. The Policy generated by this application is typically used for implementing confidential containers, where the Kata Shim and the Kata Agent have different trust properties.

**Warning** Users should review carefully the automatically-generated Policy, and modify the Policy file if needed to match better their use case, before using this Policy.

See the [`genpolicy` documentation](../../src/tools/genpolicy/README.md) and the [Policy contents examples](#policy-contents) for additional information.

## Policy contents

### The [`Rego`](https://www.openpolicyagent.org/docs/latest/policy-language/) package name

The name of the Kata Agent Policy package must be `agent_policy`. Therefore, all Agent Policy documents must start with:

```
package agent_policy
```
### Default values

When the Kata Shim sends a [ttRPC API](../../src/libs/protocols/protos/agent.proto) request to the Kata Agent, the [Policy rules](#rules) corresponding to that request type are evaluated. For example, when the Agent receives a `CopyFile` request, any rules defined in the Policy that are using the name `CopyFileRequest` are evaluated. [`OPA`](https://www.openpolicyagent.org/) evaluates these rules and tries to find at least one `CopyFileRequest` rule that returns value `true`:

1. If at least one `CopyFileRequest` rule returns `true`, `OPA` returns a `true` result to the Kata Agent, and the Agent carries out the file copy requested by the Shim.

1. If all the `CopyFileRequest` rules return `false`:
- If the Policy includes a default value for `CopyFileRequest`, `OPA` returns that value to the Agent.
- If the Policy doesn't include a default value for `CopyFileRequest`, `OPA` returns an empty response to the Agent. The Agent treats the empty response the same way as a `false` response, so it rejects the `CopyFile` request.

**Tip:** Although the Kata Agent treats empty responses from `OPA` similarly to `false` responses, it is recommended to always provide default values. With default values, the Policy document and the logs from `OPA` and Kata Agent are easier to understand.

Examples of default values:

```
default WaitProcessRequest := true
default ExecProcessRequest := false
```

### Policy data

Policy data is optional. It typically contains values that are compared by the [Policy rules](#rules) with the input parameters of a [ttRPC API](../../src/libs/protocols/protos/agent.proto) request. Based on this comparison, a rule can either allow or deny the request, by returning `true` or `false`.

Example of Policy data:

```
policy_data := {
"common": {
"cpath": "/run/kata-containers/shared/containers"
},
"request_defaults": {
"CopyFileRequest": [
"^$(cpath)/"
],
"ExecProcessRequest": {
"commands": [
"/bin/foo"
],
"regex": []
}
}
}
```

### Rules

Policy rules are optional. They typically compare the input parameters of a [ttRPC API](../../src/libs/protocols/protos/agent.proto) request with values from the [policy data](#policy-data). Based on this comparison, a rule can either allow or deny the request, by returning `true` or `false`.

Multiple rules having the same name can be defined in the same Policy. As described [above](#default-values), when the Kata Agent queries [`OPA`](https://www.openpolicyagent.org/) by using the [`OPA REST API`](https://www.openpolicyagent.org/docs/latest/rest-api/), `OPA` tries to find at least one rule having the same name as the request that returns `true` given the API input parameters defined by the [ttRPC API](../../src/libs/protocols/protos/agent.proto).

Examples of rules, corresponding to the Kata Agent `CopyFile` and `ExecProcess` requests:

```
import future.keywords.in
import input
CopyFileRequest {
print("CopyFileRequest: input.path =", input.path)
some regex1 in policy_data.request_defaults.CopyFileRequest
regex2 := replace(regex1, "$(cpath)", policy_data.common.cpath)
regex.match(regex2, input.path)
print("CopyFileRequest: true")
}
ExecProcessRequest {
print("ExecProcessRequest 1: input =", input)
i_command = concat(" ", input.process.Args)
print("ExecProcessRequest 1: i_command =", i_command)
some p_command in policy_data.request_defaults.ExecProcessRequest.commands
p_command == i_command
print("ExecProcessRequest 1: true")
}
ExecProcessRequest {
print("ExecProcessRequest 2: input =", input)
i_command = concat(" ", input.process.Args)
print("ExecProcessRequest 2: i_command =", i_command)
some p_regex in policy_data.request_defaults.ExecProcessRequest.regex
print("ExecProcessRequest 2: p_regex =", p_regex)
regex.match(p_regex, i_command)
print("ExecProcessRequest 2: true")
}
```

The `input` data from these examples is provided to `OPA` by the Kata Agent, as a ``JSON`` format representation of the API request parameters.

For additional examples of Policy rules, see [`rules.rego`](../../src/tools/genpolicy/rules.rego).
2 changes: 1 addition & 1 deletion src/tools/genpolicy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "genpolicy"
version = "0.1.0"
authors = ["The Confidential Containers community https://github.com/confidential-containers"]
authors = ["The Kata Containers community <kata-dev@lists.katacontainers.io>"]
edition = "2021"

[dependencies]
Expand Down
63 changes: 53 additions & 10 deletions src/tools/genpolicy/README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,72 @@
# Agent Policy generation tool

The Kata Containers policy generation tool (`genpolicy`):
The Kata Containers Policy generation tool (`genpolicy`):

1. Reads user's Kubernetes YAML file.
1. Reads user's Kubernetes (`K8s`) `YAML` file.

1. Infers user's intentions based on the contents of that file.

1. Generates a Kata Containers Agent (`kata-agent`) policy file
corresponding to the input YAML, using the Rego/Open Policy Agent
format.
1. Generates a Kata Containers Agent (`kata-agent`) Policy file corresponding to the input `YAML`, using the [Open Policy Agent format](https://www.openpolicyagent.org/docs/latest/policy-language/).

1. Appends the policy as an annotation to user's YAML file.
1. Encodes the auto-generated Policy text in base64 format and appends the encoded string as an annotation to user's `YAML` file.

When the user deploys that YAML file, the Kata Agent uses the attached
policy to reject possible Agent API calls that are not consistent with
the policy.
When the user deploys that `YAML` file through `K8s`, the Kata Agent uses the Policy specified by the `YAML` annotation to reject possible Agent API calls that are not consistent with the policy. For additional information, see [How to use the Kata Agent Policy](../../../docs/how-to/how-to-use-the-kata-agent-policy.md).

The Policy auto-generated by `genpolicy` is typically used for implementing confidential containers, where the Kata Shim and the Kata Agent have different trust properties.

**Warning** Users should review carefully the automatically-generated Policy, and modify the Policy file if needed to match better their use case, before using this Policy.

# Building `genpolicy` from source code

## Install build dependencies

Example for Ubuntu 22.04.3:

```bash
$ sudo apt-get update
$ sudo apt-get install -y build-essential cmake curl git musl-dev musl-tools
$ curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh
$ source "$HOME/.cargo/env"
$ arch=$(uname -m)
$ rustup target add "${arch}-unknown-linux-musl"
```

# Build `genpolicy`

```bash
$ git clone https://github.com/kata-containers/kata-containers.git
$ cd kata-containers/src/tools/genpolicy
$ source "$HOME/.cargo/env"
$ make && make install
```

If you want to use `LIBC=gnu` instead of the default `LIBC=musl`, change the last step above to:

```bash
$ LIBC=gnu make && LIBC=gnu make install
```

# Executing `genpolicy`

Example:

```sh
$ genpolicy -y samples/pod-one-container.yaml
$ genpolicy -y test.yaml
```

For a usage statement, run:

```sh
$ genpolicy --help
```

For advanced command line parameters, see [`genpolicy` advanced command line parameters](genpolicy-advanced-command-line-parameters.md).


# Supported Kubernetes `YAML` file types

`genpolicy` has support for automatic Policy generation based on Kubernetes `DaemonSet`, `Deployment`, `Job`, `Pod`, `ReplicaSet`, `ReplicationController`, and `StatefulSet` input `YAML` files.

# Policy details

See [auto-generated Policy details](genpolicy-auto-generated-policy-details.md).

0 comments on commit 4e2fce2

Please sign in to comment.