Add resource secret epoch metadata
This commit is contained in:
parent
ce260625d6
commit
a05112e6a2
12 changed files with 287 additions and 13 deletions
|
|
@ -21,6 +21,7 @@ geth-iroh = { path = "../geth-iroh" }
|
|||
geth-keychain = { path = "../geth-keychain" }
|
||||
geth-kv = { path = "../geth-kv" }
|
||||
geth-resource = { path = "../geth-resource" }
|
||||
geth-secrets = { path = "../geth-secrets" }
|
||||
geth-ssh-identity = { path = "../geth-ssh-identity" }
|
||||
geth-store = { path = "../geth-store" }
|
||||
geth-types = { path = "../geth-types" }
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use geth_iroh::{EndpointStatus, GethIrohConfig, GethIrohEndpoint, GethRelayMode}
|
|||
use geth_keychain::{KeychainOp, KeychainOpKind};
|
||||
use geth_kv::{KvEntry, KvResource};
|
||||
use geth_resource::ResourceDescriptor;
|
||||
use geth_secrets::ResourceMasterSecret;
|
||||
use geth_ssh_identity::{
|
||||
SshCertApproval, SshCertKind, SshCertRequest, SshCertRequestStatus, SshCertificateRecord,
|
||||
SshRevocationEntry, SshRevocationKind, build_ssh_cert_sign_command, cert_request_id,
|
||||
|
|
@ -21,7 +22,8 @@ use geth_ssh_identity::{
|
|||
};
|
||||
use geth_store::{
|
||||
Store, StoredAuthOp, StoredDbResource, StoredDocumentResource, StoredKeychainOp, StoredKvEntry,
|
||||
StoredKvStore, StoredResource, StoredSshCertRequest, StoredSshCertificate, StoredSshRevocation,
|
||||
StoredKvStore, StoredResource, StoredResourceSecret, StoredSshCertRequest,
|
||||
StoredSshCertificate, StoredSshRevocation,
|
||||
};
|
||||
use geth_types::{
|
||||
AuthOpId, Capability, KeyId, NodeId, PrincipalId, ResourceId, ResourceKind, ResourceName,
|
||||
|
|
@ -67,6 +69,8 @@ pub enum NodeError {
|
|||
InvalidDocumentName(String),
|
||||
#[error("document not found: {0}")]
|
||||
DocumentNotFound(String),
|
||||
#[error("resource not found: {0}")]
|
||||
ResourceNotFound(String),
|
||||
#[error("invalid ssh certificate kind: {0}")]
|
||||
InvalidSshCertKind(String),
|
||||
#[error("invalid ssh certificate request status: {0}")]
|
||||
|
|
@ -335,6 +339,27 @@ pub fn handle_request(
|
|||
nodes: view.nodes.len(),
|
||||
}))
|
||||
}
|
||||
ControlRequest::SecretStatus => Ok(ControlResponse::SecretStatus {
|
||||
secrets: store
|
||||
.list_resource_secrets()?
|
||||
.into_iter()
|
||||
.map(resource_secret_from_stored)
|
||||
.collect(),
|
||||
}),
|
||||
ControlRequest::SecretCreate { resource } => {
|
||||
ensure_resource_exists(&store, &resource)?;
|
||||
let secret = create_resource_secret(&store, &resource, 1)?;
|
||||
Ok(ControlResponse::SecretCreated { secret })
|
||||
}
|
||||
ControlRequest::SecretRotate { resource } => {
|
||||
ensure_resource_exists(&store, &resource)?;
|
||||
let next_epoch = store
|
||||
.latest_resource_secret(&resource)?
|
||||
.map(|secret| secret.epoch + 1)
|
||||
.unwrap_or(1);
|
||||
let secret = create_resource_secret(&store, &resource, next_epoch)?;
|
||||
Ok(ControlResponse::SecretCreated { secret })
|
||||
}
|
||||
ControlRequest::AuthExplain {
|
||||
subject,
|
||||
resource,
|
||||
|
|
@ -764,6 +789,48 @@ fn document_resource_from_stored(stored: &StoredDocumentResource) -> DocumentRes
|
|||
}
|
||||
}
|
||||
|
||||
fn ensure_resource_exists(store: &Store, resource_id: &str) -> Result<(), NodeError> {
|
||||
if store
|
||||
.list_resources()?
|
||||
.into_iter()
|
||||
.any(|resource| resource.resource_id == resource_id)
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(NodeError::ResourceNotFound(resource_id.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn create_resource_secret(
|
||||
store: &Store,
|
||||
resource_id: &str,
|
||||
epoch: u64,
|
||||
) -> Result<ResourceMasterSecret, NodeError> {
|
||||
let created_at = UnixMillis(geth_store::now_ms());
|
||||
let secret_id = format!(
|
||||
"secret:{}",
|
||||
geth_crypto::blake3_hex(format!("{resource_id}\0{epoch}\0{}", created_at.0).as_bytes())
|
||||
);
|
||||
let stored = StoredResourceSecret {
|
||||
secret_id,
|
||||
resource_id: resource_id.to_owned(),
|
||||
epoch,
|
||||
status: "active".to_owned(),
|
||||
created_at_ms: created_at.0,
|
||||
};
|
||||
store.insert_resource_secret(&stored)?;
|
||||
Ok(resource_secret_from_stored(stored))
|
||||
}
|
||||
|
||||
fn resource_secret_from_stored(stored: StoredResourceSecret) -> ResourceMasterSecret {
|
||||
ResourceMasterSecret {
|
||||
id: stored.secret_id.into(),
|
||||
resource: stored.resource_id.into(),
|
||||
epoch: stored.epoch,
|
||||
created_at: UnixMillis(stored.created_at_ms),
|
||||
}
|
||||
}
|
||||
|
||||
fn store_auth_op(store: &Store, op: &AuthOp) -> Result<(), NodeError> {
|
||||
store.insert_auth_op(&StoredAuthOp {
|
||||
op_id: op.id.to_string(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue