pub struct RegistryServer<S: RegistryStore, L: RateLimiter = NoopRateLimiter> { /* private fields */ }Expand description
Logical registry handler over an arbitrary RegistryStore.
L is the rate-limiting policy (RFC-ACDP-0008 §4.3). The default
NoopRateLimiter accepts every publish; operators that need a
real limiter construct via Self::with_rate_limiter.
Implementations§
Source§impl<S: RegistryStore> RegistryServer<S, NoopRateLimiter>
impl<S: RegistryStore> RegistryServer<S, NoopRateLimiter>
Sourcepub fn try_new(
store: S,
caps: CapabilitiesDocument,
authority: impl Into<String>,
) -> Result<Self, AcdpError>
pub fn try_new( store: S, caps: CapabilitiesDocument, authority: impl Into<String>, ) -> Result<Self, AcdpError>
Production constructor.
Validates that authority is a bare lowercase DNS hostname,
validates capabilities against RFC-ACDP-0007 §3, and enforces that
caps.registry_did equals did:web:<authority> (per
RFC-ACDP-0006 §4.1 step 3 — the registry’s DID document binds it
to the authority it claims).
A host:port, scheme-prefixed, or uppercase authority is rejected:
the server uses authority to mint ctx_id (acdp://<authority>/…)
and origin_registry, and a colon or slash there violates the
acdp:// URI authority rule (RFC-ACDP-0002 §3.1). For host:port
test setups use Self::try_new_for_test_authority.
Source§impl<S: RegistryStore, L: RateLimiter> RegistryServer<S, L>
impl<S: RegistryStore, L: RateLimiter> RegistryServer<S, L>
Sourcepub fn with_rate_limiter<L2: RateLimiter>(
self,
limiter: L2,
) -> RegistryServer<S, L2>
pub fn with_rate_limiter<L2: RateLimiter>( self, limiter: L2, ) -> RegistryServer<S, L2>
Replace the rate-limiting policy (RFC-ACDP-0008 §4.3).
Sourcepub fn with_receipt_signer(
self,
signer: ReceiptSigner,
) -> Result<Self, AcdpError>
pub fn with_receipt_signer( self, signer: ReceiptSigner, ) -> Result<Self, AcdpError>
Configure receipt minting (ACDP 0.2, RFC-ACDP-0010). Every subsequent verified publish mints a registry-signed receipt atomically with persistence, returns it in the publish response, and serves it on retrieval.
Also advertises the acdp-registry-receipts profile — a
registry without a signing key MUST NOT advertise it, so the
profile is bound to this call rather than to raw capabilities
input. Fails if the signer’s registry_did does not match
caps.registry_did (a receipt minted under a foreign DID would
fail every consumer’s serving-authority cross-check).
Note: Self::publish_unverified_for_tests never mints — the
producer key is not resolved on that path, so a fingerprint
attestation would be false.
Sourcepub fn store(&self) -> &S
pub fn store(&self) -> &S
Borrow the underlying store. Useful for tests that want to inspect side-effects directly.
Sourcepub fn capabilities(&self) -> &CapabilitiesDocument
pub fn capabilities(&self) -> &CapabilitiesDocument
GET /.well-known/acdp.json.
Sourcepub fn publish_verified_did_key(
&self,
req: &PublishRequest,
idempotency_key: Option<&str>,
) -> Result<PublishResponse, AcdpError>
pub fn publish_verified_did_key( &self, req: &PublishRequest, idempotency_key: Option<&str>, ) -> Result<PublishResponse, AcdpError>
RFC-conformant publish for did:key producers — no resolver.
Runs the same RFC-ACDP-0003 §2.1 pipeline as
[Self::publish_verified], but performs steps 7–8 via the pure
did:key verifier
(acdp_verify::verify_publish_request_signature_offline),
so it is available without the client feature. Rejects
did:web (and any other method) producers with
key_resolution_failed — those need the resolver-backed
[Self::publish_verified].
The capabilities gate still applies: the request is refused
unless supported_did_methods includes "did:key".
Sourcepub fn publish_verified_did_key_in_tenant(
&self,
req: &PublishRequest,
idempotency_key: Option<&str>,
tenant: Option<&str>,
) -> Result<PublishResponse, AcdpError>
pub fn publish_verified_did_key_in_tenant( &self, req: &PublishRequest, idempotency_key: Option<&str>, tenant: Option<&str>, ) -> Result<PublishResponse, AcdpError>
Like Self::publish_verified_did_key but binds the publish to a
tenant so a multi-tenant store persists tenant_id atomically with
the context row — the same contract as
[Self::publish_verified_in_tenant]. tenant = None is identical
to Self::publish_verified_did_key.
Sourcepub fn retrieve(
&self,
ctx_id: &CtxId,
requester: Option<&AgentDid>,
) -> Result<Option<FullContext>, AcdpError>
pub fn retrieve( &self, ctx_id: &CtxId, requester: Option<&AgentDid>, ) -> Result<Option<FullContext>, AcdpError>
GET /contexts/{ctx_id}.
Applies the RFC-ACDP-0008 §4.5 disclosure rules:
| Visibility | Authorized requester for retrieval |
|---|---|
public | anyone (when caps.anonymous_public_reads is true) |
restricted | producer (agent_id) or any DID in audience |
private | producer (agent_id) or any DID in audience |
Returns Ok(None) (not Err) for unauthorized callers — prevents
existence leakage via error codes.
Sourcepub fn retrieve_body(
&self,
ctx_id: &CtxId,
requester: Option<&AgentDid>,
) -> Result<Option<Body>, AcdpError>
pub fn retrieve_body( &self, ctx_id: &CtxId, requester: Option<&AgentDid>, ) -> Result<Option<Body>, AcdpError>
GET /contexts/{ctx_id}/body. See Self::retrieve for visibility rules.
Sourcepub fn lineage(
&self,
lineage_id: &LineageId,
requester: Option<&AgentDid>,
) -> Result<Vec<FullContext>, AcdpError>
pub fn lineage( &self, lineage_id: &LineageId, requester: Option<&AgentDid>, ) -> Result<Vec<FullContext>, AcdpError>
GET /lineages/{lineage_id}.
BUG-03: applies the same visibility filter as retrieve. A
caller who knows or guesses a lineage_id must not be able to
surface restricted or private bodies through the lineage
endpoint when retrieve(ctx_id, requester) would deny them.
Sourcepub fn current(
&self,
lineage_id: &LineageId,
requester: Option<&AgentDid>,
) -> Result<Option<FullContext>, AcdpError>
pub fn current( &self, lineage_id: &LineageId, requester: Option<&AgentDid>, ) -> Result<Option<FullContext>, AcdpError>
GET /lineages/{lineage_id}/current.
BUG-03 + BUG-04: returns the newest non-Superseded version
visible to the requester. None when the lineage is unknown,
when every version is superseded (RFC-ACDP-0004 §5), or when no
visible version exists.
Sourcepub fn search(
&self,
params: &SearchParams,
requester: Option<&AgentDid>,
) -> Result<SearchResponse, AcdpError>
pub fn search( &self, params: &SearchParams, requester: Option<&AgentDid>, ) -> Result<SearchResponse, AcdpError>
GET /contexts/search.
Applies the RFC-ACDP-0008 §4.5 search disclosure rules (note the asymmetry vs retrieval): private contexts surface in search only to their producer (audience members must already know the ctx_id).
When caps.anonymous_public_reads is false, an anonymous search
request is rejected outright with AcdpError::NotAuthorized
(HTTP 403) rather than returning an empty 200. An empty result
set would still leak the registry’s existence and confirm that
the keyword query ran; the required response is not_authorized
(RFC-ACDP-0005 §2.5.5, RFC-ACDP-0008 §6.3, fixture vis-009).