@@ -3011,6 +3011,8 @@ class GatewayRead(BaseModelWithConfigDict):
30113011    # Authorizations 
30123012    auth_type : Optional [str ] =  Field (None , description = "auth_type: basic, bearer, headers, oauth, or None" )
30133013    auth_value : Optional [str ] =  Field (None , description = "auth value: username/password or token or custom headers" )
3014+     auth_headers : Optional [List [Dict [str , str ]]] =  Field (default = None , description = "List of custom headers for authentication" )
3015+     auth_headers_unmasked : Optional [List [Dict [str , str ]]] =  Field (default = None , description = "Unmasked custom headers for administrative views" )
30143016
30153017    # OAuth 2.0 configuration 
30163018    oauth_config : Optional [Dict [str , Any ]] =  Field (None , description = "OAuth 2.0 configuration including grant_type, client_id, encrypted client_secret, URLs, and scopes" )
@@ -3023,6 +3025,10 @@ class GatewayRead(BaseModelWithConfigDict):
30233025    auth_header_value : Optional [str ] =  Field (None , description = "vallue for custom headers authentication" )
30243026    tags : List [str ] =  Field (default_factory = list , description = "Tags for categorizing the gateway" )
30253027
3028+     auth_password_unmasked : Optional [str ] =  Field (default = None , description = "Unmasked password for basic authentication" )
3029+     auth_token_unmasked : Optional [str ] =  Field (default = None , description = "Unmasked bearer token for authentication" )
3030+     auth_header_value_unmasked : Optional [str ] =  Field (default = None , description = "Unmasked single custom header value" )
3031+ 
30263032    # Team scoping fields for resource organization 
30273033    team_id : Optional [str ] =  Field (None , description = "Team ID this gateway belongs to" )
30283034    team : Optional [str ] =  Field (None , description = "Name of the team that owns this resource" )
@@ -3135,19 +3141,30 @@ def _populate_auth(self) -> Self:
31353141            if  not  u  or  not  p :
31363142                raise  ValueError ("basic auth requires both username and password" )
31373143            self .auth_username , self .auth_password  =  u , p 
3144+             self .auth_password_unmasked  =  p 
31383145
31393146        elif  auth_type  ==  "bearer" :
31403147            auth  =  auth_value .get ("Authorization" )
31413148            if  not  (isinstance (auth , str ) and  auth .startswith ("Bearer " )):
31423149                raise  ValueError ("bearer auth requires an Authorization header of the form 'Bearer <token>'" )
31433150            self .auth_token  =  auth .removeprefix ("Bearer " )
3151+             self .auth_token_unmasked  =  self .auth_token 
31443152
31453153        elif  auth_type  ==  "authheaders" :
31463154            # For backward compatibility, populate first header in key/value fields 
3147-             if  len (auth_value ) ==  0 :
3155+             if  not   isinstance ( auth_value ,  dict )  or   len (auth_value ) ==  0 :
31483156                raise  ValueError ("authheaders requires at least one key/value pair" )
3157+             self .auth_headers  =  [
3158+                 {"key" : str (key ), "value" : ""  if  value  is  None  else  str (value )}
3159+                 for  key , value  in  auth_value .items ()
3160+             ]
3161+             self .auth_headers_unmasked  =  [
3162+                 {"key" : str (key ), "value" : ""  if  value  is  None  else  str (value )}
3163+                 for  key , value  in  auth_value .items ()
3164+             ]
31493165            k , v  =  next (iter (auth_value .items ()))
31503166            self .auth_header_key , self .auth_header_value  =  k , v 
3167+             self .auth_header_value_unmasked  =  v 
31513168
31523169        return  self 
31533170
@@ -3182,7 +3199,23 @@ def masked(self) -> "GatewayRead":
31823199        masked_data ["auth_password" ] =  settings .masked_auth_value  if  masked_data .get ("auth_password" ) else  None 
31833200        masked_data ["auth_token" ] =  settings .masked_auth_value  if  masked_data .get ("auth_token" ) else  None 
31843201        masked_data ["auth_header_value" ] =  settings .masked_auth_value  if  masked_data .get ("auth_header_value" ) else  None 
3185- 
3202+         if  masked_data .get ("auth_headers" ):
3203+             masked_data ["auth_headers" ] =  [
3204+                 {
3205+                     "key" : header .get ("key" ),
3206+                     "value" : settings .masked_auth_value  if  header .get ("value" ) else  header .get ("value" ),
3207+                 }
3208+                 for  header  in  masked_data ["auth_headers" ]
3209+             ]
3210+ 
3211+         masked_data ["auth_password_unmasked" ] =  self .auth_password_unmasked 
3212+         masked_data ["auth_token_unmasked" ] =  self .auth_token_unmasked 
3213+         masked_data ["auth_header_value_unmasked" ] =  self .auth_header_value_unmasked 
3214+         masked_data ["auth_headers_unmasked" ] =  (
3215+             [header .copy () for  header  in  self .auth_headers_unmasked ]
3216+             if  self .auth_headers_unmasked 
3217+             else  None 
3218+         )
31863219        return  GatewayRead .model_validate (masked_data )
31873220
31883221
0 commit comments