@@ -189,6 +189,16 @@ pub async fn put_dataset_metadata(
189189 let body = body. into_inner ( ) ;
190190 let tenant_id = get_tenant_id_from_request ( & req) ;
191191
192+ // Explicit per-dataset RBAC check — the middleware cannot extract the
193+ // `{name}` path param (it looks for `logstream`), so we must verify here.
194+ let session_key = extract_session_key_from_req ( & req)
195+ . map_err ( |_| DatasetsError :: DatasetNotFound ( dataset_name. clone ( ) ) ) ?;
196+ if Users . authorize ( session_key, Action :: CreateStream , Some ( & dataset_name) , None )
197+ != rbac:: Response :: Authorized
198+ {
199+ return Err ( DatasetsError :: Unauthorized ( dataset_name) ) ;
200+ }
201+
192202 if !PARSEABLE
193203 . check_or_load_stream ( & dataset_name, & tenant_id)
194204 . await
@@ -242,6 +252,8 @@ pub async fn put_dataset_metadata(
242252pub enum DatasetsError {
243253 #[ error( "Dataset not found: {0}" ) ]
244254 DatasetNotFound ( String ) ,
255+ #[ error( "Unauthorized access to dataset: {0}" ) ]
256+ Unauthorized ( String ) ,
245257 #[ error( "Invalid tag: {0}" ) ]
246258 InvalidTag ( String ) ,
247259 #[ error( "Storage error: {0}" ) ]
@@ -252,6 +264,7 @@ impl actix_web::ResponseError for DatasetsError {
252264 fn status_code ( & self ) -> StatusCode {
253265 match self {
254266 DatasetsError :: DatasetNotFound ( _) => StatusCode :: NOT_FOUND ,
267+ DatasetsError :: Unauthorized ( _) => StatusCode :: FORBIDDEN ,
255268 DatasetsError :: InvalidTag ( _) => StatusCode :: BAD_REQUEST ,
256269 DatasetsError :: Storage ( _) => StatusCode :: INTERNAL_SERVER_ERROR ,
257270 }
0 commit comments