Skip to main content

systemprompt_security/jwt/
mod.rs

1use anyhow::Result;
2use chrono::{Duration, Utc};
3use jsonwebtoken::{Algorithm, EncodingKey, Header, encode};
4use systemprompt_identifiers::{ClientId, JwtToken, SessionId, UserId};
5use systemprompt_models::auth::{
6    JwtAudience, JwtClaims, Permission, RateLimitTier, TokenType, UserType,
7};
8
9#[derive(Debug)]
10pub struct AdminTokenParams<'a> {
11    pub user_id: &'a UserId,
12    pub session_id: &'a SessionId,
13    pub email: &'a str,
14    pub jwt_secret: &'a str,
15    pub issuer: &'a str,
16    pub duration: Duration,
17    pub client_id: Option<&'a ClientId>,
18}
19
20#[derive(Copy, Clone, Debug)]
21pub struct JwtService;
22
23impl JwtService {
24    pub fn generate_admin_token(params: &AdminTokenParams<'_>) -> Result<JwtToken> {
25        let now = Utc::now();
26        let expiry = now + params.duration;
27
28        let claims = JwtClaims {
29            sub: params.user_id.to_string(),
30            iat: now.timestamp(),
31            exp: expiry.timestamp(),
32            iss: params.issuer.to_string(),
33            aud: JwtAudience::standard(),
34            jti: uuid::Uuid::new_v4().to_string(),
35            scope: vec![Permission::Admin],
36            username: params.email.to_string(),
37            email: params.email.to_string(),
38            user_type: UserType::Admin,
39            roles: vec!["admin".to_string(), "user".to_string()],
40            client_id: params.client_id.map(ToString::to_string),
41            token_type: TokenType::Bearer,
42            auth_time: now.timestamp(),
43            session_id: Some(params.session_id.to_string()),
44            rate_limit_tier: Some(RateLimitTier::Admin),
45        };
46
47        let header = Header::new(Algorithm::HS256);
48        let token = encode(
49            &header,
50            &claims,
51            &EncodingKey::from_secret(params.jwt_secret.as_bytes()),
52        )?;
53
54        Ok(JwtToken::new(token))
55    }
56}