secrets_core/
signing_keys.rs1use crate::embedded::{SecretsCore, SecretsError};
8use crate::spec_compat::SecretUri;
9use crate::types::Scope;
10use greentic_types::{SigningKeyRef, TeamId, TenantCtx};
11use tracing::info;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
15pub enum SigningPurpose {
16 Build,
17 Attestation,
18 Sbom,
19 Generic,
20}
21
22impl SigningPurpose {
23 fn as_name(self) -> &'static str {
24 match self {
25 SigningPurpose::Build => "build",
26 SigningPurpose::Attestation => "attestation",
27 SigningPurpose::Sbom => "sbom",
28 SigningPurpose::Generic => "generic",
29 }
30 }
31}
32
33pub fn signing_key_ref_uri(
35 tenant: &TenantCtx,
36 purpose: SigningPurpose,
37) -> Result<SecretUri, SecretsError> {
38 let scope = scope_from_tenant(tenant)?;
39 let name = format!("{}__key-ref", purpose.as_name());
40 SecretUri::new(scope, "signing", name).map_err(SecretsError::from)
41}
42
43pub async fn get_signing_key_ref(
45 core: &SecretsCore,
46 tenant: &TenantCtx,
47 purpose: SigningPurpose,
48) -> Result<SigningKeyRef, SecretsError> {
49 let uri = signing_key_ref_uri(tenant, purpose)?;
50 let res = core.get_json::<SigningKeyRef>(&uri.to_string()).await;
51 match &res {
52 Ok(value) => info!(
53 tenant = %tenant.tenant_id,
54 team = ?tenant.team,
55 purpose = %purpose.as_name(),
56 signing_key_ref = %value,
57 "retrieved signing key reference",
58 ),
59 Err(err) => info!(
60 tenant = %tenant.tenant_id,
61 team = ?tenant.team,
62 purpose = %purpose.as_name(),
63 error = %err,
64 "failed to retrieve signing key reference",
65 ),
66 }
67 res
68}
69
70fn scope_from_tenant(ctx: &TenantCtx) -> Result<Scope, SecretsError> {
71 let env = ctx.env.as_ref();
72 let tenant = ctx.tenant_id.as_ref();
73 let team = ctx.team.as_ref().or(ctx.team_id.as_ref()).map(|team| {
74 let t: &TeamId = team;
75 t.as_ref().to_string()
76 });
77 Scope::new(env, tenant, team).map_err(SecretsError::from)
78}