Skip to main content

webauthn_kit/
config.rs

1//! Relying-party configuration.
2
3use crate::attestation::AttestationPolicy;
4
5/// `WebAuthn` relying party configuration.
6///
7/// This is the kit-local replacement for any application-specific auth config
8/// struct: it carries everything the protocol layer needs and nothing else.
9/// Application concerns (feature flags, storage, session handling) are
10/// deliberately excluded.
11///
12/// # Security notes
13///
14/// - `rp_id` must be the registrable domain suffix shared by all origins that
15///   may perform `WebAuthn` ceremonies. It is hashed (SHA-256) and compared
16///   against the `rpIdHash` embedded in authenticator data; a wrong value
17///   fails every verification.
18/// - Every entry in `rp_origins` is an exact-match allow-list entry. Origins
19///   are compared byte-for-byte against `clientDataJSON.origin`; scheme,
20///   host, and port must all match. List only origins you fully trust.
21/// - `allowed_algorithms` controls which COSE algorithms are *advertised* to
22///   authenticators in registration options. Runtime verification currently
23///   implements ES256 (-7) and RS256 (-257) only; other algorithms are
24///   rejected with [`crate::WebauthnError::UnsupportedAlgorithm`] regardless
25///   of this setting.
26/// - `attestation` governs attestation statement verification during
27///   registration; see [`AttestationPolicy`] for the trust implications of
28///   empty `trust_anchors` and `allow_unknown_formats`.
29#[derive(Debug, Clone)]
30pub struct WebauthnConfig {
31    /// Relying party ID (effective domain, e.g. `"example.com"`).
32    ///
33    /// Must NOT include scheme or port. See struct-level security notes.
34    pub rp_id: String,
35    /// Human-readable relying party name (advertised in registration options).
36    pub rp_name: String,
37    /// Allowed origins for `WebAuthn` ceremonies (exact match, e.g.
38    /// `"https://example.com"`).
39    pub rp_origins: Vec<String>,
40    /// COSE algorithm identifiers advertised for registration.
41    ///
42    /// Defaults to `[-7 (ES256), -257 (RS256)]`.
43    pub allowed_algorithms: Vec<i32>,
44    /// Challenge freshness window in seconds (default 300 = 5 minutes).
45    ///
46    /// Challenges older than this are rejected on consumption.
47    pub challenge_timeout_secs: u64,
48    /// Attestation verification policy applied by
49    /// [`crate::verify_registration`] (default: strict — unknown formats
50    /// rejected, no trust anchors configured).
51    pub attestation: AttestationPolicy,
52}
53
54impl Default for WebauthnConfig {
55    /// Sensible development defaults (`localhost` RP).
56    ///
57    /// Do not use `Default::default()` in production; set `rp_id` and
58    /// `rp_origins` to your real domain and HTTPS origin.
59    fn default() -> Self {
60        Self {
61            rp_id: "localhost".to_string(),
62            rp_name: "webauthn-kit".to_string(),
63            rp_origins: vec!["http://localhost:8080".to_string()],
64            allowed_algorithms: vec![-7, -257],
65            challenge_timeout_secs: 300,
66            attestation: AttestationPolicy::default(),
67        }
68    }
69}
70
71// Tests exercise failure paths and invariants directly; unwrap/expect,
72// slicing, and panicking asserts are acceptable here — violations
73// surface as test failures, not production panics.
74#[allow(
75    clippy::unwrap_used,
76    clippy::expect_used,
77    clippy::indexing_slicing,
78    clippy::panic
79)]
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_config_default() {
86        let config = WebauthnConfig::default();
87        assert_eq!(config.rp_id, "localhost");
88        assert_eq!(config.rp_name, "webauthn-kit");
89        assert_eq!(config.rp_origins, vec!["http://localhost:8080"]);
90        assert_eq!(config.allowed_algorithms, vec![-7, -257]);
91        assert_eq!(config.challenge_timeout_secs, 300);
92    }
93
94    #[test]
95    fn test_config_custom_algorithms() {
96        let config = WebauthnConfig {
97            allowed_algorithms: vec![-7],
98            ..WebauthnConfig::default()
99        };
100        assert_eq!(config.allowed_algorithms.len(), 1);
101        assert_eq!(config.allowed_algorithms[0], -7);
102    }
103}