Skip to content

Commit

Permalink
token: re-enable simple tokens
Browse files Browse the repository at this point in the history
It turns out we do want to support the simple/coco tokens
alongside ear tokens.

This adds some complexity, but we can achieve it by making the policy
engine more flexible (it can now take a list of claims to evaluate).

We move the logic to evaluate the policy into the token broker itself.
Since each token broker will care about different claims and package the
results of evaluation in a different way, this logic can live inside the
token broker itself.

Signed-off-by: Tobin Feldman-Fitzthum <[email protected]>
Signed-off-by: Xynnn007 <[email protected]>
  • Loading branch information
fitzthum committed Oct 30, 2024
1 parent b78e38d commit 8049709
Show file tree
Hide file tree
Showing 27 changed files with 1,539 additions and 634 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/as-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ jobs:
- name: OPA policy.rego fmt and check
run: |
opa fmt -d attestation-service/src/policy_engine/opa/default_policy.rego | awk '{ print } END { if (NR!=0) { print "run `opa fmt -w <path_to_rego>` to fix this"; exit 1 } }'
opa check attestation-service/src/policy_engine/opa/default_policy.rego
opa fmt -d attestation-service/src/token/ear_default_policy.rego | awk '{ print } END { if (NR!=0) { print "run `opa fmt -w <path_to_rego>` to fix this"; exit 1 } }'
opa check attestation-service/src/token/ear_default_policy.rego
opa fmt -d attestation-service/src/token/simple_default_policy.rego | awk '{ print } END { if (NR!=0) { print "run `opa fmt -w <path_to_rego>` to fix this"; exit 1 } }'
opa check attestation-service/src/token/simple_default_policy.rego
- name: Install protoc
run: |
Expand Down
50 changes: 6 additions & 44 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ kms = { git = "https://github.com/confidential-containers/guest-components.git",
jsonwebtoken = { version = "9", default-features = false }
log = "0.4.17"
prost = "0.12"
regorus = { version = "0.1.5", default-features = false, features = ["regex", "base64", "time"] }
regorus = { version = "0.2.6", default-features = false, features = ["regex", "base64", "time", "std" ] }
reqwest = { version = "0.12", default-features = false, features = ["default-tls"] }
rstest = "0.18.1"
serde = { version = "1.0", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion attestation-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ The results of every policy that is evaluated are included in the attestation to

**Note**: Please refer to the [Policy Language](https://www.openpolicyagent.org/docs/latest/policy-language/) documentation for more information about Rego.

If the policy is not updated, the AS will use the [default policy](src/policy_engine/opa/default_policy.rego).
If the policy is not updated, the AS will use the [default policy](src/token/ear_default_policy.rego).

Concrete policy usages please refer to [this guide](docs/policy.md).

Expand Down
5 changes: 2 additions & 3 deletions attestation-service/config.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"work_dir": "/var/lib/attestation-service/",
"policy_engine": "opa",
"rvps_config": {
"store_type": "LocalFs",
"remote_addr": ""
},
"attestation_token_broker": "Simple",
"attestation_token_config": {
"attestation_token_broker": {
"type": "Simple",
"duration_min": 5
}
}
4 changes: 2 additions & 2 deletions attestation-service/docs/policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ values provided by the RVPS.

`input` are the TCB claims generated by the verifier.

See the [default policy](../src/policy_engine/opa/default_policy.rego) for an example.
See the [default policy](../src/token/ear_default_policy.rego) for an example.

## How to Use Policy

Expand Down Expand Up @@ -102,7 +102,7 @@ curl -k -X POST http://127.0.0.1:8080/attestation \

We will introduce the format of policy by providing some examples to show the use cases.

1. The [default policy](../src/policy_engine/opa/default_policy.rego). This policy assigns multiple trust claims based on reference values.
1. The [default policy](../src/token/ear_default_policy.rego). This policy assigns multiple trust claims based on reference values.
2. An [SGX policy](../tests/coco-as/policy/example-1.rego). The client want to ensure the `mr_signer` and `mrenclave` are both expected value.
3. A [TDX policy](../tests/coco-as/policy/example-2.rego). The client want to ensure the TDX module (reflected by `tdx.quote.body.mr_seam`), guest firmware (reflected by `tdx.quote.body.mr_td`), kernel (reflected by `tdx.ccel.kernel`) are all as expected.
4. A [IBM SE policy](../tests/coco-as/policy/example-3.rego). The client want to ensure the `se.version`, `se.tag`, `se.user_data`, `se.image_phkh` and `se.attestation_phkh` are all expected value.
9 changes: 1 addition & 8 deletions attestation-service/src/bin/restful/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,6 @@ pub async fn attestation(
}
};

let policy_ids = if request.policy_ids.is_empty() {
info!("no policy specified, use `default`");
vec!["default".into()]
} else {
request.policy_ids
};

let token = cocoas
.read()
.await
Expand All @@ -156,7 +149,7 @@ pub async fn attestation(
runtime_data_hash_algorithm,
init_data,
init_data_hash_algorithm,
policy_ids,
request.policy_ids,
)
.await
.context("attestation report evaluate")?;
Expand Down
104 changes: 96 additions & 8 deletions attestation-service/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,18 @@ use thiserror::Error;

/// Environment macro for Attestation Service work dir.
const AS_WORK_DIR: &str = "AS_WORK_DIR";
const DEFAULT_WORK_DIR: &str = "/opt/confidential-containers/attestation-service";
pub const DEFAULT_WORK_DIR: &str = "/opt/confidential-containers/attestation-service";

#[derive(Clone, Debug, Deserialize)]
#[derive(Clone, Debug, Deserialize, PartialEq)]
pub struct Config {
/// The location for Attestation Service to store data.
pub work_dir: PathBuf,

/// Policy Engine type.
pub policy_engine: String,

/// Configurations for RVPS.
pub rvps_config: RvpsConfig,

/// The Attestation Result Token Broker Config
pub attestation_token_config: AttestationTokenConfig,
pub attestation_token_broker: AttestationTokenConfig,
}

#[derive(Error, Debug)]
Expand All @@ -46,9 +43,8 @@ impl Default for Config {

Config {
work_dir,
policy_engine: "opa".to_string(),
rvps_config: RvpsConfig::default(),
attestation_token_config: AttestationTokenConfig::default(),
attestation_token_broker: AttestationTokenConfig::default(),
}
}
}
Expand All @@ -74,3 +70,95 @@ impl TryFrom<&Path> for Config {
serde_json::from_reader::<File, Config>(file).map_err(ConfigError::JsonFileParse)
}
}

#[cfg(test)]
mod tests {
use std::path::PathBuf;

use rstest::rstest;
use serde_json::json;

use crate::{
rvps::RvpsConfig,
token::{ear_broker, simple, AttestationTokenConfig},
};

use super::Config;

#[rstest]
#[case("./tests/configs/example1.json", Config {
work_dir: PathBuf::from("/var/lib/attestation-service/"),
rvps_config: RvpsConfig {
remote_addr: "".into(),
store_type: "LocalFs".into(),
store_config: json!({}),
},
attestation_token_broker: AttestationTokenConfig::Simple(simple::Configuration {
duration_min: 5,
issuer_name: "test".into(),
signer: None,
policy_dir: "/var/lib/attestation-service/policies".into(),
})
})]
#[case("./tests/configs/example2.json", Config {
work_dir: PathBuf::from("/var/lib/attestation-service/"),
rvps_config: RvpsConfig {
remote_addr: "".into(),
store_type: "LocalFs".into(),
store_config: json!({}),
},
attestation_token_broker: AttestationTokenConfig::Simple(simple::Configuration {
duration_min: 5,
issuer_name: "test".into(),
policy_dir: "/var/lib/attestation-service/policies".into(),
signer: Some(simple::TokenSignerConfig {
key_path: "/etc/key".into(),
cert_url: Some("https://example.io".into()),
cert_path: Some("/etc/cert.pem".into())
})
})
})]
#[case("./tests/configs/example3.json", Config {
work_dir: PathBuf::from("/var/lib/attestation-service/"),
rvps_config: RvpsConfig {
remote_addr: "".into(),
store_type: "LocalFs".into(),
store_config: json!({}),
},
attestation_token_broker: AttestationTokenConfig::Ear(ear_broker::Configuration {
duration_min: 5,
issuer_name: "test".into(),
signer: None,
policy_dir: "/var/lib/attestation-service/policies".into(),
developer_name: "someone".into(),
build_name: "0.1.0".into(),
profile_name: "tag:github.com,2024:confidential-containers/Trustee".into()
})
})]
#[case("./tests/configs/example4.json", Config {
work_dir: PathBuf::from("/var/lib/attestation-service/"),
rvps_config: RvpsConfig {
remote_addr: "".into(),
store_type: "LocalFs".into(),
store_config: json!({}),
},
attestation_token_broker: AttestationTokenConfig::Ear(ear_broker::Configuration {
duration_min: 5,
issuer_name: "test".into(),
policy_dir: "/var/lib/attestation-service/policies".into(),
developer_name: "someone".into(),
build_name: "0.1.0".into(),
profile_name: "tag:github.com,2024:confidential-containers/Trustee".into(),
signer: Some(ear_broker::TokenSignerConfig {
key_path: "/etc/key".into(),
cert_url: Some("https://example.io".into()),
cert_path: Some("/etc/cert.pem".into())
})
})
})]
fn read_config(#[case] config: &str, #[case] expected: Config) {
let config = std::fs::read_to_string(config).unwrap();
let config: Config = serde_json::from_str(&config).unwrap();
assert_eq!(config, expected);
}
}
Loading

0 comments on commit 8049709

Please sign in to comment.