@@ -39,24 +39,42 @@ pub struct ApiKeyStore {
3939 pub keys : RwLock < HashMap < String , HashMap < Ulid , ApiKey > > > ,
4040}
4141
42+ /// Type of API key, determining how it can be used.
43+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Serialize , Deserialize ) ]
44+ #[ serde( rename_all = "lowercase" ) ]
45+ pub enum KeyType {
46+ /// Used as a substitute for basic auth on ingestion endpoints
47+ Ingestion ,
48+ /// Used as a substitute for basic auth on query endpoints (global query access)
49+ Query ,
50+ }
51+
4252#[ derive( Debug , Clone , Serialize , Deserialize ) ]
4353#[ serde( rename_all = "camelCase" ) ]
4454pub struct ApiKey {
4555 pub key_id : Ulid ,
4656 pub api_key : String ,
4757 pub key_name : String ,
58+ #[ serde( default = "default_key_type" ) ]
59+ pub key_type : KeyType ,
4860 pub created_by : String ,
4961 pub created_at : DateTime < Utc > ,
5062 pub modified_at : DateTime < Utc > ,
5163 #[ serde( default ) ]
5264 pub tenant : Option < String > ,
5365}
5466
67+ fn default_key_type ( ) -> KeyType {
68+ KeyType :: Ingestion
69+ }
70+
5571/// Request body for creating a new API key
5672#[ derive( Debug , Deserialize ) ]
5773#[ serde( rename_all = "camelCase" ) ]
5874pub struct CreateApiKeyRequest {
5975 pub key_name : String ,
76+ #[ serde( default = "default_key_type" ) ]
77+ pub key_type : KeyType ,
6078}
6179
6280/// Response for list keys (api_key masked to last 4 chars)
@@ -66,18 +84,25 @@ pub struct ApiKeyListEntry {
6684 pub key_id : Ulid ,
6785 pub api_key : String ,
6886 pub key_name : String ,
87+ pub key_type : KeyType ,
6988 pub created_by : String ,
7089 pub created_at : DateTime < Utc > ,
7190 pub modified_at : DateTime < Utc > ,
7291}
7392
7493impl ApiKey {
75- pub fn new ( key_name : String , created_by : String , tenant : Option < String > ) -> Self {
94+ pub fn new (
95+ key_name : String ,
96+ key_type : KeyType ,
97+ created_by : String ,
98+ tenant : Option < String > ,
99+ ) -> Self {
76100 let now = Utc :: now ( ) ;
77101 Self {
78102 key_id : Ulid :: new ( ) ,
79103 api_key : uuid:: Uuid :: new_v4 ( ) . to_string ( ) ,
80104 key_name,
105+ key_type,
81106 created_by,
82107 created_at : now,
83108 modified_at : now,
@@ -96,6 +121,7 @@ impl ApiKey {
96121 key_id : self . key_id ,
97122 api_key : masked,
98123 key_name : self . key_name . clone ( ) ,
124+ key_type : self . key_type ,
99125 created_by : self . created_by . clone ( ) ,
100126 created_at : self . created_at ,
101127 modified_at : self . modified_at ,
@@ -228,24 +254,24 @@ impl ApiKeyStore {
228254 . ok_or_else ( || ApiKeyError :: KeyNotFound ( key_id. to_string ( ) ) )
229255 }
230256
231- /// Validate an API key for ingestion. Returns true if the key is valid.
257+ /// Validate an API key against a required key type. Returns true if the
258+ /// key is valid AND its type matches the required type.
232259 /// For multi-tenant: checks the key belongs to the specified tenant.
233260 /// For single-tenant: checks the key exists globally.
234- pub async fn validate_key ( & self , api_key_value : & str , tenant_id : & Option < String > ) -> bool {
261+ pub async fn validate_key (
262+ & self ,
263+ api_key_value : & str ,
264+ tenant_id : & Option < String > ,
265+ required_type : KeyType ,
266+ ) -> bool {
235267 let map = self . keys . read ( ) . await ;
236- if let Some ( tenant_id) = tenant_id {
237- // Multi-tenant: check keys for the specific tenant
238- if let Some ( tenant_keys) = map. get ( tenant_id) {
239- return tenant_keys. values ( ) . any ( |k| k. api_key == api_key_value) ;
240- }
241- false
242- } else {
243- // Single-tenant: check keys under DEFAULT_TENANT
244- if let Some ( tenant_keys) = map. get ( DEFAULT_TENANT ) {
245- return tenant_keys. values ( ) . any ( |k| k. api_key == api_key_value) ;
246- }
247- false
268+ let tenant = tenant_id. as_deref ( ) . unwrap_or ( DEFAULT_TENANT ) ;
269+ if let Some ( tenant_keys) = map. get ( tenant) {
270+ return tenant_keys
271+ . values ( )
272+ . any ( |k| k. api_key == api_key_value && k. key_type == required_type) ;
248273 }
274+ false
249275 }
250276
251277 /// Insert an API key directly into memory (used for sync from prism)
0 commit comments