MARS documentation
Rust librariesmars-server

mars-server · config

Public declarations and documentation for mars-server::config.

Package: mars-server · Workspace version: 0.1.0 · Module: config

This reference follows declared modules and public syntax, including public implementation methods. Function bodies and constant values are omitted. Feature conditions are retained. Private-module re-exports and trait resolution require the compiler; not every declaration is a root import.

config::DeploymentEnv

Deployment environment for the MARS registry server.

Parsed from the MARS_ENV environment variable. Controls fail-fast production safety checks (see validate_production_config in main.rs).

  • Development (default) — relaxed checks, localhost defaults allowed.
  • Staging — relaxed checks; primarily used for tagging deployments.
  • Production — strict checks; refuses to start with localhost defaults for Sigil RPC or federation peer URLs.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum DeploymentEnv {
    #[default]
    Development,
    Staging,
    Production,
}

Source line: 22.

config::DeploymentEnv::parse

Parse a [DeploymentEnv] from a string, case-insensitively.

Recognized values:

  • "development" / "dev" -> [DeploymentEnv::Development]
  • "staging" / "stage" -> [DeploymentEnv::Staging]
  • "production" / "prod" -> [DeploymentEnv::Production]

Anything else (including the empty string) returns [DeploymentEnv::Development] so misconfiguration cannot silently upgrade a deployment to production.

pub fn parse(raw: &str) -> Self;

Source line: 40.

config::DeploymentEnv::from_env

Read [DeploymentEnv] from the MARS_ENV environment variable.

Returns [DeploymentEnv::Development] when the variable is unset.

pub fn from_env() -> Self;

Source line: 51.

config::DeploymentEnv::as_str

Human-readable label for logs.

pub fn as_str(&self) -> &'static str;

Source line: 59.

config::TrustKeyAlgorithm

Supported algorithms for operator-pinned trust keys.

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TrustKeyAlgorithm {
    /// Ed25519 verification key encoded as 32-byte hexadecimal.
    Ed25519,
}

Source line: 70.

config::PinnedPublisherKey

An operator-pinned publisher verification key.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PinnedPublisherKey {
/// Publisher DID controlled by this key.

pub publisher_did: String,
/// Full DID URL, including key fragment.

pub key_id: String,
/// Signature algorithm.

pub algorithm: TrustKeyAlgorithm,
/// Lower- or uppercase hexadecimal encoding of the 32-byte public key.

pub public_key_hex: String
}

Source line: 78.

config::PinnedPeerKey

An operator-pinned federation peer verification key.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PinnedPeerKey {
/// Registry DID controlled by this key.

pub peer_did: String,
/// Full DID URL, including key fragment.

pub key_id: String,
/// Signature algorithm.

pub algorithm: TrustKeyAlgorithm,
/// Lower- or uppercase hexadecimal encoding of the 32-byte public key.

pub public_key_hex: String
}

Source line: 92.

config::TrustConfig

Operator trust roots and bootstrap policy.

Optional policy flags have environment-aware defaults: production requires publisher pins and disables self-signed HMR/MHR bootstrap, while local development preserves the explicit bootstrap workflow.

#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TrustConfig {
/// Override whether at least one publisher pin is required.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub require_pinned_publishers: Option<bool>,
/// Override whether peer pins are required when federation is enabled.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub require_pinned_peers: Option<bool>,
/// Override whether a new HMR/MHR may bootstrap from its embedded key.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub allow_self_signed_bootstrap: Option<bool>,
/// Trusted publisher keys, resolved before registry-stored keys.

#[serde(default)]
pub publisher_keys: Vec<PinnedPublisherKey>,
/// Trusted federation peer keys, resolved before registry-stored keys.

#[serde(default)]
pub peer_keys: Vec<PinnedPeerKey>
}

Source line: 110.

config::TrustConfig::requires_pinned_publishers

Whether publisher pins are required after environment defaults.

pub fn requires_pinned_publishers(&self, env: DeploymentEnv) -> bool;

Source line: 130.

config::TrustConfig::requires_pinned_peers

Whether peer pins are required after environment defaults.

pub fn requires_pinned_peers(&self, env: DeploymentEnv, federation_enabled: bool) -> bool;

Source line: 136.

config::TrustConfig::allows_self_signed_bootstrap

Whether self-signed root bootstrap is allowed after environment defaults.

pub fn allows_self_signed_bootstrap(&self, env: DeploymentEnv) -> bool;

Source line: 142.

config::AuthConfig

Authentication profiles and server-controlled expiry policy.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthConfig {
/// Profiles accepted by the credential registry.

#[serde(default = "default_enabled_auth_profiles")]
pub enabled_profiles: Vec<AuthProfile>,
/// Session lifetime in milliseconds.

#[serde(default = "default_session_ttl_ms")]
pub session_ttl_ms: i64,
/// Challenge lifetime in milliseconds.

#[serde(default = "default_challenge_ttl_ms")]
pub challenge_ttl_ms: i64,
/// Server-pinned SIWS origin. Client requests may omit it or repeat this

/// exact value, but cannot select a different signing origin.

#[serde(default = "default_siws_origin")]
pub expected_siws_origin: String
}

Source line: 151.

config::AuthConfig::validate

Validate server-controlled authentication lifetimes.

pub fn validate(&self) -> Result<(), crate::ServerError>;

Source line: 180.

config::DatabaseConfig

PostgreSQL pool, connection, session, and maintenance bounds.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DatabaseConfig {
/// Minimum warm connections retained by the pool.

#[serde(default = "default_min_db_connections")]
pub min_connections: u32,
/// Maximum connections retained by the pool.

#[serde(default = "default_max_db_connections")]
pub max_connections: u32,
/// Maximum wait for a pooled connection.

#[serde(default = "default_db_acquire_timeout_ms")]
pub acquire_timeout_ms: u64,
/// Maximum wait for initial pool establishment.

#[serde(default = "default_db_connect_timeout_ms")]
pub connect_timeout_ms: u64,
/// Maximum idle lifetime for connections above the minimum.

#[serde(default = "default_db_idle_timeout_ms")]
pub idle_timeout_ms: u64,
/// Maximum lifetime for one physical database connection.

#[serde(default = "default_db_max_lifetime_ms")]
pub max_lifetime_ms: u64,
/// PostgreSQL statement timeout installed on every connection.

#[serde(default = "default_db_statement_timeout_ms")]
pub statement_timeout_ms: u64,
/// PostgreSQL lock wait timeout installed on every connection.

#[serde(default = "default_db_lock_timeout_ms")]
pub lock_timeout_ms: u64,
/// PostgreSQL idle-in-transaction timeout installed on every connection.

#[serde(default = "default_db_idle_in_transaction_timeout_ms")]
pub idle_in_transaction_session_timeout_ms: u64,
/// Interval between out-of-band retention cleanup passes.

#[serde(default = "default_db_maintenance_interval_ms")]
pub maintenance_interval_ms: u64
}

Source line: 236.

config::DatabaseConfig::validate

Validate all bounds before opening a connection or binding a listener.

pub fn validate(&self) -> Result<(), crate::ServerError>;

Source line: 271.

config::SearchConfig

Search pagination integrity and expiry policy.

HMAC key fields may be deserialized from a protected config source, but serialization and debug formatting never expose key material. Environment variables override file values during server startup.

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SearchConfig {
/// Maximum lifetime of an issued pagination chain.

#[serde(default = "default_search_cursor_max_age_seconds")]
pub cursor_max_age_seconds: u64,
/// Opt in to the deterministic development/test key.

#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub use_insecure_test_cursor_key: bool
}

Source line: 385.

config::SearchConfig::with_cursor_keys

Construct typed search configuration from already validated key types.

pub fn with_cursor_keys(
        active_cursor_hmac_key: crate::search::SearchCursorKey,
        previous_cursor_hmac_key: Option<crate::search::PreviousSearchCursorKey>,
        cursor_max_age_seconds: u64,
    ) -> Self;

Source line: 417.

config::SearchConfig::apply_environment

Apply secret and lifetime overrides from the process environment.

Supported variables are MARS_SEARCH_CURSOR_HMAC_KEY, MARS_SEARCH_CURSOR_PREVIOUS_HMAC_KEY, MARS_SEARCH_CURSOR_PREVIOUS_HMAC_KEY_EXPIRES_AT, MARS_SEARCH_CURSOR_MAX_AGE_SECONDS, and MARS_SEARCH_USE_INSECURE_TEST_CURSOR_KEY.

pub fn apply_environment(&mut self) -> Result<(), crate::ServerError>;

Source line: 443.

config::SearchConfig::cursor_codec

Build the runtime codec after enforcing environment-specific policy.

pub fn cursor_codec(
        &self,
        env: DeploymentEnv,
    ) -> Result<crate::search::SearchCursorCodec, crate::ServerError>;

Source line: 489.

config::SearchConfig::clear_cursor_hmac_keys

Remove key copies once the runtime codec has been assembled.

pub fn clear_cursor_hmac_keys(&mut self);

Source line: 558.

config::ServerConfig

Top-level configuration for the MARS registry server.

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerConfig {
/// Deployment environment. Not part of the on-disk config — parsed at

/// startup from the `MARS_ENV` environment variable.

#[serde(skip)]
pub env: DeploymentEnv,
/// Address to bind the HTTP server.

pub listen_addr: SocketAddr,
/// Registry DID (e.g. `"did:oas:registry:mars-1"`).

pub registry_did: String,
/// Maximum entries per discovery query page.

pub max_page_size: u64,
/// Default page size for discovery queries.

pub default_page_size: u64,
/// Search cursor integrity, rotation, and expiry policy.

#[serde(default)]
pub search: SearchConfig,
/// Retention window for authenticated mutation idempotency responses.

#[serde(default = "default_idempotency_ttl_seconds")]
pub idempotency_ttl_seconds: u64,
/// Rate limit configuration.

pub rate_limits: RateLimitConfig,
/// Federation configuration.

pub federation: FederationConfig,
/// Operator trust roots and root-record bootstrap policy.

#[serde(default)]
pub trust: TrustConfig,
/// Authentication adapters and expiry policy.

#[serde(default)]
pub auth: AuthConfig,
/// PostgreSQL connection URL for durable storage.

///

/// **Required in production.** The server refuses to start without this

/// unless `MARS_ALLOW_MEMORY_STORE=1` is set (development/CI only).

///

/// Example: `"postgres://mars:mars@localhost/mars"`

#[serde(skip_serializing_if = "Option::is_none")]
pub database_url: Option<String>,
/// PostgreSQL resource and timeout policy.

#[serde(default)]
pub database: DatabaseConfig,
/// Anchor configuration for on-chain Sigil anchoring.

#[serde(default)]
pub anchor: AnchorServerConfig,
/// Logging level (e.g. `"info"`, `"debug"`, `"warn"`).

#[serde(default = "default_log_level")]
pub log_level: String
}

Source line: 585.

config::ServerConfig::env

Return the deployment environment for this config.

pub fn env(&self) -> DeploymentEnv;

Source line: 679.

config::SigilSubmissionMode

Whether MARS only validates would-submit payloads or may submit them.

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SigilSubmissionMode {
    /// Call Sigil's no-authority simulation endpoint and retain submitted
    /// evidence without broadcasting a transaction.
    #[default]
    Shadow,
    /// Broadcast signed transactions when the emergency switch is enabled.
    Live,
}

Source line: 687.

config::SigilAnchorConfig

Live Sigil RPC and signing policy for GAL reads and anchor submissions.

Secret values are never serialized into this structure. The configured fields name environment variables loaded into zeroizing runtime buffers.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SigilAnchorConfig {
/// Credential-free JSON-RPC endpoint.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub rpc_url: Option<String>,
#[serde(default = "default_sigil_chain_id")]
pub chain_id: String,
/// OAS DID whose registered key authorizes signed anchor transactions.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub sender_did: Option<String>,
/// Environment variable containing the RPC bearer token.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub rpc_token_env: Option<String>,
/// Environment variable containing a 32-byte Ed25519 key in base64url or hex.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub signing_key_env: Option<String>,
#[serde(default = "default_sigil_request_timeout_ms")]
pub request_timeout_ms: u64,
#[serde(default = "default_sigil_connect_timeout_ms")]
pub connect_timeout_ms: u64,
#[serde(default = "default_sigil_finality_timeout_ms")]
pub finality_timeout_ms: u64,
#[serde(default = "default_sigil_max_response_bytes")]
pub max_response_bytes: usize,
#[serde(default = "default_sigil_gas_limit")]
pub gas_limit: u64,
#[serde(default = "default_sigil_gas_price")]
pub gas_price: u64,
#[serde(default)]
pub mode: SigilSubmissionMode,
/// Emergency switch. `false` prevents new live broadcasts while GAL reads,

/// shadow validation, and durable outbox records remain available.

#[serde(default)]
pub submissions_enabled: bool
}

Source line: 702.

config::SigilAnchorConfig::validate_for

pub fn validate_for(
        &self,
        env: DeploymentEnv,
        anchoring_enabled: bool,
    ) -> Result<(), crate::ServerError>;

Source line: 758.

config::AnchorServerConfig

Provider-neutral anchor policy and worker configuration.

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AnchorServerConfig {
/// Whether mutations enqueue anchor intents and a registered worker runs.

pub enabled: bool,
/// Whether public discovery requires a confirmed current anchor.

#[serde(default)]
pub required: bool,
#[serde(default = "default_anchor_batch_size")]
pub batch_size: u32,
#[serde(default = "default_anchor_lease_ms")]
pub lease_ms: u64,
#[serde(default = "default_anchor_max_attempts", alias = "retryAttempts")]
pub max_attempts: u32,
#[serde(default = "default_anchor_retry_base_ms")]
pub retry_base_ms: u64,
#[serde(default = "default_anchor_retry_max_ms")]
pub retry_max_ms: u64,
#[serde(default = "default_anchor_jitter_bps")]
pub jitter_bps: u16,
#[serde(default = "default_anchor_confirmation_poll_ms")]
pub confirmation_poll_ms: u64,
/// Time confirmed/abandoned intents remain in the hot outbox before

/// archival. Historical records and receipts remain queryable.

#[serde(default = "default_anchor_terminal_retention_ms")]
pub terminal_retention_ms: u64,
/// Maximum terminal intents moved by one maintenance transaction.

#[serde(default = "default_anchor_terminal_archive_batch_size")]
pub terminal_archive_batch_size: u32,
/// Concrete Sigil integration configuration.

#[serde(default)]
pub sigil: SigilAnchorConfig
}

Source line: 886.

config::AnchorServerConfig::validate

Validate worker and terminal-retention bounds before startup.

pub fn validate(&self, env: DeploymentEnv) -> Result<(), crate::ServerError>;

Source line: 939.

config::AnchorServerConfig::terminal_retention

Validated terminal-retention duration.

pub fn terminal_retention(&self) -> Result<chrono::Duration, crate::ServerError>;

Source line: 962.

config::AnchorServerConfig::worker_config

Convert wire/config milliseconds into the worker's validated durations.

pub fn worker_config(&self) -> Result<crate::anchor::AnchorWorkerConfig, crate::ServerError>;

Source line: 972.

config::RateLimitConfig

Rate limit configuration per client.

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RateLimitConfig {
/// Max write operations per minute per client.

pub writes_per_minute: u32,
/// Max read operations per minute per client.

pub reads_per_minute: u32,
/// Max discovery queries per minute per client.

pub queries_per_minute: u32,
/// Max authentication operations per minute per network client.

#[serde(default = "default_auth_per_minute")]
pub auth_per_minute: u32,
/// Max WebSocket upgrade attempts per minute per network client.

#[serde(default = "default_websocket_per_minute")]
pub websocket_per_minute: u32,
/// Hard cap on resident client buckets in each limiter.

#[serde(default = "default_max_client_buckets")]
pub max_client_buckets: u32,
/// Inactivity TTL for each client bucket.

#[serde(default = "default_bucket_ttl_seconds")]
pub bucket_ttl_seconds: u64,
/// Proxy networks allowed to supply `Forwarded` or `X-Forwarded-For`.

///

/// Forwarding headers from every other direct peer are ignored.

#[serde(default)]
pub trusted_proxy_cidrs: Vec<ipnet::IpNet>
}

Source line: 1046.

config::RateLimitConfig::validate

Validate the hard memory and lifetime bounds shared by all limiters.

pub fn validate(&self) -> Result<(), crate::ServerError>;

Source line: 1096.

config::MtlsConfig

Optional mutual-TLS material for one federation peer.

Secret-bearing paths are accepted from protected runtime configuration but are deliberately omitted from serialization and debug output.

#[derive(Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MtlsConfig {
/// Require a client certificate and private trust root for this peer.

#[serde(default)]
pub enabled: bool,
/// PEM client certificate chain.

#[serde(default, skip_serializing)]
pub certificate_path: Option<PathBuf>,
/// PKCS#8 PEM private key. The loader rejects symlinks and permissive Unix

/// file modes.

#[serde(default, skip_serializing)]
pub private_key_path: Option<PathBuf>,
/// PEM CA certificate used to authenticate the peer.

#[serde(default, skip_serializing)]
pub ca_certificate_path: Option<PathBuf>
}

Source line: 1133.

config::MtlsConfig::validate

Validate the all-or-nothing mTLS contract before any network request.

pub fn validate(&self) -> Result<(), crate::ServerError>;

Source line: 1163.

config::FederationPeerConfig

One identity-bound outbound federation peer.

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct FederationPeerConfig {
/// Canonical OAS `service` DID expected in signed responses.

pub peer_did: String,
/// HTTPS base URL.

pub endpoint: String,
/// Narrow CIDRs permitted to resolve to non-public addresses.

#[serde(default)]
pub allow_private_cidrs: Vec<ipnet::IpNet>,
/// Persisted agreements that authorize traffic with this peer.

#[serde(default)]
pub agreement_ids: Vec<String>,
/// Optional fail-closed client certificate configuration.

#[serde(default)]
pub mtls: MtlsConfig
}

Source line: 1203.

config::FederationPeerConfig::new

#[must_use]
pub fn new(peer_did: impl Into<String>, endpoint: impl Into<String>) -> Self;

Source line: 1221.

config::MAX_FEDERATION_DISCOVERY_PEERS

Absolute peer fanout bound accepted by federation configuration.

pub const MAX_FEDERATION_DISCOVERY_PEERS: u32;

Source line: 1233.

config::MAX_FEDERATION_DISCOVERY_COST

Absolute remote result-slot budget accepted by federation configuration.

pub const MAX_FEDERATION_DISCOVERY_COST: u64;

Source line: 1235.

config::FederationConfig

Federation configuration for registry peering, synchronization, and optional distributed discovery.

#[derive(Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FederationConfig {
/// Whether federation is enabled.

pub enabled: bool,
/// Sync interval in seconds.

pub sync_interval_secs: u64,
/// Maximum entries per sync batch.

pub max_sync_batch: u32,
/// Identity-bound peers contacted by workers and discovery fanout.

#[serde(default)]
pub peers: Vec<FederationPeerConfig>,
/// Durable bilateral agreement documents.

#[serde(default)]
pub agreements: Vec<mars_protocol::federation::FederationAgreement>,
/// Maximum peers synchronized concurrently.

#[serde(default = "default_federation_max_concurrency")]
pub max_concurrency: u32,
/// End-to-end request timeout.

#[serde(default = "default_federation_request_timeout_ms")]
pub request_timeout_ms: u64,
/// TCP/TLS establishment timeout.

#[serde(default = "default_federation_connect_timeout_ms")]
pub connect_timeout_ms: u64,
/// Maximum accepted envelope clock difference.

#[serde(default = "default_federation_clock_skew_seconds")]
pub clock_skew_seconds: u64,
/// Durable replay nonce retention.

#[serde(default = "default_federation_nonce_ttl_seconds")]
pub nonce_ttl_seconds: u64,
/// Failed attempts before a peer's breaker opens.

#[serde(default = "default_federation_breaker_threshold")]
pub breaker_failure_threshold: u32,
/// Breaker cooldown before one half-open probe.

#[serde(default = "default_federation_breaker_cooldown_ms")]
pub breaker_cooldown_ms: u64,
/// Initial exponential retry delay.

#[serde(default = "default_federation_retry_base_ms")]
pub retry_base_ms: u64,
/// Maximum exponential retry delay.

#[serde(default = "default_federation_retry_max_ms")]
pub retry_max_ms: u64,
/// Symmetric retry jitter in basis points.

#[serde(default = "default_federation_jitter_bps")]
pub jitter_bps: u16,
/// Enable bounded peer discovery fanout.

#[serde(default)]
pub discovery_enabled: bool,
/// Maximum peers queried for one federated discovery request.

#[serde(default = "default_federation_discovery_fanout")]
pub discovery_fanout: u32,
/// Per-peer discovery deadline.

#[serde(default = "default_federation_discovery_timeout_ms")]
pub discovery_timeout_ms: u64,
/// Maximum results requested from each peer before local merge.

#[serde(default = "default_federation_discovery_results")]
pub discovery_max_results_per_peer: u32,
/// Maximum remote result slots consumed by one federated discovery call.

///

/// Cost is computed before fanout as selected peers multiplied by

/// `discoveryMaxResultsPerPeer`.

#[serde(default = "default_federation_discovery_max_cost")]
pub discovery_max_cost: u64,
/// Sender key DID URL. Public metadata, safe to serialize.

#[serde(default, skip_serializing_if = "Option::is_none")]
pub signing_key_id: Option<String>,
/// Protected path containing exactly one 32-byte seed, encoded as

/// canonical unpadded base64url. Never serialized.

#[serde(default, skip_serializing)]
pub signing_key_path: Option<PathBuf>,
/// Environment variable holding the same canonical secret. Never

/// serialized. Exactly one path/environment source may be selected.

#[serde(default, skip_serializing)]
pub signing_key_env: Option<String>
}

Source line: 1242.

config::FederationConfig::validate

Validate bounded worker/discovery policy and secret-source selection.

pub fn validate(&self) -> Result<(), crate::ServerError>;

Source line: 1386.

Source provenance

Source: mars-server/src/config.rs · SHA-256 de9705a79c897fbac6d8bfe433db96ee8c530f4c7044d0c8ab7b36590ad1b78b. Package overview.

On this page