use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum SecretSource {
Vault {
mount: String,
path: String,
},
AwsSecretsManager {
secret_id: String,
region: Option<String>,
},
GcpSecretManager {
project: String,
secret_id: String,
},
AzureKeyVault {
vault_url: String,
secret_name: String,
},
OsKeystore {
service: String,
},
Kubernetes {
namespace: String,
name: String,
key: String,
},
Hardware {
slot: String,
},
Custom {
provider: String,
config: serde_json::Value,
},
}
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SecretAccessOutcome {
Resolved,
Denied,
Failed,
Renewed,
Released,
}
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecretAccessEvent {
pub credential_name: String,
pub source: SecretSource,
pub outcome: SecretAccessOutcome,
pub timestamp_ms: u64,
pub lease_id: Option<String>,
pub lease_ttl_secs: Option<u64>,
pub reason: Option<String>,
pub workflow_id: Option<String>,
pub agent_id: Option<String>,
pub trace_id: Option<String>,
}
impl SecretSource {
pub fn kind(&self) -> &'static str {
#[allow(unreachable_patterns)]
match self {
SecretSource::Vault { .. } => "vault",
SecretSource::AwsSecretsManager { .. } => "aws",
SecretSource::GcpSecretManager { .. } => "gcp",
SecretSource::AzureKeyVault { .. } => "azure",
SecretSource::OsKeystore { .. } => "os_keystore",
SecretSource::Kubernetes { .. } => "kubernetes",
SecretSource::Hardware { .. } => "hardware",
SecretSource::Custom { .. } => "custom",
_ => "unknown",
}
}
}
impl SecretAccessEvent {
pub fn new(
credential_name: impl Into<String>,
source: SecretSource,
outcome: SecretAccessOutcome,
timestamp_ms: u64,
) -> Self {
Self {
credential_name: credential_name.into(),
source,
outcome,
timestamp_ms,
lease_id: None,
lease_ttl_secs: None,
reason: None,
workflow_id: None,
agent_id: None,
trace_id: None,
}
}
}