62 lines
1.8 KiB
Rust
62 lines
1.8 KiB
Rust
|
|
use remora_domain::ports::{ActiveCredentialGrant, CredentialResolver};
|
||
|
|
|
||
|
|
use crate::error::CredentialError;
|
||
|
|
use crate::registry::CredentialRegistry;
|
||
|
|
use crate::types::SecretMaterial;
|
||
|
|
use crate::vault::VaultClient;
|
||
|
|
|
||
|
|
/// Grant-bound credential resolver.
|
||
|
|
///
|
||
|
|
/// Every resolve reloads durable execution-grant pin state. Unknown, revoked,
|
||
|
|
/// or destroyed pins fail closed. Callers cannot resolve by forging bare
|
||
|
|
/// credential/version IDs.
|
||
|
|
#[derive(Clone, Debug)]
|
||
|
|
pub struct GrantBoundResolver {
|
||
|
|
registry: CredentialRegistry,
|
||
|
|
vault: VaultClient,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl GrantBoundResolver {
|
||
|
|
#[must_use]
|
||
|
|
pub fn new(registry: CredentialRegistry, vault: VaultClient) -> Self {
|
||
|
|
Self { registry, vault }
|
||
|
|
}
|
||
|
|
|
||
|
|
pub async fn resolve_access(
|
||
|
|
&self,
|
||
|
|
access: &ActiveCredentialGrant,
|
||
|
|
) -> Result<SecretMaterial, CredentialError> {
|
||
|
|
let pin = self
|
||
|
|
.registry
|
||
|
|
.load_active_grant_pin(access.grant_id())
|
||
|
|
.await?
|
||
|
|
.ok_or(CredentialError::GrantInactive)?;
|
||
|
|
let coord = self
|
||
|
|
.registry
|
||
|
|
.load_version_coord(&pin.credential_id, &pin.version_id)
|
||
|
|
.await?
|
||
|
|
.ok_or(CredentialError::Unresolvable)?;
|
||
|
|
if coord.destroyed {
|
||
|
|
return Err(CredentialError::Unresolvable);
|
||
|
|
}
|
||
|
|
self.vault
|
||
|
|
.get_version(
|
||
|
|
&coord.secret_mount,
|
||
|
|
&coord.secret_path,
|
||
|
|
coord.vault_kv_version,
|
||
|
|
)
|
||
|
|
.await
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl CredentialResolver for GrantBoundResolver {
|
||
|
|
type Error = CredentialError;
|
||
|
|
type Secret = SecretMaterial;
|
||
|
|
|
||
|
|
fn resolve(
|
||
|
|
&self,
|
||
|
|
access: &ActiveCredentialGrant,
|
||
|
|
) -> impl std::future::Future<Output = Result<Self::Secret, Self::Error>> + Send {
|
||
|
|
self.resolve_access(access)
|
||
|
|
}
|
||
|
|
}
|