@@ -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