pub struct PluginSourceConfig {
pub url: String,
pub digest: String,
pub signature: Option<String>,
pub public_key: Option<String>,
pub cache_path: Option<String>,
}Expand description
SCALE-12 (#192)/DW-165: remote/signed plugin source configuration.
The gateway resolves the .wasm artifact at every publish: cache
lookup first, then a download from url on a miss, then SHA-256
digest verification (mandatory) and Ed25519 signature
verification (when configured) — only then is the artifact loaded.
Resolution failures are fail-closed per plugin (Crashed at publish,
its routes answer 500), never a partial load.
Fields§
§url: StringThe registry URL to fetch the .wasm artifact from. Must be
https://; fetched with one HTTP/1.1 GET (redirects are not
followed — configure the artifact’s final URL). oci://
references are not supported in this version: publish the
artifact over https or pre-fetch it with dwara-cli plugin install and reference the local file with wasm.
digest: StringExpected SHA-256 digest of the artifact, hex-encoded (64 chars, case-insensitive). Verified against the cached AND the downloaded bytes before loading; a mismatch fails the plugin (never a partial load). Required — there are no unsigned remote artifacts (digest-pinning is the floor; signatures are the ceiling).
signature: Option<String>Optional Ed25519 signature over the artifact bytes, hex-encoded
(64 bytes / 128 chars). When set, it must verify against
public_key and, when plugin_registry.public_keys pins
keys, against a pinned key too. Absent means digest-only
verification — rejected when the registry pins public keys.
public_key: Option<String>Ed25519 public key (32 bytes, hex-encoded) for signature
verification. Required when signature is set unless
plugin_registry.public_keys pins keys. A public_key set
WITHOUT a signature is rejected (a key that verifies nothing
is a config mistake — sign the artifact or remove the key).
cache_path: Option<String>Local cache path for the resolved artifact. When absent, the
artifact is cached content-addressed as
<cache_dir>/<digest>.wasm (plugin_registry.cache_dir,
default ./plugin-cache). When set, the path must be a
RELATIVE path under the cache dir with no .. parent
segments (containment: the resolver creates directories and
writes artifact bytes at this path, so it must not be able to
point outside the cache). The cached file is re-verified
(digest and signature) on every publish; a cached file that
does not match the pinned digest fails closed instead of being
silently re-fetched.
Implementations§
Source§impl PluginSourceConfig
impl PluginSourceConfig
Sourcepub fn cache_path_violation(cache_path: &str) -> Option<&'static str>
pub fn cache_path_violation(cache_path: &str) -> Option<&'static str>
Why a cache_path value violates cache containment, or None
when it is acceptable. The rule is deliberately simple: a
non-empty RELATIVE path with no .. parent segments — the
resolver creates directories and writes artifact bytes at this
path, so it must stay inside plugin_registry.cache_dir.
Shared by snapshot validation (the operator-facing, earliest
rejection) and the resolver (defense in depth); lives here
because both may import config and nothing below it.
Trait Implementations§
Source§impl Clone for PluginSourceConfig
impl Clone for PluginSourceConfig
Source§fn clone(&self) -> PluginSourceConfig
fn clone(&self) -> PluginSourceConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PluginSourceConfig
impl Debug for PluginSourceConfig
Source§impl<'de> Deserialize<'de> for PluginSourceConfig
impl<'de> Deserialize<'de> for PluginSourceConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for PluginSourceConfig
impl JsonSchema for PluginSourceConfig
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreSource§impl PartialEq for PluginSourceConfig
impl PartialEq for PluginSourceConfig
Source§impl Serialize for PluginSourceConfig
impl Serialize for PluginSourceConfig
impl StructuralPartialEq for PluginSourceConfig
Auto Trait Implementations§
impl Freeze for PluginSourceConfig
impl RefUnwindSafe for PluginSourceConfig
impl Send for PluginSourceConfig
impl Sync for PluginSourceConfig
impl Unpin for PluginSourceConfig
impl UnwindSafe for PluginSourceConfig
Blanket Implementations§
§impl<T> AnyExt for T
impl<T> AnyExt for T
§fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
fn downcast_ref<T>(this: &Self) -> Option<&T>where
T: Any,
T behind reference§fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>where
T: Any,
T behind mutable reference§fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>where
T: Any,
T behind Rc pointer§fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>where
T: Any,
T behind Arc pointer§fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>where
T: Any,
T behind Box pointer§fn downcast_move<T>(this: Self) -> Option<T>
fn downcast_move<T>(this: Self) -> Option<T>
Self to T,
useful only in generic context as a workaround for specializationSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
impl<T, X> CoerceTo<T> for Xwhere
T: CoerceFrom<X> + ?Sized,
fn coerce_rc_to(self: Rc<X>) -> Rc<T>
fn coerce_box_to(self: Box<X>) -> Box<T>
fn coerce_ref_to(&self) -> &T
fn coerce_mut_to(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more