diff --git a/attestation-service/Cargo.toml b/attestation-service/Cargo.toml index fce9a5a6c..4e9e32bc7 100644 --- a/attestation-service/Cargo.toml +++ b/attestation-service/Cargo.toml @@ -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" ] @@ -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 } @@ -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 @@ -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"] } diff --git a/attestation-service/Makefile b/attestation-service/Makefile index c8ed190eb..f75e1daf2 100644 --- a/attestation-service/Makefile +++ b/attestation-service/Makefile @@ -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 diff --git a/attestation-service/config.json b/attestation-service/config.json index 1c66a61a0..332abd611 100644 --- a/attestation-service/config.json +++ b/attestation-service/config.json @@ -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": { diff --git a/attestation-service/docs/config.md b/attestation-service/docs/config.md new file mode 100644 index 000000000..a59807a1f --- /dev/null +++ b/attestation-service/docs/config.md @@ -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" + } + } +} +``` diff --git a/attestation-service/docs/grpc-as.md b/attestation-service/docs/grpc-as.md index 41f0042c9..1084d09b6 100644 --- a/attestation-service/docs/grpc-as.md +++ b/attestation-service/docs/grpc-as.md @@ -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 diff --git a/attestation-service/docs/restful-as.md b/attestation-service/docs/restful-as.md index 2a4c3196c..ab5c9618d 100644 --- a/attestation-service/docs/restful-as.md +++ b/attestation-service/docs/restful-as.md @@ -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 diff --git a/attestation-service/src/config.rs b/attestation-service/src/config.rs index 232567648..895b00857 100644 --- a/attestation-service/src/config.rs +++ b/attestation-service/src/config.rs @@ -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. @@ -26,6 +28,7 @@ pub struct Config { /// /// Possible values: /// * `Simple` + #[serde(default)] pub attestation_token_broker: AttestationTokenBrokerType, /// The Attestation Result Token Broker Config @@ -33,6 +36,14 @@ pub struct Config { 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}")] @@ -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(), } } diff --git a/attestation-service/src/lib.rs b/attestation-service/src/lib.rs index 6e66c722e..0f95bf836 100644 --- a/attestation-service/src/lib.rs +++ b/attestation-service/src/lib.rs @@ -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; @@ -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( diff --git a/attestation-service/src/rvps/builtin.rs b/attestation-service/src/rvps/builtin.rs index 055dd5130..084281516 100644 --- a/attestation-service/src/rvps/builtin.rs +++ b/attestation-service/src/rvps/builtin.rs @@ -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}; diff --git a/attestation-service/src/rvps/grpc.rs b/attestation-service/src/rvps/grpc.rs index 5ddc232b5..6538e8ae2 100644 --- a/attestation-service/src/rvps/grpc.rs +++ b/attestation-service/src/rvps/grpc.rs @@ -1,5 +1,5 @@ -use crate::rvps::RvpsError; -use anyhow::{Context, Result}; +use serde::Deserialize; +use thiserror::Error; use tokio::sync::Mutex; use self::rvps_api::{ @@ -7,18 +7,39 @@ use self::rvps_api::{ 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>, } impl Agent { - pub async fn new(addr: &str) -> Result { + pub async fn new(addr: &str) -> Result { Ok(Self { client: Mutex::new( ReferenceValueProviderServiceClient::connect(addr.to_string()).await?, @@ -37,8 +58,7 @@ impl RvpsApi for Agent { .lock() .await .register_reference_value(req) - .await - .context("register failed")?; + .await?; Ok(()) } diff --git a/attestation-service/src/rvps/mod.rs b/attestation-service/src/rvps/mod.rs index 4e34ce847..b95b0a6b3 100644 --- a/attestation-service/src/rvps/mod.rs +++ b/attestation-service/src/rvps/mod.rs @@ -3,15 +3,35 @@ // SPDX-License-Identifier: Apache-2.0 // -use anyhow::Result; -use log::{info, warn}; -pub use reference_value_provider_service::config::{ - Config as RvpsCrateConfig, DEFAULT_STORAGE_TYPE, -}; +use log::info; +pub use reference_value_provider_service::config::Config as RvpsCrateConfig; use serde::Deserialize; -use serde_json::{json, Value}; use thiserror::Error; +#[cfg(feature = "rvps-grpc")] +pub mod grpc; + +pub mod builtin; + +#[derive(Error, Debug)] +pub enum RvpsError { + #[error("Serde Json Error: {0}")] + SerdeJson(#[from] serde_json::Error), + + #[cfg(feature = "rvps-grpc")] + #[error("Returned status: {0}")] + Status(#[from] tonic::Status), + + #[cfg(feature = "rvps-grpc")] + #[error("tonic transport error: {0}")] + TonicTransport(#[from] tonic::transport::Error), + + #[error(transparent)] + Anyhow(#[from] anyhow::Error), +} + +type Result = std::result::Result; + /// The interfaces of Reference Value Provider Service /// * `verify_and_extract` is responsible for verify a message and /// store reference values from it. @@ -26,93 +46,31 @@ pub trait RvpsApi { async fn get_digests(&self, name: &str) -> Result>; } -#[cfg(feature = "rvps-grpc")] -pub mod grpc; - -#[cfg(feature = "rvps-builtin")] -pub mod builtin; - -fn default_store_type() -> String { - DEFAULT_STORAGE_TYPE.into() -} - -fn default_store_config() -> Value { - json!({}) -} - #[derive(Deserialize, Clone, Debug, PartialEq)] -pub struct RvpsConfig { - /// 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 = "String::default")] - pub remote_addr: String, - - /// This field will be used only if `remote_addr` is not given. - #[serde(default = "default_store_type")] - pub store_type: String, - - /// This field will be used only if `remote_addr` is not given. - #[serde(default = "default_store_config")] - pub store_config: Value, -} - -impl From for RvpsCrateConfig { - fn from(val: RvpsConfig) -> RvpsCrateConfig { - RvpsCrateConfig { - store_type: val.store_type, - store_config: val.store_config, - } - } +#[serde(tag = "type")] +pub enum RvpsConfig { + BuiltIn(RvpsCrateConfig), + #[cfg(feature = "rvps-grpc")] + GrpcRemote(grpc::RvpsRemoteConfig), } impl Default for RvpsConfig { fn default() -> Self { - Self { - remote_addr: String::new(), - store_type: default_store_type(), - store_config: default_store_config(), - } + Self::BuiltIn(RvpsCrateConfig::default()) } } -#[derive(Error, Debug)] -pub enum RvpsError { - #[error("feature `rvps-grpc` or `rvps-builtin` should be enabled")] - FeatureNotEnabled, - #[error("Serde Json Error: {0}")] - SerdeJson(#[from] serde_json::Error), - #[error("Returned status: {0}")] - Status(#[from] tonic::Status), - #[error("tonic transport error: {0}")] - TonicTransport(#[from] tonic::transport::Error), - #[error(transparent)] - Anyhow(#[from] anyhow::Error), -} - -pub async fn initialize_rvps_client( - config: &RvpsConfig, -) -> Result, RvpsError> { - cfg_if::cfg_if! { - if #[cfg(feature = "rvps-grpc")] { - if !config.remote_addr.is_empty() { - let remote_addr = &config.remote_addr; - info!("connect to remote RVPS: {remote_addr}"); - Ok(Box::new(grpc::Agent::new(remote_addr).await?) as Box) - } else { - cfg_if::cfg_if! { - if #[cfg(feature = "rvps-builtin")] { - warn!("No RVPS address provided and will launch a built-in rvps"); - Ok(Box::new(builtin::Rvps::new(config.clone().into())?) as Box) - } else { - return RvpsError::FeatureNotEnabled; - } - } - } - } else if #[cfg(feature = "rvps-builtin")] { +pub async fn initialize_rvps_client(config: &RvpsConfig) -> Result> { + match config { + RvpsConfig::BuiltIn(config) => { info!("launch a built-in RVPS."); - Ok(Box::new(builtin::Rvps::new(config.clone().into())) as Box) - } else { - return RvpsError::FeatureNotEnabled; + Ok(Box::new(builtin::Rvps::new(config.clone())?) as Box) + } + #[cfg(feature = "rvps-grpc")] + RvpsConfig::GrpcRemote(config) => { + info!("connect to remote RVPS: {}", config.address); + Ok(Box::new(grpc::Agent::new(&config.address).await?) + as Box) } } } diff --git a/attestation-service/src/token/mod.rs b/attestation-service/src/token/mod.rs index 1af172196..6a6616e4d 100644 --- a/attestation-service/src/token/mod.rs +++ b/attestation-service/src/token/mod.rs @@ -23,8 +23,9 @@ pub trait AttestationTokenBroker { fn pubkey_jwks(&self) -> Result; } -#[derive(Deserialize, Debug, Clone, EnumString, Display, PartialEq)] +#[derive(Deserialize, Debug, Clone, EnumString, Display, Default, PartialEq)] pub enum AttestationTokenBrokerType { + #[default] Simple, } diff --git a/deps/verifier/src/se/README.md b/deps/verifier/src/se/README.md index 569d4c92f..887b711d4 100644 --- a/deps/verifier/src/se/README.md +++ b/deps/verifier/src/se/README.md @@ -112,8 +112,8 @@ attestation_token_broker = "Simple" duration_min = 5 [as_config.rvps_config] +type = "BuiltIn" store_type = "LocalFs" -remote_addr = "" ``` - Launch the KBS program diff --git a/kbs/Cargo.toml b/kbs/Cargo.toml index b58e08b15..663dcc03a 100644 --- a/kbs/Cargo.toml +++ b/kbs/Cargo.toml @@ -19,7 +19,7 @@ coco-as = ["as"] coco-as-builtin = ["coco-as", "attestation-service/default"] # Use built-in CoCo-AS as backend attestation service without verifier -coco-as-builtin-no-verifier = ["coco-as", "attestation-service/rvps-builtin"] +coco-as-builtin-no-verifier = ["coco-as"] # Use remote gRPC CoCo-AS as backend attestation service coco-as-grpc = ["coco-as", "mobc", "tonic", "tonic-build", "prost"] diff --git a/kbs/config/as-config.json b/kbs/config/as-config.json index 9445908e5..0a2a3e1f9 100644 --- a/kbs/config/as-config.json +++ b/kbs/config/as-config.json @@ -2,10 +2,11 @@ "work_dir": "/opt/confidential-containers/attestation-service", "policy_engine": "opa", "rvps_config": { - "remote_addr":"http://rvps:50003" + "type": "GrpcRemote", + "address": "http://rvps:50003" }, "attestation_token_broker": "Simple", "attestation_token_config": { "duration_min": 5 } -} +} \ No newline at end of file diff --git a/kbs/config/kbs-config.toml b/kbs/config/kbs-config.toml index e7bed67c3..0adef72ea 100644 --- a/kbs/config/kbs-config.toml +++ b/kbs/config/kbs-config.toml @@ -14,8 +14,8 @@ attestation_token_broker = "Simple" duration_min = 5 [attestation_service.rvps_config] +type = "BuiltIn" store_type = "LocalFs" -remote_addr = "" [policy_engine] policy_path = "/opa/confidential-containers/kbs/policy.rego" diff --git a/kbs/config/kubernetes/base/kbs-config.toml b/kbs/config/kubernetes/base/kbs-config.toml index b142f52c6..3bee3790b 100644 --- a/kbs/config/kubernetes/base/kbs-config.toml +++ b/kbs/config/kubernetes/base/kbs-config.toml @@ -13,12 +13,12 @@ work_dir = "/opt/confidential-containers/attestation-service" policy_engine = "opa" attestation_token_broker = "Simple" - [attestation_service.attestation_token_config] - duration_min = 5 +[attestation_service.attestation_token_config] +duration_min = 5 - [attestation_service.rvps_config] - store_type = "LocalFs" - remote_addr = "" +[attestation_service.rvps_config] +type = "BuiltIn" +store_type = "LocalFs" [admin] auth_public_key = "/kbs/kbs.pem" diff --git a/kbs/docs/config.md b/kbs/docs/config.md index d044b7632..b4830c18a 100644 --- a/kbs/docs/config.md +++ b/kbs/docs/config.md @@ -82,7 +82,7 @@ When `type` is set to `coco_as_builtin`, the following properties can be set. | Property | Type | Description | Default | |----------------------------|-----------------------------|-----------------------------------------------------|----------| -| `timeout` | Integer | The maximum time (in minutes) between RCAR handshake's `auth` and `attest` requests | 5 | +| `timeout` | Integer | The maximum time (in minutes) of the attestation session | 5 | | `work_dir` | String | The location for Attestation Service to store data. | First try from env `AS_WORK_DIR`. If no this env, then use `/opt/confidential-containers/attestation-service` | | `policy_engine` | String | Policy engine type. Valid values: `opa` | `opa` | | `rvps_config` | [RVPSConfiguration][2] | RVPS configuration | See [RVPSConfiguration][2] | @@ -115,14 +115,40 @@ This section is **optional**. When omitted, an ephemeral RSA key pair is generat ##### RVPS Configuration -| Property | Type | Description | Default | -|----------------|-------------------------|------------------------------------------------------|---------| -| `remote_addr` | String | Remote RVPS' address. If this is specified, will use a remote RVPS. Or a local RVPS will be configured with `store_type` and `store_config`| Empty | -| `store_type` | String | Used if `remote_addr` is not set. The underlying storage type of RVPS. | `LocalFs` | -| `store_config` | JSON Map | Used if `remote_addr` is not set. The optional configurations to the underlying storage. | Empty | +| 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. -See the details of `store_config` in [concrete implementations of storages](../../rvps/src/store/). + +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`| #### gRPC CoCo AS @@ -231,8 +257,8 @@ attestation_token_broker = "Simple" duration_min = 5 [attestation_service.rvps_config] + type = "BuiltIn" store_type = "LocalFs" - remote_addr = "" [[plugins]] name = "resource" diff --git a/kbs/docs/self-signed-https.md b/kbs/docs/self-signed-https.md index 034bf77b0..3d9e19df6 100644 --- a/kbs/docs/self-signed-https.md +++ b/kbs/docs/self-signed-https.md @@ -87,7 +87,7 @@ attestation_token_broker = "Simple" duration_min = 5 [attestation_service.rvps_config] - remote_addr = "" + type = "BuiltIn" store_type = "LocalFs" [[plugins]] diff --git a/kbs/src/config.rs b/kbs/src/config.rs index 06d3af2a1..3c4f2ff41 100644 --- a/kbs/src/config.rs +++ b/kbs/src/config.rs @@ -120,7 +120,7 @@ mod tests { #[cfg(feature = "coco-as-builtin")] use attestation_service::{ - rvps::{RvpsConfig, DEFAULT_STORAGE_TYPE}, + rvps::{grpc::RvpsRemoteConfig, RvpsConfig, RvpsCrateConfig}, token::{ AttestationTokenBrokerType, AttestationTokenConfig, COCO_AS_ISSUER_NAME, DEFAULT_TOKEN_TIMEOUT, @@ -186,11 +186,9 @@ mod tests { work_dir: "/opt/coco/attestation-service".into(), policy_engine: "opa".into(), attestation_token_broker: AttestationTokenBrokerType::Simple, - rvps_config: RvpsConfig { - remote_addr: "http://127.0.0.1:50003".into(), - store_type: DEFAULT_STORAGE_TYPE.into(), - store_config: json!({}), - }, + rvps_config: RvpsConfig::GrpcRemote(RvpsRemoteConfig { + address: "http://127.0.0.1:50003".into(), + }), attestation_token_config: AttestationTokenConfig { duration_min: DEFAULT_TOKEN_TIMEOUT, issuer_name: COCO_AS_ISSUER_NAME.into(), @@ -301,11 +299,10 @@ mod tests { work_dir: "/opt/confidential-containers/attestation-service".into(), policy_engine: "opa".into(), attestation_token_broker: AttestationTokenBrokerType::Simple, - rvps_config: RvpsConfig { - remote_addr: "".into(), + rvps_config: RvpsConfig::BuiltIn(RvpsCrateConfig { store_type: "LocalFs".into(), store_config: json!({}), - }, + }), attestation_token_config: AttestationTokenConfig { duration_min: 5, ..Default::default() @@ -434,11 +431,10 @@ mod tests { work_dir: "/opt/confidential-containers/attestation-service".into(), policy_engine: "opa".into(), attestation_token_broker: AttestationTokenBrokerType::Simple, - rvps_config: RvpsConfig { - remote_addr: "".into(), + rvps_config: RvpsConfig::BuiltIn(RvpsCrateConfig { store_type: "LocalFs".into(), ..Default::default() - }, + }), attestation_token_config: AttestationTokenConfig { duration_min: 5, ..Default::default() diff --git a/kbs/test/config/kbs.toml b/kbs/test/config/kbs.toml index 933f16979..012e8b622 100644 --- a/kbs/test/config/kbs.toml +++ b/kbs/test/config/kbs.toml @@ -14,16 +14,16 @@ work_dir = "./work/attestation-service" policy_engine = "opa" attestation_token_broker = "Simple" - [attestation_service.attestation_token_config] - duration_min = 5 +[attestation_service.attestation_token_config] +duration_min = 5 - [attestation_service.attestation_token_config.signer] - key_path = "./work/token.key" - cert_path = "./work/token-cert-chain.pem" +[attestation_service.attestation_token_config.signer] +key_path = "./work/token.key" +cert_path = "./work/token-cert-chain.pem" - [attestation_service.rvps_config] - store_type = "LocalFs" - remote_addr = "" +[attestation_service.rvps_config] +type = "BuiltIn" +store_type = "LocalFs" [policy_engine] policy_path = "./work/kbs-policy.rego" diff --git a/kbs/test_data/configs/coco-as-builtin-1.toml b/kbs/test_data/configs/coco-as-builtin-1.toml index 7fd6da32c..1b776755d 100644 --- a/kbs/test_data/configs/coco-as-builtin-1.toml +++ b/kbs/test_data/configs/coco-as-builtin-1.toml @@ -4,5 +4,6 @@ work_dir = "/opt/coco/attestation-service" policy_engine = "opa" attestation_token_broker = "Simple" - [attestation_service.rvps_config] - remote_addr = "http://127.0.0.1:50003" +[attestation_service.rvps_config] +type = "GrpcRemote" +address = "http://127.0.0.1:50003" diff --git a/kbs/test_data/configs/coco-as-builtin-2.toml b/kbs/test_data/configs/coco-as-builtin-2.toml index c2398128c..e137d9523 100644 --- a/kbs/test_data/configs/coco-as-builtin-2.toml +++ b/kbs/test_data/configs/coco-as-builtin-2.toml @@ -12,12 +12,12 @@ work_dir = "/opt/confidential-containers/attestation-service" policy_engine = "opa" attestation_token_broker = "Simple" - [attestation_service.attestation_token_config] - duration_min = 5 +[attestation_service.attestation_token_config] +duration_min = 5 - [attestation_service.rvps_config] - store_type = "LocalFs" - remote_addr = "" +[attestation_service.rvps_config] +type = "BuiltIn" +store_type = "LocalFs" [admin] auth_public_key = "/kbs/kbs.pem" diff --git a/kbs/test_data/configs/coco-as-builtin-3.toml b/kbs/test_data/configs/coco-as-builtin-3.toml index 1d8e13f44..7786781d8 100644 --- a/kbs/test_data/configs/coco-as-builtin-3.toml +++ b/kbs/test_data/configs/coco-as-builtin-3.toml @@ -9,12 +9,12 @@ work_dir = "/opt/confidential-containers/attestation-service" policy_engine = "opa" attestation_token_broker = "Simple" - [attestation_service.attestation_token_config] - duration_min = 5 +[attestation_service.attestation_token_config] +duration_min = 5 - [attestation_service.rvps_config] - store_type = "LocalFs" - remote_addr = "" +[attestation_service.rvps_config] +type = "BuiltIn" +store_type = "LocalFs" [policy_engine] policy_path = "/opa/confidential-containers/kbs/policy.rego" diff --git a/rvps/README.md b/rvps/README.md index 3500d3f09..f2fb5fb49 100644 --- a/rvps/README.md +++ b/rvps/README.md @@ -100,8 +100,7 @@ RVPS can be launched with a specified configuration file by `-c` flag. A configu ### Native Mode (Not Recommend) -In this way RVPS will work as a crate inside AS binary. If AS is built without feature `rvps-grpc` -and with feature `rvps-builtin`, the RVPS will be built-in AS. +In this way RVPS will work as a crate inside AS binary. ![](./diagrams/rvps-native.svg) diff --git a/rvps/src/config.rs b/rvps/src/config.rs index 63103d014..98bf34f58 100644 --- a/rvps/src/config.rs +++ b/rvps/src/config.rs @@ -8,16 +8,27 @@ use serde_json::{json, Value}; pub const DEFAULT_STORAGE_TYPE: &str = "LocalFs"; -#[derive(Deserialize, Clone, Debug)] +#[derive(Deserialize, Clone, Debug, PartialEq)] pub struct Config { + #[serde(default = "default_store_type")] pub store_type: String, + + #[serde(default = "default_store_config")] pub store_config: Value, } +fn default_store_type() -> String { + DEFAULT_STORAGE_TYPE.to_string() +} + +fn default_store_config() -> Value { + json!({}) +} + impl Default for Config { fn default() -> Self { Self { - store_type: DEFAULT_STORAGE_TYPE.to_string(), + store_type: default_store_type(), store_config: json!({}), } }