Crate Layout
The project is organized as a Cargo workspace with libraries (traits and logic) and example runtimes (executable targets).
crates/
├── core/ (multistore) # Runtime-agnostic: traits, S3 parsing, SigV4, registries
├── metering/ (multistore-metering) # Usage metering and quota enforcement middleware
├── sts/ (multistore-sts) # OIDC/STS token exchange (AssumeRoleWithWebIdentity)
├── oidc-provider/ (multistore-oidc-provider) # Outbound OIDC provider (JWT signing, JWKS, exchange)
├── static-config/ (multistore-static-config) # Static config provider (buckets/roles/credentials)
├── path-mapping/ (multistore-path-mapping) # Hierarchical path-based backend resolution
└── cf-workers/ (multistore-cf-workers) # Cloudflare Workers runtime library (WASM)
examples/
├── server/ (multistore-server) # Tokio/Hyper for container deployments
├── lambda/ (multistore-lambda) # AWS Lambda runtime
└── cf-workers/ (multistore-cf-workers-example) # Cloudflare Workers example for edge deploymentsCrate Responsibilities
multistore
The runtime-agnostic core. Contains:
ProxyGateway— Router-based dispatch + S3 parsing + identity resolution + two-phase request dispatch (handle_request()→GatewayResponse)Router— Path-based route matching viamatchitfor efficient pre-dispatchRouteHandlertrait — Pluggable request interceptionMiddlewaretrait — Composable post-auth middleware for dispatch, withafter_dispatchfor post-response observationBucketRegistrytrait — Bucket lookup, authorization, and listingCredentialRegistrytrait — Credential and role storageProxyBackendtrait — Runtime abstraction for store/signer/raw HTTP; itsforward()method provides backend HTTP transport, and the core orchestrates the call so middleware can observe response metadata- S3 request parsing, XML response building, list prefix rewriting
- SigV4 signature verification
- Sealed session token encryption/decryption
- Type definitions (
BucketConfig,RoleConfig,AccessScope,TemporaryCredentials,BackendCredentials, etc.) — includingBackendCredentials, the backend credential value type the outbound exchange produces and injects into aBucketConfig
Feature flags:
azure— Azure Blob Storage supportgcp— Google Cloud Storage support
multistore-metering
Usage metering and quota enforcement middleware:
MeteringMiddleware<Q, U>— Pre-dispatch quota checking + post-dispatch usage recording via theMiddlewaretraitQuotaCheckertrait — Pre-dispatch quota enforcement; returnErr(QuotaExceeded)to reject with HTTP 429UsageRecordertrait — Post-dispatch operation recording for usage trackingUsageEvent— Operation metadata passed to the recorder (identity, operation, bytes, status)NoopQuotaChecker/NoopRecorder— Convenience no-op implementations for when only one side is needed
multistore-sts
OIDC token exchange implementing AssumeRoleWithWebIdentity:
StsRouterExt— registers a closure that intercepts STS requests on theRouter- JWT decoding and validation (RS256)
- JWKS fetching and caching
- Trust policy evaluation (issuer, audience, subject conditions)
- Temporary credential minting with scope template variables
multistore-oidc-provider
Outbound OIDC identity provider for backend authentication:
OidcRouterExt— registers closures for.well-knowndiscovery endpoints on theRouter- RSA JWT signing (
JwtSigner) - JWKS endpoint serving
- OpenID Connect discovery document
- AWS STS credential exchange — the
AssumeRoleWithWebIdentityrequest build + XML parse, plus theAwsBackendAuthmiddleware that drives it - Credential caching
multistore-static-config
The built-in configuration provider (StaticProvider) — the only config provider shipped today:
- Loads buckets, roles, and credentials from a single TOML or JSON file
- Implements
BucketRegistryandCredentialRegistryover the parsed config - Suitable for static deployments where the bucket/role/credential set is known ahead of time
multistore-path-mapping
Hierarchical path-based backend resolution:
- Maps request paths of the form
/{account}/{product}/{key}to a per-(account, product) backend - Resolves the backend for each account/product pair from the configured mapping
multistore-server
The native server runtime (in examples/server/):
- Tokio/Hyper HTTP server
ServerBackendimplementingProxyBackendwith reqwest- Streaming via hyper
Incomingbodies and reqwestbytes_stream() - Wires
ProxyGatewaywith aRouter(OIDC discovery + STS routes) - CLI argument parsing (
--config,--listen,--domain,--sts-config)
multistore-cf-workers
The reusable Cloudflare Workers WASM runtime library (in crates/cf-workers/):
WorkerBackendimplementingProxyBackendwithweb_sys::fetchRequestParts— extracts owned HTTP metadata fromweb_sys::Requestand providesas_request_info()for gateway dispatchGatewayResponseExt— extension trait for convertingGatewayResponsetoweb_sys::Responsevia.into_web_sys()JsBody— zero-copy body wrapper aroundweb_sys::ReadableStreamWsHeaders— newtype aroundweb_sys::HeaderswithFrom<&HeaderMap>(works around orphan rules)FetchConnectorbridgingobject_storeHTTP to Workers Fetch API
WARNING
This crate is excluded from the workspace default-members because WASM types are !Send and won't compile on native targets. Always build with --target wasm32-unknown-unknown.
multistore-cf-workers-example
The Cloudflare Workers example deployment (in examples/cf-workers/). It wires the multistore-cf-workers library together with config, STS, OIDC, and metering, and adds example-only symbols:
BandwidthMeterDurable Object — per-(bucket, identity) sliding-window byte counterDoBandwidthMeterimplementingQuotaChecker+UsageRecordervia theBandwidthMeterDOCfRateLimitermiddleware for request-rate limiting via CF Rate Limiting API- Config loading from env vars (
PROXY_CONFIG,BANDWIDTH_QUOTAS)
Dependency Flow
Libraries define trait abstractions. Runtimes implement ProxyBackend with platform-native primitives, build a Router with extension traits, and convert the two-variant GatewayResponse into a platform response (e.g. via GatewayResponseExt::into_web_sys() on Workers).