systemprompt_security/jwt/
mod.rs1use chrono::{Duration, Utc};
8use jsonwebtoken::{Algorithm, Header, encode};
9use systemprompt_identifiers::{ClientId, JwtToken, SessionId, UserId};
10use systemprompt_models::auth::{
11 JwtAudience, JwtClaims, Permission, RateLimitTier, TokenType, UserType,
12};
13
14use crate::error::{JwtError, JwtResult};
15use crate::keys::authority;
16
17#[derive(Debug)]
18pub struct AdminTokenParams<'a> {
19 pub user_id: &'a UserId,
20 pub session_id: &'a SessionId,
21 pub email: &'a str,
22 pub issuer: &'a str,
23 pub duration: Duration,
24 pub client_id: Option<&'a ClientId>,
25}
26
27#[derive(Copy, Clone, Debug)]
28pub struct JwtService;
29
30impl JwtService {
31 pub fn generate_admin_token(params: &AdminTokenParams<'_>) -> JwtResult<JwtToken> {
32 let now = Utc::now();
33 let expiry = now + params.duration;
34
35 let claims = JwtClaims {
36 sub: params.user_id.to_string(),
37 iat: now.timestamp(),
38 exp: expiry.timestamp(),
39 nbf: Some(now.timestamp()),
40 iss: params.issuer.to_string(),
41 aud: JwtAudience::standard(),
42 jti: uuid::Uuid::new_v4().to_string(),
43 scope: vec![Permission::Admin],
44 username: params.email.to_string(),
45 email: params.email.to_string(),
46 user_type: UserType::Admin,
47 roles: vec!["admin".to_string(), "user".to_string()],
48 department: None,
49 client_id: params.client_id.cloned(),
50 token_type: TokenType::Bearer,
51 auth_time: now.timestamp(),
52 session_id: Some(params.session_id.clone()),
53 rate_limit_tier: Some(RateLimitTier::Admin),
54 plugin_id: None,
55 act: None,
56 };
57
58 let kid = authority::active_kid().map_err(|e| JwtError::Signing(e.to_string()))?;
59 let mut header = Header::new(Algorithm::RS256);
60 header.kid = Some(kid.to_string());
61 let key = authority::encoding_key().map_err(|e| JwtError::Signing(e.to_string()))?;
62 let token = encode(&header, &claims, key).map_err(JwtError::from)?;
63
64 Ok(JwtToken::new(token))
65 }
66}