metrale_server/rate_limiter/
identity.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-26: The rate-limiter key of a request: who is asking. How fast
4//! they may go is the parent module's job.
5//!
6//! Owner: server rate limiter.
7//! Invariants: every key starts with `bearer:`, `xff:` or `peer:`, and a
8//! bearer token appears in a key only as its FNV-1a hash.
9
10/// 2026-09-26: The rate-limit key, first match wins: `bearer:<hash>` for a
11/// non-empty `Authorization: Bearer` token, `xff:<ip>` for the first
12/// non-empty `X-Forwarded-For` entry (taken as sent, not validated), then
13/// `peer:<ip>`, or `peer:unknown` without a peer address. `rate_limit_middleware`
14/// (`main_modules/middleware.rs`) keys the limiter with it.
15pub fn extract_identity(
16    headers: &axum::http::HeaderMap,
17    peer: Option<std::net::SocketAddr>,
18) -> String {
19    use axum::http::header;
20    if let Some(v) = headers
21        .get(header::AUTHORIZATION)
22        .and_then(|v| v.to_str().ok())
23        && let Some(tok) = v.strip_prefix("Bearer ")
24    {
25        let tok = tok.trim();
26        if !tok.is_empty() {
27            // 2026-09-26: Hashed so the limiter map never holds the raw token.
28            return format!("bearer:{}", hash_token(tok));
29        }
30    }
31    if let Some(xff) = headers.get("x-forwarded-for").and_then(|v| v.to_str().ok())
32        && let Some(first) = xff.split(',').next()
33    {
34        let first = first.trim();
35        if !first.is_empty() {
36            return format!("xff:{first}");
37        }
38    }
39    match peer {
40        Some(addr) => format!("peer:{}", addr.ip()),
41        None => "peer:unknown".to_string(),
42    }
43}
44
45/// 2026-09-26: FNV-1a 64-bit hash as 16 hex digits: a stable opaque key, not
46/// a cryptographic hash.
47fn hash_token(tok: &str) -> String {
48    let mut h: u64 = 0xcbf29ce484222325;
49    for b in tok.as_bytes() {
50        h ^= *b as u64;
51        h = h.wrapping_mul(0x100000001b3);
52    }
53    format!("{h:016x}")
54}