@@ -2916,6 +2916,8 @@ class GatewayRead(BaseModelWithConfigDict):
29162916 # Authorizations
29172917 auth_type : Optional [str ] = Field (None , description = "auth_type: basic, bearer, headers, oauth, or None" )
29182918 auth_value : Optional [str ] = Field (None , description = "auth value: username/password or token or custom headers" )
2919+ auth_headers : Optional [List [Dict [str , str ]]] = Field (default = None , description = "List of custom headers for authentication" )
2920+ auth_headers_unmasked : Optional [List [Dict [str , str ]]] = Field (default = None , description = "Unmasked custom headers for administrative views" )
29192921
29202922 # OAuth 2.0 configuration
29212923 oauth_config : Optional [Dict [str , Any ]] = Field (None , description = "OAuth 2.0 configuration including grant_type, client_id, encrypted client_secret, URLs, and scopes" )
@@ -2928,6 +2930,10 @@ class GatewayRead(BaseModelWithConfigDict):
29282930 auth_header_value : Optional [str ] = Field (None , description = "vallue for custom headers authentication" )
29292931 tags : List [str ] = Field (default_factory = list , description = "Tags for categorizing the gateway" )
29302932
2933+ auth_password_unmasked : Optional [str ] = Field (default = None , description = "Unmasked password for basic authentication" )
2934+ auth_token_unmasked : Optional [str ] = Field (default = None , description = "Unmasked bearer token for authentication" )
2935+ auth_header_value_unmasked : Optional [str ] = Field (default = None , description = "Unmasked single custom header value" )
2936+
29312937 # Team scoping fields for resource organization
29322938 team_id : Optional [str ] = Field (None , description = "Team ID this gateway belongs to" )
29332939 team : Optional [str ] = Field (None , description = "Name of the team that owns this resource" )
@@ -3040,19 +3046,24 @@ def _populate_auth(self) -> Self:
30403046 if not u or not p :
30413047 raise ValueError ("basic auth requires both username and password" )
30423048 self .auth_username , self .auth_password = u , p
3049+ self .auth_password_unmasked = p
30433050
30443051 elif auth_type == "bearer" :
30453052 auth = auth_value .get ("Authorization" )
30463053 if not (isinstance (auth , str ) and auth .startswith ("Bearer " )):
30473054 raise ValueError ("bearer auth requires an Authorization header of the form 'Bearer <token>'" )
30483055 self .auth_token = auth .removeprefix ("Bearer " )
3056+ self .auth_token_unmasked = self .auth_token
30493057
30503058 elif auth_type == "authheaders" :
30513059 # For backward compatibility, populate first header in key/value fields
3052- if len (auth_value ) == 0 :
3060+ if not isinstance ( auth_value , dict ) or len (auth_value ) == 0 :
30533061 raise ValueError ("authheaders requires at least one key/value pair" )
3062+ self .auth_headers = [{"key" : str (key ), "value" : "" if value is None else str (value )} for key , value in auth_value .items ()]
3063+ self .auth_headers_unmasked = [{"key" : str (key ), "value" : "" if value is None else str (value )} for key , value in auth_value .items ()]
30543064 k , v = next (iter (auth_value .items ()))
30553065 self .auth_header_key , self .auth_header_value = k , v
3066+ self .auth_header_value_unmasked = v
30563067
30573068 return self
30583069
@@ -3087,7 +3098,19 @@ def masked(self) -> "GatewayRead":
30873098 masked_data ["auth_password" ] = settings .masked_auth_value if masked_data .get ("auth_password" ) else None
30883099 masked_data ["auth_token" ] = settings .masked_auth_value if masked_data .get ("auth_token" ) else None
30893100 masked_data ["auth_header_value" ] = settings .masked_auth_value if masked_data .get ("auth_header_value" ) else None
3090-
3101+ if masked_data .get ("auth_headers" ):
3102+ masked_data ["auth_headers" ] = [
3103+ {
3104+ "key" : header .get ("key" ),
3105+ "value" : settings .masked_auth_value if header .get ("value" ) else header .get ("value" ),
3106+ }
3107+ for header in masked_data ["auth_headers" ]
3108+ ]
3109+
3110+ masked_data ["auth_password_unmasked" ] = self .auth_password_unmasked
3111+ masked_data ["auth_token_unmasked" ] = self .auth_token_unmasked
3112+ masked_data ["auth_header_value_unmasked" ] = self .auth_header_value_unmasked
3113+ masked_data ["auth_headers_unmasked" ] = [header .copy () for header in self .auth_headers_unmasked ] if self .auth_headers_unmasked else None
30913114 return GatewayRead .model_validate (masked_data )
30923115
30933116
0 commit comments