Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

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

13 changes: 7 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,18 @@ test-kbs-docker-e2e:
trap "docker compose -f $(CURDIR)/docker-compose.yml --project-directory $$E2E_DIR down -v; sudo rm -rf $$E2E_DIR || true" EXIT && \
set -e && \
mkdir -p $$E2E_DIR/kbs/config/docker-compose $$E2E_DIR/kbs/data/kbs-storage $$E2E_DIR/kbs/data/nebula-ca $$E2E_DIR/kbs/data/attestation-service $$E2E_DIR/kbs/data/reference-values && \
cp $(CURDIR)/kbs/config/as-config.json $(CURDIR)/kbs/config/rvps.json $$E2E_DIR/kbs/config/ && \
cp $(CURDIR)/kbs/config/docker-compose/kbs-config.toml $$E2E_DIR/kbs/config/docker-compose/ && \
openssl genpkey -algorithm ed25519 > $$E2E_DIR/kbs/config/private.key && \
openssl pkey -in $$E2E_DIR/kbs/config/private.key -pubout -out $$E2E_DIR/kbs/config/public.pub && \
cp $(CURDIR)/kbs/config/docker-compose/as-config.json \
$(CURDIR)/kbs/config/docker-compose/rvps.json \
$(CURDIR)/kbs/config/docker-compose/kbs-config.toml \
$(CURDIR)/kbs/config/docker-compose/setup.sh \
$$E2E_DIR/kbs/config/docker-compose/ && \
docker compose -f $(CURDIR)/docker-compose.yml build --build-arg BUILDPLATFORM="$${BUILD_PLATFORM:-linux/amd64}" --build-arg ARCH="$${TARGET_ARCH:-x86_64}" --build-arg VERIFIER="$${VERIFIER:-all-verifier}" && \
docker compose -f $(CURDIR)/docker-compose.yml --project-directory $$E2E_DIR up -d && \
cd $(CURDIR)/target/release && \
echo "shhhhh" > test-secret && \
./kbs-client --url http://127.0.0.1:8080 config --auth-private-key $$E2E_DIR/kbs/config/private.key set-resource --path "test-org/test-repo/test-secret" --resource-file test-secret && \
./kbs-client --url http://127.0.0.1:8080 config --admin-token-file $$E2E_DIR/kbs/config/docker-compose/admin-token set-resource --path "test-org/test-repo/test-secret" --resource-file test-secret && \
! ./kbs-client --url http://127.0.0.1:8080 get-resource --path "test-org/test-repo/test-secret" && \
./kbs-client --url http://127.0.0.1:8080 config --auth-private-key $$E2E_DIR/kbs/config/private.key set-resource-policy --policy-file "$(CURDIR)/kbs/test/data/policy_2.rego" && \
./kbs-client --url http://127.0.0.1:8080 config --admin-token-file $$E2E_DIR/kbs/config/docker-compose/admin-token set-resource-policy --policy-file "$(CURDIR)/kbs/test/data/policy_2.rego" && \
./kbs-client --url http://127.0.0.1:8080 get-resource --path "test-org/test-repo/test-secret"

# Attestation service e2e tests
Expand Down
4 changes: 2 additions & 2 deletions attestation-service/docs/amd-offline-certificate-cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ environments.

Update the attestation configuration file to use a predefined vcek store:

`kbs/config/as-config.json`:
`kbs/config/docker-compose/as-config.json`:

```json
{
Expand Down Expand Up @@ -142,7 +142,7 @@ On the air-gapped trustee attestation-service host:
```bash
# Update as-config.json to enable Disk Caching
cd /path/to/trustee
vi kbs/config/as-config.json
vi kbs/config/docker-compose/as-config.json
# Update the verifier_config section to:
# "verifier_config": {
# "snp_verifier": {
Expand Down
14 changes: 9 additions & 5 deletions deps/verifier/src/se/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,15 @@ sockets = ["0.0.0.0:8080"]
insecure_http = true

[admin]
type = "Simple"
mode = "Enforce"

[[admin.personas]]
id = "admin"
public_key_path = "/kbs/kbs.pem"
[admin.token_verifier]
type = "BearerJwt"
signer_pairs = [{ issuer = "admin", public_key_path = "/kbs/kbs.pem" }]

[admin.authorizer]
type = "RegexAcl"
roles = [{ subject = "admin", allowed_endpoints = "^/kbs/.+$" }]

[attestation_token]
insecure_key = true
Expand Down Expand Up @@ -259,5 +263,5 @@ Where the values `se.version`, `se.attestation_phkh`, `se.image_phkh` and `se.ta

#### Set the attestation policy
```bash
kbs-client --url http://127.0.0.1:8080 config --auth-private-key ./kbs/kbs.key set-attestation-policy --policy-file ./ibmse-policy.rego
kbs-client --url http://127.0.0.1:8080 config --admin-token-file ./kbs/admin-token set-attestation-policy --policy-file ./ibmse-policy.rego
```
30 changes: 7 additions & 23 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:
volumes:
- ./kbs/data/kbs-storage:/opt/confidential-containers/kbs/repository:rw
- ./kbs/data/nebula-ca:/opt/confidential-containers/kbs/nebula-ca:rw
- ./kbs/config:/opt/confidential-containers/kbs/user-keys
- ./kbs/config/docker-compose:/opt/confidential-containers/kbs/user-keys
depends_on:
as:
condition: service_started
Expand All @@ -39,8 +39,8 @@ services:
- /run/dcap:size=50k
volumes:
- ./kbs/data/attestation-service:/opt/confidential-containers/attestation-service:rw
- ./kbs/config/as-config.json:/etc/as-config.json:rw
- ./kbs/config:/opt/confidential-containers/kbs/user-keys
- ./kbs/config/docker-compose/as-config.json:/etc/as-config.json:rw
- ./kbs/config/docker-compose:/opt/confidential-containers/kbs/user-keys
command: [
"grpc-as",
"--socket",
Expand All @@ -63,7 +63,7 @@ services:
- "50003:50003"
volumes:
- ./kbs/data/reference-values:/opt/confidential-containers/attestation-service/reference_values:rw
- ./kbs/config/rvps.json:/etc/rvps.json:rw
- ./kbs/config/docker-compose/rvps.json:/etc/rvps.json:rw
command: [
"rvps",
"--address",
Expand All @@ -78,7 +78,7 @@ services:
ports:
- "50000:50000"
volumes:
- ./kbs/config:/opt/confidential-containers/kbs/user-keys
- ./kbs/config/docker-compose:/opt/confidential-containers/kbs/user-keys
command: [
"coco_keyprovider",
"--socket",
Expand All @@ -98,23 +98,7 @@ services:
image: alpine/openssl
environment:
- RUST_LOG
entrypoint: /bin/ash
command: >
-c "
if [ ! -s /opt/confidential-containers/kbs/user-keys/private.key ]; then
/usr/bin/openssl genpkey -algorithm ed25519 > /opt/confidential-containers/kbs/user-keys/private.key &&
/usr/bin/openssl pkey -in /opt/confidential-containers/kbs/user-keys/private.key -pubout -out /opt/confidential-containers/kbs/user-keys/public.pub;
fi
cd /opt/confidential-containers/kbs/user-keys
if [ ! -s token.key ]; then
openssl genrsa -traditional -out ca.key 2048
openssl req -new -key ca.key -out ca-req.csr -subj \"/O=CNCF/OU=CoCo/CN=KBS-compose-root\"
openssl req -x509 -days 3650 -key ca.key -in ca-req.csr -out ca-cert.pem
openssl ecparam -name prime256v1 -genkey -noout -out token.key
openssl req -new -key token.key -out token-req.csr -subj \"/O=CNCF/OU=CoCo/CN=CoCo-AS\"
openssl x509 -req -in token-req.csr -CA ca-cert.pem -CAkey ca.key -CAcreateserial -out token-cert.pem -extensions req_ext
cat token-cert.pem ca-cert.pem > token-cert-chain.pem;
fi"
entrypoint: ["/bin/ash", "/opt/confidential-containers/kbs/user-keys/setup.sh"]

volumes:
- ./kbs/config:/opt/confidential-containers/kbs/user-keys
- ./kbs/config/docker-compose:/opt/confidential-containers/kbs/user-keys
1 change: 1 addition & 0 deletions integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ base64.workspace = true
openssl.workspace = true
rstest.workspace = true
serde_json.workspace = true
jsonwebtoken.workspace = true
serial_test.workspace = true
sha2.workspace = true
tempfile.workspace = true
Expand Down
117 changes: 67 additions & 50 deletions integration-tests/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use kbs::admin::{
simple::{SimpleAdminConfig, SimplePersonaConfig},
AdminBackendType, AdminConfig, AdminRole,
};
use kbs::admin::AdminConfig;
use kbs::attestation::config::{AttestationConfig, AttestationServiceConfig};
use kbs::config::HttpServerConfig;
use kbs::config::KbsConfig;
Expand Down Expand Up @@ -35,8 +32,10 @@ use base64::{
engine::general_purpose::{STANDARD, URL_SAFE_NO_PAD},
Engine,
};
use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
use openssl::pkey::PKey;
use serde_json::json;
use std::time::{SystemTime, UNIX_EPOCH};
use std::sync::{Arc, Once};
use tempfile::TempDir;
use tokio::sync::RwLock;
Expand Down Expand Up @@ -127,6 +126,23 @@ pub struct TestHarness {
}

impl TestHarness {
fn sign_admin_token(&self) -> Result<String> {
let encoding_key = EncodingKey::from_ed_pem(self.auth_privkey.as_bytes())?;
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|e| anyhow!("System time error: {e}"))?
.as_secs();
let claims = json!({
"issuer": "tester",
"subject": "tester",
"audiences": [],
"iat": now,
"exp": now + 7200,
});
let token = encode(&Header::new(Algorithm::EdDSA), &claims, &encoding_key)?;
Ok(token)
}

pub async fn new(test_parameters: TestParameters) -> Result<TestHarness> {
let auth_keypair = PKey::generate_ed25519()?;
let auth_pubkey = String::from_utf8(auth_keypair.public_key_to_pem()?)?;
Expand Down Expand Up @@ -197,32 +213,45 @@ impl TestHarness {
};

let admin_config = match &test_parameters.admin_type {
AdminType::Simple => AdminConfig {
admin_backend: AdminBackendType::Simple(SimpleAdminConfig {
personas: vec![SimplePersonaConfig {
id: "tester".to_string(),
public_key_path: auth_pubkey_path.as_path().to_path_buf(),
}],
}),
roles: Vec::new(),
},
AdminType::SimpleRestricted => AdminConfig {
admin_backend: AdminBackendType::Simple(SimpleAdminConfig {
personas: vec![SimplePersonaConfig {
id: "tester".to_string(),
public_key_path: auth_pubkey_path.as_path().to_path_buf(),
}],
}),
roles: vec![AdminRole {
id: "tester".to_string(),
allowed_endpoints: "^/kbs/v0/reference-value/[a-zA-Z0-9]+$".to_string(),
}],
},

AdminType::DenyAll => AdminConfig {
admin_backend: AdminBackendType::DenyAll,
roles: Vec::new(),
},
// Keep original "Simple" test semantics:
// requests must carry a verifiable admin token and are broadly authorized.
AdminType::Simple => serde_json::from_value(json!({
"mode": "Enforce",
"authorizer": {
"type": "RegexAcl",
"roles": [{
"subject": "tester",
"allowed_endpoints": "^/kbs/v0/.*$"
}]
},
"token_verifier": {
"type": "BearerJwt",
"signer_pairs": [{
"issuer": "tester",
"public_key_path": auth_pubkey_path.as_path()
}]
}
}))?,
// Keep restricted mode behavior as "authenticated admin required and then ACL checked".
// Build via serde to avoid direct construction of private config fields.
AdminType::SimpleRestricted => serde_json::from_value(json!({
"mode": "Enforce",
"authorizer": {
"type": "RegexAcl",
"roles": [{
"subject": "tester",
"allowed_endpoints": "^/kbs/v0/reference-value/[a-zA-Z0-9]+$"
}]
},
"token_verifier": {
"type": "BearerJwt",
"signer_pairs": [{
"issuer": "tester",
"public_key_path": auth_pubkey_path.as_path()
}]
}
}))?,
AdminType::DenyAll => AdminConfig::DenyAll,
};

let kbs_config = KbsConfig {
Expand Down Expand Up @@ -291,26 +320,21 @@ impl TestHarness {
PolicyType::Custom(p) => p.to_string().into_bytes(),
};

kbs_client::set_resource_policy(
KBS_URL,
self.auth_privkey.clone(),
policy_bytes,
// Optional HTTPS certs for KBS
vec![],
)
.await?;
let token = self.sign_admin_token()?;
kbs_client::set_resource_policy(KBS_URL, Some(token), policy_bytes, vec![]).await?;

Ok(())
}

pub async fn set_attestation_policy(&self, policy: String, policy_id: String) -> Result<()> {
let token = self.sign_admin_token()?;
kbs_client::set_attestation_policy(
KBS_URL,
self.auth_privkey.clone(),
Some(token),
policy.as_bytes().to_vec(),
None, // Policy type (default is rego)
None,
Some(policy_id),
vec![], // Optional HTTPS certs for KBS
vec![],
)
.await?;

Expand All @@ -319,15 +343,8 @@ impl TestHarness {

pub async fn set_secret(&self, secret_path: String, secret_bytes: Vec<u8>) -> Result<()> {
info!("TEST: Setting Secret");
kbs_client::set_resource(
KBS_URL,
self.auth_privkey.clone(),
secret_bytes,
&secret_path,
// Optional HTTPS certs for KBS
vec![],
)
.await?;
let token = self.sign_admin_token()?;
kbs_client::set_resource(KBS_URL, Some(token), secret_bytes, &secret_path, vec![]).await?;

Ok(())
}
Expand Down
Loading
Loading