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

[RVPS] RVPS Update Design #350

Open
4 tasks
Xynnn007 opened this issue Mar 13, 2024 · 7 comments
Open
4 tasks

[RVPS] RVPS Update Design #350

Xynnn007 opened this issue Mar 13, 2024 · 7 comments

Comments

@Xynnn007
Copy link
Member

Xynnn007 commented Mar 13, 2024

Currently, we have Reference Value Provider Service (RVPS) as a black box aiming to provide the following functionalities

  1. register_reference_value(manifest) Receive different format of reference value manifests, e.g. Sample format, in-toto (developing), CoRIM (TBD) and store the related reference values
  2. query_reference_value(claim_id) Provide a querying API for users e.g. attestation service to query reference value to a specific key

The reference value inside the RVPS are some key-value pairs. The key is a measurement claim name, such as mr_td for TDX and measurement for SNP.
The value is the reference values of that field.

@thomas-fossati has raised a core issue named compound reference value problem upon current design.

The concrete model is described here

Thus, a new concept name Target Environment (TE) is brought as defined in RATS.

A reference value can comprise one or more measurement claims, this means that only if the all claims
in the reference value and TE's measurements are matched altogether, the verification against the reference value
succeeds. A reference value applies to a given TE.

Reference values can be provided in "manifests" comprising one or more reference values.

The updated RVPS will update the API like the following

  1. register_reference_value(manifest) will not change.
  2. query_reference_value(claim_id) will be updated to query_reference_value(TE_id). This means a set of reference values will be indexed by
    an id of TE. The result reference values should be matched altogether.

Thus we need some related work along with the road.

  1. How to generate TE_id from a given reference value manifest.
  2. Some reference values ​​themselves have complex logic that goes beyond an exact match of a field.
    For example, a security version number field is greater than a specific number. We might also do some change to facilitate the current OPA integration in CoCoAS.

Roadmaps & Thoughts

  • A better way to help reference values and OPA policy inside AS work together. We might need an intermediate strategy language for users to facilitate configuring attestation policy.
  • Support CoRIM format as one of the reference value manifest in RVPS.
  • Publish CoCo's TDX stack reference value in CoRIM and finish e2e test.
  • Publish CoCo's Arm stack reference value in CoRIM and finish e2e test.
@fitzthum
Copy link
Member

It seems like one of the main concrete suggestions here is to update the RVPS to allow reference values to be grouped in terms of the so-called Target Environment. This seems like a good idea, but I"m still a bit fuzzy on how the RVPS should be used in practice.

Some pieces that I don't quite understand yet include what a policy that uses reference values should actually look like, how the the manifest should actually be generated, etc.

@Xynnn007
Copy link
Member Author

Xynnn007 commented Mar 20, 2024

It seems like one of the main concrete suggestions here is to update the RVPS to allow reference values to be grouped in terms of the so-called Target Environment. This seems like a good idea, but I"m still a bit fuzzy on how the RVPS should be used in practice.

Some pieces that I don't quite understand yet include what a policy that uses reference values should actually look like, how the the manifest should actually be generated, etc.

About the manifest

  • Generation: Manifests should be published together with the binaries building process. For CoCo, I'd like to help to put some abilities upon kata's payload building process to generate CoRIMs of the payloads and put them together with original payload files. Or, put the CoRIMs on the confidential-containers.org for users to download. This might be a start.
  • Consumption: RVPS works similiar with AS' policy, truely. However the core idea of RVPS is the reference value manifests parsed are in different formats and probably endorsed by configured trust anchor. With this proposal, a bunch of reference values could be grouped so that a concrete combination software running environment could be described. Currently the default OPA policy inside AS is somehow coupled with reference values got from RVPS and hard to configure. Having some discussions with @jialez0 , we both think that having an intermediate simple language (could be just JSON with specific keys) to configure the policy would make it easier. A draft might include some basic rules (semantically, no need to be a new DSL), e.g. ev.A == B, ev applies TE_id[B], ev.A in B, env.A > B. This would seems more direct and easy for users to config and would integrate RVPS functions into AS in a more natural way.

I am not sure if it makes sense overall.

@mkulke
Copy link
Contributor

mkulke commented Mar 20, 2024

At the moment, in rego policies, we are able to express a group of values and perform policy assertions on them (==, >=, ...).

Now the problem, if I understood correctly: (groups of) reference values are managed by a different persona than the persona who manages the policy and they shouldn't be coupled.

questions:

  • Is my undestanding correct, that this would mean we change the reference atom from value to a manifest, which is a set of reference values (ref_value[] => [{id, rev_value[]}), so you can only match again manifests?
  • what are the semantics of TE_id ? is this just the id of a manifest?
  • would we iterate through all sets until we find a match?
  • What would we gain by replacing rego with a homegrown rule engine? if we don't want to conflate values and policy assertions, we could just associate a rego policy with a certain TE_id?

@Xynnn007
Copy link
Member Author

Xynnn007 commented Mar 20, 2024

  • Is my undestanding correct, that this would mean we change the reference atom from value to a manifest, which is a set of reference values (ref_value[] => [{id, rev_value[]}), so you can only match again manifests?

Partially yes. Sorry for my overlook for the starting of this question. One idea is what you said reference values are managed by a different persona than the persona who manages the policy and they shouldn't be coupled. The other is that we should support both manifest and simple claims without manifest. Manifests are for defined rvs (mostly from trusted entity, s.t. personas of reference value providers). Single claims are for flexibility of user (who cares where they come). That is why I exampled both ev.A == B and ev.A applies TE[B], they mean simple claim and manifests (hints that TE[B] would be retrieved from RVPS).

  • what are the semantics of TE_id ? is this just the id of a manifest?

Yes

  • would we iterate through all sets until we find a match?

This is a good question. There are two parts

  1. How to write rules. If we use set operands like in, we should explicitly list the members.
  2. How to apply the rules inside the program. We can use (Hash/BTree)Set to improve the performance. Also, we could leverage OPA to work as the underlying
  • What would we gain by replacing rego with a homegrown rule engine?

Convenience for user experience. Even for me now it is hard to write an expected policy.

if we don't want to conflate values and policy assertions, we could just associate a rego policy with a certain TE_id?

Abstractly speaking, a TE contains both logic (code, how to match. not only simply equal) and value (data, s.t. reference values) due to some CoRIM profiles. And allow some scenarios where a user want to apply TE[A] and some self-defined claims values (equal judgement). I am not sure I understand associating a rego policy with a certain TE_id here. Does it mean we can embed a TE_id inside a rego? If so, we need extra parser to parse the rego and do lexical analysis to determine which tokens represent TE_id. This would make it complexer than we have a simple language (not really, we can even use something like the following. Hopefully this is easy to understand)

// This is a policy
{
  "TE": ["TE_1", "TE_2"],  // This evidence must apply to these TEs
  "claims": {
    "tdx.quote.header.version": {"equal": 4},   // equal operand
    "tdx.quote.body.tcb_svn": {"greater-than": 12},  // comparation operand
    "tdx.quote.body.xfam": {"in": ["0x0", "0xff"]}, // set operand
  }
}

However, I admit these are just my current thoughts and could be corrected.

@fitzthum
Copy link
Member

Maybe we should try to come up with examples of exactly what the end-to-end flow would look like. Ultimately the goal is that users should be able to provision the AS with reference values and some sort of policy as easily as possible.

I am wary of creating a new convention for expressing the policy, but I do think the current OPA implementation doesn't quite make sense. Most of the time, the policy will be the same. It's really the selection of reference values that are most significant. In the current implementation we have tons of flexibility and expressiveness for specifying the policy, but almost none for specifying the reference values.

One thing that might help the situation would be if we provided a better default policy. We already have one that attempts to compare the claims map to the reference values, but this doesn't allow for some of the more complex comparisons that @Xynnn007 mentions (i.e. a > b). We could try to come up with a more detailed policy that defines these requirements for all the different platforms. Obviously this wouldn't work for every possible situation, but it might help some users not need to write a policy at all.

On a semi-related note, we currently return the reference values from the AS as part of the AS Token. Is this a good idea? It makes the token a lot larger. If the token is issued, then presumably the claims maps is valid. I'm not really sure what we envisioned people doing with this info and maybe there is a chance that it could leak something.

@Xynnn007
Copy link
Member Author

Xynnn007 commented Mar 22, 2024

@fitzthum

Maybe we should try to come up with examples of exactly what the end-to-end flow would look like. Ultimately the goal is that users should be able to provision the AS with reference values and some sort of policy as easily as possible.

Totally agree. The limit we are facing now is that we do not have enough reference values that can be selected to configure a policy. I believe after we realize the artifact publishment together with CoCo-signed reference values, the situation will be better and we can provide a guide for users to quick start with standard CoCo components.

I am wary of creating a new convention for expressing the policy, but I do think the current OPA implementation doesn't quite make sense. Most of the time, the policy will be the same. It's really the selection of reference values that are most significant. In the current implementation we have tons of flexibility and expressiveness for specifying the policy, but almost none for specifying the reference values.

Yes. The default policy now actually provide only one ability: if any reference data is provided, compare that with the one in parsed claims. Except for that, nothing else is defined. So this seems tightly coupled with reference values from RVPS.

By default, no reference value will be set inside RVPS. So the default setting is -- do nothing : |

In some cases, users might not want to configure or use RVPS but prefer to configure some reference values into policy manually. So based on such an observation, I gradually realize that an intermediate expressing might help. Just like container-image-policy we are using, they are straightforward and could be extended by adding new rule types any time.

Some basic rule type will not involve query well-defined reference value manifest inside RVPS, but just do logiccal/set/numerical operations and their nested operations.

But, let's see.

On a semi-related note, we currently return the reference values from the AS as part of the AS Token. Is this a good idea? It makes the token a lot larger. If the token is issued, then presumably the claims maps is valid. I'm not really sure what we envisioned people doing with this info and maybe there is a chance that it could leak something.

Nice point. Current implementation like this ensures the token itself could ensure the integrity of reference values used to verify -- as mentioned the default policy just tell to use reference values got from RVPS to compare, but not tell what reference values are.

If we have

  • A well defined policy format
  • An global unique id to look up reference value manifests

We can get rid of the current reference values fields from the token. As the hash of the policy could ensure the integrity of the policy, and the policy contains the manual reference values, logic and reference value manifest ids.

@bpradipt
Copy link
Member

bpradipt commented Apr 3, 2024

A better way to help reference values and OPA policy inside AS work together. We might need an intermediate strategy language for users to facilitate configuring attestation policy.

I think to start with it's better to provide OPA policy examples, including a sane default policy that works for common use cases.
Then once the rest of the code stabilises, we have successful CI runs and feedback from end users, we should embark on providing an intermediate language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants