veraison / evcli

CLI for handling attestation evidence
Apache License 2.0
2 stars 1 forks source link

An "agent" mode for evcli #30

Open thomas-fossati opened 2 weeks ago

thomas-fossati commented 2 weeks ago

The idea of standardising an "agent" interface that attesters can expose to their challengers has popped up in several discussion threads.

The problem has two orthogonal dimensions:

  1. Defining a suitable interface - meaning one that starts as simple as possible but that can evolve to accommodate different use cases and attester technologies;
  2. Allowing different authz/authn mechanisms to authorise the requester.

MVP

I suggest we start experimenting with an MVP that only tackles the functional part (1), and consists of a synchronous REST API with a single endpoint /chares[^1] as follows:

POST /chares HTTP/1.1
Host: attester.example
Content-Type: application/vnd.veraison.chares-params-v1+json
Accept: application/cmw+json, application/cmw+cbor

{
  "challenge": "base64encode"
}
HTTP/1.1 200 OK
Content-Type: application/cmw+json

{
  "type": "...",
  "value": "base64encode"
}

Note that using CMW to wrap evidence provides native support for composite devices using collections.

AuthN/AuthZ

There are several ways to tackle the authz/authn problem, e.g.: using HTTP authentication framework, OAuth2, mTLS, an API implementation must provide at least one method.

[^1]: Any similarity to actual persons, living or dead, is purely coincidental.

iolivergithub commented 2 weeks ago

I second this and have a prototype (relaying party/verifier).

deeglaze commented 2 weeks ago

Note that confidential containers has an API defined already and has gRPC and ttRPC implementations of the service for localhost connections: https://github.com/confidential-containers/guest-components/blob/main/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs

Each attester can return its own blob of bytes for a return format.

I think the endpoint, request inputs and response outputs should be defined in such a way that adapters are easy enough to wrap your own auth{z,n} solution around the service.

If we have a different, say, "IETF attester" backend to propose, I'd suggest we do it in confidential-containers and then depend on it here if the veraison project uses it directly.

Edit: Intel has an API in mind as well for possible RPCs to make ubiquitous https://github.com/cc-api/cc-trusted-api?tab=readme-ov-file#3-apis

thomas-fossati commented 2 weeks ago

Note that confidential containers has an API defined already and has gRPC and ttRPC implementations of the service for localhost connections: https://github.com/confidential-containers/guest-components/blob/main/attestation-agent/attestation-agent/src/bin/grpc-aa/server.rs

Thanks! Coincidentally, I bumped into this just a few hours ago while working on the CCA integration. I like gRPC (I use it all the time for intra-service comms) but it has a slightly less "universal" flavour than ReST. And while it has pretty decent support for authentication, it's unclear whether the OAuth2 option is only available via Google services. Do you have any insight to share? Another reason for prefering ReST is that it maps naturally to CoAP and therefore IoT.

I think the endpoint, request inputs and response outputs should be defined in such a way that adapters are easy enough to wrap your own auth{z,n} solution around the service.

Do you mean that the functional definition cannot be disentangled from the authorisation aspects?

If we have a different, say, "IETF attester" backend to propose, I'd suggest we do it in confidential-containers and then depend on it here if the veraison project uses it directly.

My goal here is to have a minimalist design and do some practical experimentation with running code. It's not my intention to propose any IETF protocol. Once/if we are satisfied with it we can go to CoCo and other places (CCC attestation SIG) and share it.

Edit: Intel has an API in mind as well for possible RPCs to make ubiquitous https://github.com/cc-api/cc-trusted-api?tab=readme-ov-file#3-apis

Nice, thanks. From a quick skim I couldn't get if it allows remote calls or just local ones.

deeglaze commented 2 weeks ago

I wouldn't say that gRPC has to be used. gRPC actually integrates with REST with protobuf options

rpc Echo(EchoMessage) returns (EchoMessage) {
    option (google.api.http) = {
      post: "/v1/echo"
      body: "*"
    };
  }

My goal here is to have a minimalist design and do some practical experimentation with running code. It's not my intention to propose any IETF protocol. Once/if we are satisfied with it we can go to CoCo and other places (CCC attestation SIG) and share it.

Okay. I think we ought to separate the duties here there. The confidential-containers agent is a local service to allow containers to interact with attestation.

Your agent is to allow remote actors to challenge an attester outside the context of an application that would interact with attestation the way it wants to expose.

What is the use case that you're trying to enable? Allowing the verifier to challenge attesters without needing to be contacted by the attester? To what end?

gRPC's authentication that uses ALTS is Google-specific, but the OAuth2 isn't. You "just" have to have your own OAuth2 setup in order to request service tokens from, e.g., AWS and Azure. Authorization through oauth2 allows authorization business logic to be delegated outside the attestation agent, but not everyone will have IAM servers, and may just want static trust stores for mTLS, say.

A proof of concept could say that you need a bearer token in an https header that passes a predicate (e.g., lambda x: x == 'foo'). A better PoC could say you need to have the mTLS connection terminated by a key certified by your locally configured trust store. Beyond that, you have identity and access management system integration problems: configuration and requests to different services like AWS OAuth2.0 identity pools, GCP identity pools, Oracle Cloud identity domains, Azure Entra ID, Active Directory... Kerberos? I'm not sure what all needs to be managed by the agent.

Nice, thanks. From a quick skim I couldn't get if it allows remote calls or just local ones.

The cc-trusted-api is meant to be a library for evidence collection, so wire serialization and a service layer are an exercise for the reader. Still the API in terms of what questions can be asked seems reasonable.

thomas-fossati commented 2 weeks ago

I wouldn't say that gRPC has to be used. gRPC actually integrates with REST with protobuf options

rpc Echo(EchoMessage) returns (EchoMessage) {
    option (google.api.http) = {
      post: "/v1/echo"
      body: "*"
    };
  }

That's great. If making a gRPC version is not only possible but (apparently) painless, all the better.

[...] I think we ought to separate the duties here there. The confidential-containers agent is a local service to allow containers to interact with attestation.

Your agent is to allow remote actors to challenge an attester outside the context of an application that would interact with attestation the way it wants to expose.

Yes, exactly.

What is the use case that you're trying to enable? Allowing the verifier to challenge attesters without needing to be contacted by the attester? To what end?

It's a pretty common pattern, especially in TPM-based RA flows.

gRPC's authentication that uses ALTS is Google-specific, but the OAuth2 isn't. You "just" have to have your own OAuth2 setup in order to request service tokens from, e.g., AWS and Azure. Authorization through oauth2 allows authorization business logic to be delegated outside the attestation agent, but not everyone will have IAM servers, and may just want static trust stores for mTLS, say.

Awesome; I got confused by the documentation I read: it seemed to suggest Google was an unavoidable 3rd party in the OAuth2 flow. But, yes, authorisation decisions must be made as flexible as possible, and as orthogonal as possible to the functional aspects of the interaction.

A proof of concept could say that you need a bearer token in an https header that passes a predicate (e.g., lambda x: x == 'foo'). A better PoC could say you need to have the mTLS connection terminated by a key certified by your locally configured trust store. Beyond that, you have identity and access management system integration problems: configuration and requests to different services like AWS OAuth2.0 identity pools, GCP identity pools, Oracle Cloud identity domains, Azure Entra ID, Active Directory... Kerberos? I'm not sure what all needs to be managed by the agent.

Some of that could be delegated - modulo the usual TCB considerations.

Nice, thanks. From a quick skim I couldn't get if it allows remote calls or just local ones.

The cc-trusted-api is meant to be a library for evidence collection, so wire serialization and a service layer are an exercise for the reader. Still the API in terms of what questions can be asked seems reasonable.

Yes, it looks like a reasonable starting point. Not all of that surface needs to be made visible to a remote peer. We could start from there and carefully consider what should be included in an external view of the API.

iolivergithub commented 2 weeks ago

Following up to Thomas' comments - yes, this is the use case we are looking at; utilising a remote attestation environment to query evcli in the same way as we (and others) query the TPM remotely (cf: Keylime etc). All that we require is a suitable endpoint (protocol, formats etc do not matter - these can be handled later if necessary) and a list of functions+parameters. In this case from discussions with Thomas, this is a single function and a nonce as.a parameter?

thomas-fossati commented 2 weeks ago

[...] this is a single function and a nonce as a parameter?

yes, this would be my starting point.

The media type "application/vnd.veraison.chares-params-v1+json" describes a JSON object with a single "challenge" key:

{
  "challenge": "base64encode"
}

A future -v2 (that can be content-negotiated) could include other things (e.g., PRCs that one may want to quote, etc.)

thomas-fossati commented 1 week ago

This and the CC-API proposal look like complementary work: one rich & platform-facing, the other exposing only the "safe" surface of the former to a remote and trusted verifier or relying party.

We should keep a close eye on it and make sure they are kept in sync.

cc: @kenplusplus @wenhuizhang

iolivergithub commented 1 week ago

This and the CC-API proposal look like complementary work: one rich & platform-facing, the other exposing only the "safe" surface of the former to a remote and trusted verifier or relying party.

We should keep a close eye on it and make sure they are kept in sync.

Should be able to code against those and support it in Jane trivially as well

To me I don't think it is a problem to have multiple APIs, but to ensure that the structures returned can be cross-checked against each other at some point.

wenhuizhang commented 1 week ago

This and the CC-API proposal look like complementary work: one rich & platform-facing, the other exposing only the "safe" surface of the former to a remote and trusted verifier or relying party.

We should keep a close eye on it and make sure they are kept in sync.

cc: @kenplusplus @wenhuizhang

Good point , we will keep an eye on this, and see how could we collaborate :)