Skip to content

Latest commit

 

History

History
145 lines (107 loc) · 4.61 KB

README.opa.md

File metadata and controls

145 lines (107 loc) · 4.61 KB

Open Policy Engine Backend

Usage

To use this backend, specify "opa" as the policy.backend in the config:

import "github.com/veraison/services/config"

cfg := config.Config{
    "policy.backend": "opa",
}

agent, err := CreateAgent(cfg)

This is also the default backend, so if no other backend is specified, opa will be used.

Writing Policies

Please see the OPA official documentation for information on how to write Rego policies. This section describes what is necessary to implement a valid Veraison policy, and assumes a general familiarity with Rego.

Package declaration

Your policy should specify policy as the package.

package policy

Evaluation Data

Data to be evaluated is defined as the following variables in the policy package:

evidence contains the JSON representation of proto.EvidenceContext.Evidence structure. This is the scheme-specific values extracted from the attestation token.

endorsements is an array of endorsement JSON objects. Their structure is scheme-specific.

result is a JSON object representing proto.AttestationResult that was generated by the scheme.

scheme is the name of the attestation scheme.

Rules

You can update the attestation result by defining one or more of the following rules:

  • status
  • hw_authenticity
  • sw_integrity
  • sw_up_to_dateness
  • config_integrity
  • runtime_integrity
  • certification_status

The first overwrites the overall attestation result status. The subsequent rules overwrite the corresponding entries in the trust vector.

The rules must be defined such that they produce the string "SUCCESS" if the conditions have been met, and the string "FAILURE" otherwise.

As various versions are often represented using Semantic Versioning, policy package provides a utility function, semver_cmp to aid in their comparison (note: currently, pre-release suffixes are not supported).

For example:

sw_integrity = "SUCCESS" {
    # note: This is an example. The evidence entries do not correspond to any
    #       actual scheme.
    evidence["application-hash"] == "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc="
    evidence["firmware-hash"] == "h0KPxSKAPTEGXnvOPPA/5HUJZjHl4Hu9eg/eYMTPJcc="
    semver_cmp(evidence["firmware-version"], "1.2.0") >= 0
} else = "FAILURE"

Dealing With Multiple Attestation Schemes

If you expect your policy to be applied to inputs from multiple attestation schemes, you differentiate between them using the format variable defined by the policy package. For example you can define rules for each scheme, and then alias the generic rules above to one of them based on the value of the format variable. For example:

sw_up_to_dateness = psa_sw_up_to_dateness { format == "PSA_IOT" }
             else = enacttrust_sw_up_to_dateness { format == "TPM_ENACTTRUST" }

psa_sw_up_to_dateness = "SUCCESS" {
    # ...
} else = "FAILURE"

enacttrust_sw_up_to_dateness = "SUCCESS" {
    # ...
} else = "FAILURE"

Example Policy

This is a example of a policy that sets the SoftwareUpToDateness value in the trust vector for PSA_IOT and TPM_ENACTTRUST schemes (neither scheme has built-in definition for software up-to-dateness, and so that entry is undefined in the results generated by the schemes).

package policy

# Use the psa_sw_up_to_dateness rules iff the attestation format is PSA_IOT, and
# to enacttrust_sw_up_to_dateness iff the format is TPM_ENACTTRUST, otherwise,
# sw_up_to_dateness will remain undefined.
sw_up_to_dateness = psa_sw_up_to_dateness { format == "PSA_IOT" }
             else = enacttrust_sw_up_to_dateness { format == "TPM_ENACTTRUST" }

# This sets sw-up-to-dateness trust vector value to success iff BL version is
# 3.5 or greater, and to failure otherwise.
psa_sw_up_to_dateness = "SUCCESS" {
  # there exisists some i such that...
  some i
  # ...the i'th software component has type "BL", and...
  evidence["psa-software-components"][i]["measurement-type"] == "BL"

  # ...the version of this component is greater or equal to 3.5.
  # (semver_cmp is defined by the policy package. It returns 1 if the first
  # parameter is greater than the second, -1 if it is less than the second,
  # and 0 if they are equal.)
  semver_cmp(evidence["psa-software-components"][i].version, "3.5") >= 0
} else = "FAILURE" # unless the above condition is met, return "FAILURE"

# Unlike the PSA token, the EnactTrust token does not include information about
# multiple sofware componets and instead has a single "firmware" entry.
enacttrust_sw_up_to_dateness = "SUCCESS" {
  evidence["firmware"] >= 8
} else = "FAILURE"