Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools: add policy generation tool #8248

Merged
merged 11 commits into from
Jan 11, 2024
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).