Skip to main content

webauthn_kit/
config.rs

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