This repository has been archived on 2025-11-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
supervisor/core/src/auth.rs
2025-11-13 14:41:30 +01:00

107 lines
2.9 KiB
Rust

//! Authentication and API key management
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
/// API key scope/permission level
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ApiKeyScope {
/// Full access - can manage keys, runners, jobs
Admin,
/// Can register new runners
Registrar,
/// Can create and manage jobs
User,
}
impl ApiKeyScope {
pub fn as_str(&self) -> &'static str {
match self {
ApiKeyScope::Admin => "admin",
ApiKeyScope::Registrar => "registrar",
ApiKeyScope::User => "user",
}
}
}
/// An API key with metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiKey {
/// The actual key value (UUID or custom string)
pub key: String,
/// Human-readable name for the key
pub name: String,
/// Permission scope
pub scope: ApiKeyScope,
/// When the key was created
pub created_at: String,
/// Optional expiration timestamp
pub expires_at: Option<String>,
}
impl ApiKey {
/// Create a new API key with a generated UUID
pub fn new(name: String, scope: ApiKeyScope) -> Self {
Self {
key: Uuid::new_v4().to_string(),
name,
scope,
created_at: chrono::Utc::now().to_rfc3339(),
expires_at: None,
}
}
/// Create a new API key with a specific key value
pub fn with_key(key: String, name: String, scope: ApiKeyScope) -> Self {
Self {
key,
name,
scope,
created_at: chrono::Utc::now().to_rfc3339(),
expires_at: None,
}
}
}
/// Response for auth verification
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthVerifyResponse {
pub valid: bool,
pub name: String,
pub scope: String,
}
/// Method authorization requirements
/// Maps RPC method names to required scopes
pub fn get_method_required_scopes(method: &str) -> Option<Vec<ApiKeyScope>> {
use ApiKeyScope::*;
match method {
// Admin-only methods
"key.add" | "key.remove" | "key.list" |
"auth.create_key" | "auth.remove_key" | "auth.list_keys" |
"supervisor.info" |
"secrets.list_admin" | "secrets.list_user" | "secrets.list_register" => {
Some(vec![Admin])
}
// Admin or Registrar methods
"runner.register" | "runner.add" | "runner.remove" => {
Some(vec![Admin, Registrar])
}
// Admin or User methods
"jobs.create" | "job.run" | "job.start" | "job.stop" | "job.delete" => {
Some(vec![Admin, User])
}
// Public methods (no auth required)
"rpc.discover" => None,
// Any authenticated user
_ => Some(vec![Admin, Registrar, User]),
}
}