Add durable credential registry and secret lifecycle
This commit is contained in:
parent
9b6c3dc71f
commit
ac2289bd0a
1 changed files with 4499 additions and 4 deletions
62
crates/remora-credentials/src/resolve.rs
Normal file
62
crates/remora-credentials/src/resolve.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue