Skip to content

Commit

Permalink
AS: fix build with rvps features
Browse files Browse the repository at this point in the history
Before this commit when we only enable `restful-bin,rvps-grpc` features,
the attestation service cannot be built.

This patch fixes this issue. Also, this commit deletes the `rvps-builtin`
feature as the code of rvps does not bring in any new dependencies.

Related configurations are updated to make it more robust, together with
the documents.

Signed-off-by: Xynnn007 <[email protected]>
  • Loading branch information
Xynnn007 committed Nov 22, 2024
1 parent 842fa4f commit 423e208
Show file tree
Hide file tree
Showing 26 changed files with 339 additions and 183 deletions.
19 changes: 8 additions & 11 deletions attestation-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"

[features]
default = ["restful-bin", "rvps-grpc", "rvps-builtin"]
default = [ "restful-bin", "rvps-grpc" ]
all-verifier = [ "verifier/all-verifier" ]
tdx-verifier = [ "verifier/tdx-verifier" ]
sgx-verifier = [ "verifier/sgx-verifier" ]
Expand All @@ -15,24 +15,21 @@ csv-verifier = [ "verifier/csv-verifier" ]
cca-verifier = [ "verifier/cca-verifier" ]
se-verifier = [ "verifier/se-verifier" ]

# Only for testing and CI
rvps-builtin = [ "reference-value-provider-service" ]

rvps-grpc = [ "prost", "tonic" ]
rvps-grpc = ["prost", "tonic"]

# For building gRPC CoCo-AS binary
grpc-bin = [ "clap", "env_logger", "prost", "tonic" ]
grpc-bin = ["clap", "env_logger", "prost", "tonic"]

# For restful CoCo-AS binary
restful-bin = [ "actix-web/openssl", "clap", "env_logger", "thiserror" ]
restful-bin = ["actix-web/openssl", "clap", "env_logger"]

[[bin]]
name = "grpc-as"
required-features = [ "grpc-bin" ]
required-features = ["grpc-bin"]

[[bin]]
name = "restful-as"
required-features = [ "restful-bin" ]
required-features = ["restful-bin"]

[dependencies]
actix-web = { workspace = true, optional = true }
Expand All @@ -50,7 +47,7 @@ log.workspace = true
openssl = "0.10.55"
prost = { workspace = true, optional = true }
rand = "0.8.5"
reference-value-provider-service = { path = "../rvps", optional = true }
reference-value-provider-service.path = "../rvps"
regorus.workspace = true
rsa = { version = "0.9.2", features = ["sha2"] }
serde.workspace = true
Expand All @@ -60,7 +57,7 @@ sha2.workspace = true
shadow-rs.workspace = true
strum.workspace = true
time = { version = "0.3.23", features = ["std"] }
thiserror = { workspace = true, optional = true }
thiserror.workspace = true
tokio.workspace = true
tonic = { workspace = true, optional = true }
uuid = { version = "1.1.2", features = ["v4"] }
Expand Down
14 changes: 1 addition & 13 deletions attestation-service/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,8 @@ VERIFIER ?= all-verifier

RVPS_GRPC := true

# TODO: Remove `RVPS_BUILTIN`
# when https://github.com/confidential-containers/trustee/pull/553 gets merged
# Here we also declare another variable `RVPS_FEATURES1` because a blank will
# be added when doing '+=' operation in Makefile
RVPS_BUILTIN := true

ifeq ($(RVPS_GRPC), true)
RVPS_FEATURES1 := rvps-grpc
endif

ifeq ($(RVPS_BUILTIN), true)
RVPS_FEATURES := $(RVPS_FEATURES1),rvps-builtin
else
RVPS_FEATURES := $(RVPS_FEATURES1)
RVPS_FEATURES := rvps-grpc
endif

ifdef DEBUG
Expand Down
4 changes: 2 additions & 2 deletions attestation-service/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"work_dir": "/var/lib/attestation-service/",
"policy_engine": "opa",
"rvps_config": {
"store_type": "LocalFs",
"remote_addr": ""
"type": "BuiltIn",
"store_type": "LocalFs"
},
"attestation_token_broker": "Simple",
"attestation_token_config": {
Expand Down
145 changes: 145 additions & 0 deletions attestation-service/docs/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# CoCo AS Configuration File

The Confidential Containers KBS properties can be configured through a
JSON-formatted configuration file.

## Configurable Properties

The following sections list the CoCo AS properties which can be set through the
configuration file.

### Global Properties

The following properties can be set globally, i.e. not under any configuration
section:

| Property | Type | Description | Required | Default |
|----------------------------|-----------------------------|-----------------------------------------------------|----------|---------|
| `work_dir` | String | The location for Attestation Service to store data. | False | Firstly try to read from ENV `AS_WORK_DIR`. If not any, use `/opt/confidential-containers/attestation-service` |
| `policy_engine` | String | Policy engine type. Valid values: `opa` | False | `opa` |
| `rvps_config` | [RVPSConfiguration][2] | RVPS configuration | False | - |
| `attestation_token_broker` | String | Type of the attestation result token broker. Valid values: `Simple` | False | `Simple` |
| `attestation_token_config` | [AttestationTokenConfig][1] | Attestation result token configuration. | False | - |

[1]: #attestationtokenconfig
[2]: #rvps-configuration

#### AttestationTokenConfig

| Property | Type | Description | Required | Default |
|----------------|-------------------------|------------------------------------------------------|----------|---------|
| `duration_min` | Integer | Duration of the attestation result token in minutes. | No | `5` |
| `issuer_name` | String | Issure name of the attestation result token. | No |`CoCo-Attestation-Service`|
| `signer` | [TokenSignerConfig][1] | Signing material of the attestation result token. | No | None |

[1]: #tokensignerconfig

#### TokenSignerConfig

This section is **optional**. When omitted, a new RSA key pair is generated and used.

| Property | Type | Description | Required | Default |
|----------------|---------|----------------------------------------------------------|----------|---------|
| `key_path` | String | RSA Key Pair file (PEM format) path. | Yes | - |
| `cert_url` | String | RSA Public Key certificate chain (PEM format) URL. | No | - |
| `cert_path` | String | RSA Public Key certificate chain (PEM format) file path. | No | - |

#### RVPS Configuration

| Property | Type | Description | Required | Default |
|----------------|-------------------------|------------------------------------------------------|----------|---------|
| `type` | String | It can be either `BuiltIn` (Built-In RVPS) or `GrpcRemote` (connect to a remote gRPC RVPS) | No | `BuiltIn` |

##### BuiltIn RVPS

If `type` is set to `BuiltIn`, the following extra properties can be set

| Property | Type | Description | Required | Default |
|----------------|-------------------------|-----------------------------------------------------------------------|----------|----------|
| `store_type` | String | The underlying storage type of RVPS. (`LocalFs` or `LocalJson`) | No | `LocalFs`|
| `store_config` | JSON Map | The optional configurations to the underlying storage. | No | Null |

Different `store_type` will have different `store_config` items.

For `LocalFs`, the following properties can be set

| Property | Type | Description | Required | Default |
|----------------|-------------------------|----------------------------------------------------------|----------|----------|
| `file_path` | String | The path to the directory storing reference values | No | `/opt/confidential-containers/attestation-service/reference_values`|

For `LocalJson`, the following properties can be set

| Property | Type | Description | Required | Default |
|----------------|-------------------------|----------------------------------------------------------|----------|----------|
| `file_path` | String | The path to the file that storing reference values | No | `/opt/confidential-containers/attestation-service/reference_values.json`|

##### Remote RVPS

If `type` is set to `GrpcRemote`, the following extra properties can be set

| Property | Type | Description | Required | Default |
|----------------|-------------------------|-----------------------------------------|----------|------------------|
| `address` | String | Remote address of the RVPS server | No | `127.0.0.1:50003`|


## Configuration Examples

Running with a built-in RVPS:

```json
{
"work_dir": "/var/lib/attestation-service/",
"policy_engine": "opa",
"rvps_config": {
"type": "BuiltIn",
"store_type": "LocalFs",
"store_config": {
"file_path": "/var/lib/attestation-service/reference-values"
}
},
"attestation_token_broker": "Simple",
"attestation_token_config": {
"duration_min": 5
}
}
```

Running with a remote RVPS:

```json
{
"work_dir": "/var/lib/attestation-service/",
"policy_engine": "opa",
"rvps_config": {
"type": "GrpcRemote",
"address": "127.0.0.1:50003"
},
"attestation_token_broker": "Simple",
"attestation_token_config": {
"duration_min": 5
}
}
```

Configurations for token signer

```json
{
"work_dir": "/var/lib/attestation-service/",
"policy_engine": "opa",
"rvps_config": {
"type": "GrpcRemote",
"address": "127.0.0.1:50003"
},
"attestation_token_broker": "Simple",
"attestation_token_config": {
"duration_min": 5,
"issuer_name": "some-body",
"signer": {
"key_path": "/etc/coco-as/signer.key",
"cert_url": "https://example.io/coco-as-certchain",
"cert_path": "/etc/coco-as/signer.pub"
}
}
}
```
2 changes: 2 additions & 0 deletions attestation-service/docs/grpc-as.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ Then a response will be returned

The value is a base64 encoded JWT. The body of the JWT is showed in the [example.token.json](./example.token.json).

More configuration items please refer to the [document](./config.md).

## Advanced Topic

### Building from Source
Expand Down
3 changes: 3 additions & 0 deletions attestation-service/docs/restful-as.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJjdXN0b21pemVkX2NsYWltcyI6eyJ0ZXN0X2tleSI

The value is a base64 encoded JWT. The body of the JWT is showed in the [example.token.json](./example.token.json).


More configuration items please refer to the [document](./config.md).

## Advanced Topics

### Building from Source
Expand Down
21 changes: 14 additions & 7 deletions attestation-service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ const DEFAULT_WORK_DIR: &str = "/opt/confidential-containers/attestation-service
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct Config {
/// The location for Attestation Service to store data.
#[serde(default = "default_work_dir")]
pub work_dir: PathBuf,

/// Policy Engine type.
#[serde(default = "default_policy_engine")]
pub policy_engine: String,

/// Configurations for RVPS.
Expand All @@ -26,13 +28,22 @@ pub struct Config {
///
/// Possible values:
/// * `Simple`
#[serde(default)]
pub attestation_token_broker: AttestationTokenBrokerType,

/// The Attestation Result Token Broker Config
#[serde(default)]
pub attestation_token_config: AttestationTokenConfig,
}

fn default_work_dir() -> PathBuf {
PathBuf::from(std::env::var(AS_WORK_DIR).unwrap_or_else(|_| DEFAULT_WORK_DIR.to_string()))
}

fn default_policy_engine() -> String {
"opa".to_string()
}

#[derive(Error, Debug)]
pub enum ConfigError {
#[error("io error: {0}")]
Expand All @@ -48,15 +59,11 @@ pub enum ConfigError {
impl Default for Config {
// Construct a default instance of `Config`
fn default() -> Config {
let work_dir = PathBuf::from(
std::env::var(AS_WORK_DIR).unwrap_or_else(|_| DEFAULT_WORK_DIR.to_string()),
);

Config {
work_dir,
policy_engine: "opa".to_string(),
work_dir: default_work_dir(),
policy_engine: default_policy_engine(),
rvps_config: RvpsConfig::default(),
attestation_token_broker: AttestationTokenBrokerType::Simple,
attestation_token_broker: AttestationTokenBrokerType::default(),
attestation_token_config: AttestationTokenConfig::default(),
}
}
Expand Down
6 changes: 4 additions & 2 deletions attestation-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//!
//! # Features
//! - `rvps-grpc`: The AS will connect a remote RVPS.
//! - `rvps-builtin`: The AS will integrate RVPS functionalities itself.
pub mod config;
pub mod policy_engine;
Expand Down Expand Up @@ -273,7 +272,10 @@ impl AttestationService {

/// Registry a new reference value
pub async fn register_reference_value(&mut self, message: &str) -> Result<()> {
self.rvps.verify_and_extract(message).await
self.rvps
.verify_and_extract(message)
.await
.context("register reference value")
}

pub async fn generate_supplemental_challenge(
Expand Down
3 changes: 1 addition & 2 deletions attestation-service/src/rvps/builtin.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::RvpsApi;
use anyhow::*;
use super::{Result, RvpsApi};
use async_trait::async_trait;
use core::result::Result::Ok;
use reference_value_provider_service::{Config, Core};
Expand Down
32 changes: 26 additions & 6 deletions attestation-service/src/rvps/grpc.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,45 @@
use crate::rvps::RvpsError;
use anyhow::{Context, Result};
use serde::Deserialize;
use thiserror::Error;
use tokio::sync::Mutex;

use self::rvps_api::{
reference_value_provider_service_client::ReferenceValueProviderServiceClient,
ReferenceValueQueryRequest, ReferenceValueRegisterRequest,
};

use super::RvpsApi;
use super::{Result, RvpsApi};

pub mod rvps_api {
tonic::include_proto!("reference");
}

#[derive(Deserialize, Clone, Debug, PartialEq)]
pub struct RvpsRemoteConfig {
/// Address of remote RVPS. If this field is given, a remote RVPS will be connected to.
/// If this field is not given, a built-in RVPS will be used.
#[serde(default = "default_address")]
pub address: String,
}

fn default_address() -> String {
"127.0.0.1:50003".into()
}

#[derive(Error, Debug)]
pub enum GrpcRvpsError {
#[error("Returned status: {0}")]
Status(#[from] tonic::Status),

#[error("tonic transport error: {0}")]
TonicTransport(#[from] tonic::transport::Error),
}

pub struct Agent {
client: Mutex<ReferenceValueProviderServiceClient<tonic::transport::Channel>>,
}

impl Agent {
pub async fn new(addr: &str) -> Result<Self, RvpsError> {
pub async fn new(addr: &str) -> Result<Self> {
Ok(Self {
client: Mutex::new(
ReferenceValueProviderServiceClient::connect(addr.to_string()).await?,
Expand All @@ -37,8 +58,7 @@ impl RvpsApi for Agent {
.lock()
.await
.register_reference_value(req)
.await
.context("register failed")?;
.await?;
Ok(())
}

Expand Down
Loading

0 comments on commit 423e208

Please sign in to comment.