This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Policies

Controlling the KBS with policies

Trustee allows users to create policies that govern when secrets are released. Trustee has two different policies, the resource policies, and the attestation policy, which serve distinct purposes.

Resource policies control which secrets are released and are generally scoped to the workload. Attestation policies define how TCB claims are compared to reference values to determine if the enclave is in a valid state. Generally this policy reflects the enclave boot flow. Both policies use OPA.

Provisioning Policies

Both types of policies can be provisioned with the KBS Client.

kbs-client --url <kbs-url> config \
    --auth-private-key <admin-private-key> set-resource-policy \
    --policy-file <path-to-policy-file>

The attestation policy is set in a similar manner.

kbs-client --url <kbs-url> config \
    --auth-private-key <admin-private-key> set-attestation-policy \
    --policy-file <path-to-policy-file>

Resource Policies

Resource policies, also known as KBS Policies, control whether a resource is released to a guest. The input to the resource policies is the URI of the resource that is being requested and the attestation token which was generated by attestation service for the guest making the request.

Basic Policies

The simplest possible policies either allow or reject all requests.

package policy

default allow = true

Allowing all requests is generally not secure. By default the resource policy allows all requests as long as the evidence does not come from the sample attester. This means that some TEE must have been used to request the secret although it makes no guarantees about the TCB. If you are testing Trustee without a TEE (with the sample evidence) the default policy will block all of your requests.

Usually the policy should check if the attestation token represents a valid TCB. The attestation token is an EAR token, so we can check if it is contraindicated. The status field in the EAR token represents an AR4SI Trustworthiness Tier. There are 4 tiers: Contraindicated, Warning, Affirming, and None. Ideally secrets should only be released when the token affirms the guest TCB.

package policy
import rego.v1

default allow = false

allow if {
    input["submods"]["cpu"]["ear.status"] != "contraindicated"
}

Usually the attestation service must be provisioned with reference values to return attestation tokens that are not contraindicated. This is described in upcoming sections.

A more advanced policy could check that the token is not contraindicated and that the enclave is of a certain type. For example, this policy will only allow requests if the evidence is not contraindicated and comes from an SNP guest.

package policy
import rego.v1

default allow = false

allow if {
    input["submods"]["cpu"]["ear.status"] != "contraindicated"
    input["submods"]["cpu"]["ear.veraison.annotated-evidence"]["snp"]
}

Advanced Policies

The EAR attestation token offers a generic but specific description of the guest TCB status. In addition to whether or not a module (such as the CPU) is contraindicated, an EAR appraisal can address eight different facets of the TCB.

These are instance_identity, configuration, executables, file_system, hardware, runtime_opaque, storage_opaque, sourced_data.

Not all of these vectors is in scope for confidential containers. See the next section for how these vectors are calculated.

A resource policy can check each of these values. For instance this policy builds on the previous one to make sure that in addition to not being contraindicated, the executables trust vector has a particular claim.

package policy
import rego.v1

default allow = false

allow if {
    input["submods"]["cpu"]["ear.status"] != "contraindicated"
    input["submods"]["cpu"]["ear.veraison.annotated-evidence"]["snp"]
    input["submods"]["cpu"]["ear.status.executables"] == 2
}

In AR4SI and EAR, numerical trust claims are assigned specific meanings. For instance, for the executables trust claim the value 2 stands for “Only a recognized genuine set of approved executables have been loaded during the boot process.” A full listing of trust vectors and their meanings can be found here.

The policy also takes the requested resource URI as input so the policy can have different behavior depending on which resource is requested.

Here is a basic policy checking which resource is requested.

package policy
import rego.v1

default allowed = false

path := split(data["resource-path"], "/")

allowed if {
    path[0] == "red"
}

This policy only allows requests to certain repositories. This technique can be combined with those above. For instance, you could write a policy that allows different resources on different platforms, or requires different trust claims for different secrets.

package policy
import rego.v1

default allowed = false

path := split(data["resource-path"], "/")

allowed if {
    path[0] == "red"
    input["submods"]["cpu"]["ear.status"] != "contraindicated"
    input["submods"]["cpu"]["ear.veraison.annotated-evidence"]["snp"]
}

allowed if {
    path[0] == "blue"
    input["submods"]["cpu"]["ear.status"] != "contraindicated"
    input["submods"]["cpu"]["ear.veraison.annotated-evidence"]["tdx"]
}

Finally, policies can access guest init-data if it has been specified. Init-data is a measured field set by the host on boot. Init-data allows dynamic, measured configurations to be propagated to a guest. Those configurations can also be provided to Trustee as part of the KBS protocol. If they are, policies can check the init-data, which is located at submods.cpu.ear.veraison.annotated-evidence.init_data_claims. This is only supported on platforms that have a hardware init-data field (such as HostData on SEV-SNP or mrconfigid/mrowner/mrownerconfig on TDX).

Accessing init-data from policies can be extremely powerful because users can specify whatever they want to in the init-data. This allows users to create their own schemes for identifying guests. For instance, the init-data could be used to assign each guest a UUID or a workload class.

Attestation Policies

Attestation policies are what the attestation service uses to calculate EAR trust vectors based on the TCB claims extracted from the hardware evidence by the verifiers. Essentially the AS policy defines which parts of the evidence are important and how the evidence should be compared to reference values.

The default attestation policy already defines this relationship for TDX and SNP guests booted by the Kata shim and running Kata guests. If you are using Confidential Containers with these platforms you probably do not need to change this policy. If you are using Trustee to boot different types of guests, you might want to adjust the AS policy to capture your TCB.

Either way, you’ll need to provide the reference values that the policy expects. Take a look at the default policy to see which values are expected. You only need to provision the reference values for the platform that you are using.