Skip to main content

spacedb_access/
directory.rs

1//! The key-directory seam: DID → published verification key.
2//!
3//! This is the open-core boundary for identity. A verifier needs the issuer's
4//! published key to check a capability's signature; how that key is discovered is
5//! an operator concern. This crate ships [`MemKeyDirectory`]; MATA implements the
6//! seam over its `did:mata` / IAMHUMAN directory (Supabase-hosted DID documents).
7
8use std::collections::HashMap;
9use std::sync::RwLock;
10
11use crate::error::{AccessError, AccessResult};
12use crate::identity::{Did, Identity};
13
14/// Resolves a [`Did`] to its published SEC1 verification key.
15pub trait KeyDirectory {
16    /// The published key bytes for `did`, or `None` if the DID is unknown
17    /// (an unknown issuer is a [`Deny`](crate::Decision), not an error).
18    fn published_key(&self, did: &Did) -> AccessResult<Option<Vec<u8>>>;
19}
20
21/// In-memory DID → key directory, for tests and single-machine use.
22#[derive(Default)]
23pub struct MemKeyDirectory {
24    keys: RwLock<HashMap<Did, Vec<u8>>>,
25}
26
27impl MemKeyDirectory {
28    pub fn new() -> Self {
29        Self::default()
30    }
31
32    /// Publish an identity's DID → public key binding.
33    pub fn publish(&self, identity: &Identity) -> AccessResult<()> {
34        self.publish_key(identity.did().clone(), identity.public_key().to_vec())
35    }
36
37    /// Publish a raw DID → SEC1 key binding.
38    pub fn publish_key(&self, did: Did, public_sec1: Vec<u8>) -> AccessResult<()> {
39        self.keys
40            .write()
41            .map_err(|_| AccessError::Directory("lock poisoned".into()))?
42            .insert(did, public_sec1);
43        Ok(())
44    }
45}
46
47impl KeyDirectory for MemKeyDirectory {
48    fn published_key(&self, did: &Did) -> AccessResult<Option<Vec<u8>>> {
49        Ok(self
50            .keys
51            .read()
52            .map_err(|_| AccessError::Directory("lock poisoned".into()))?
53            .get(did)
54            .cloned())
55    }
56}