Skip to content

[Bug]: APIKeySecurityScheme implementation parsing in the client #165

@alberto-atk

Description

@alberto-atk

What happened?

Hello everyone,

I am trying to do an example of an A2A client-server communication with APIKeySecurityScheme authentication.

My pydantic version is 2.11.3 and the a2a library version is the 0.2.5.

This is my agent card specification in the server:

agent_card = AgentCard(
        name='Carpenter Agent',
        description='This agent handles carpentry tasks using tools like hammer and screwdriver.',
        url=f'http://{host}:{port}/',
        version='1.0.0',
        defaultInputModes=CarpenterAgent.SUPPORTED_CONTENT_TYPES,
        defaultOutputModes=CarpenterAgent.SUPPORTED_CONTENT_TYPES,
        capabilities=capabilities,
        skills=skills,
        securitySchemes={
           "api-key": {
               "description":"the description of the security schema",
               "in":In.header,
               "name":"passed_api_key",
               "type":"apiKey"}
       }
    ) 

The problem is in the A2ACardResolver when it retrieves the card with the get_agent_card() method, as the server sends the 'in' parameter in the securityScheme like 'in_' (using the 'model_dump' from pydantic) so the model_validate() in the client cannot parse it and throws the error showed in the log.

The solution I've managed is to remove the Field in the 'in_' types definition for APIKeySecurityScheme:

class APIKeySecurityScheme(BaseModel):
    """
    API Key security scheme.
    """

    description: str | None = None
    """
    Description of this security scheme.
    """
    in_: In
    """
    The location of the API key. Valid values are "query", "header", or "cookie".
    """
    name: str
    """
    The name of the header, query or cookie parameter to be used.
    """
    type: Literal['apiKey'] = 'apiKey

And having my new card like this:

agent_card = AgentCard(
        name='Carpenter Agent',
        description='This agent handles carpentry tasks using tools like hammer and screwdriver.',
        url=f'http://{host}:{port}/',
        version='1.0.0',
        defaultInputModes=CarpenterAgent.SUPPORTED_CONTENT_TYPES,
        defaultOutputModes=CarpenterAgent.SUPPORTED_CONTENT_TYPES,
        capabilities=capabilities,
        skills=skills,
        securitySchemes={
           "api-key": {
               "description":"the description of the security schema",
               "in_":In.header,
               "name":"passed_api_key",
               "type":"apiKey"}
       }
    )

Should I add it as a new PR or there is an existant solution?

Thank you so much!

Relevant log output

a2a.client.errors.A2AClientJSONError: JSON Error: Failed to validate agent card structure from http://localhost:8080/.well-known/agent.json: [{"type":"missing","loc":["securitySchemes","api-key","APIKeySecurityScheme","in"],"msg":"Field required","input":{"description":"the description of the security schema","in_":"header","name":"passed_api_key","type":"apiKey"},"url":"https://errors.pydantic.dev/2.11/v/missing"},{"type":"missing","loc":["securitySchemes","api-key","HTTPAuthSecurityScheme","scheme"],"msg":"Field required","input":{"description":"the description of the security schema","in_":"header","name":"passed_api_key","type":"apiKey"},"url":"https://errors.pydantic.dev/2.11/v/missing"},{"type":"literal_error","loc":["securitySchemes","api-key","HTTPAuthSecurityScheme","type"],"msg":"Input should be 'http'","input":"apiKey","ctx":{"expected":"'http'"},"url":"https://errors.pydantic.dev/2.11/v/literal_error"},{"type":"missing","loc":["securitySchemes","api-key","OAuth2SecurityScheme","flows"],"msg":"Field required","input":{"description":"the description of the security schema","in_":"header","name":"passed_api_key","type":"apiKey"},"url":"https://errors.pydantic.dev/2.11/v/missing"},{"type":"literal_error","loc":["securitySchemes","api-key","OAuth2SecurityScheme","type"],"msg":"Input should be 'oauth2'","input":"apiKey","ctx":{"expected":"'oauth2'"},"url":"https://errors.pydantic.dev/2.11/v/literal_error"},{"type":"missing","loc":["securitySchemes","api-key","OpenIdConnectSecurityScheme","openIdConnectUrl"],"msg":"Field required","input":{"description":"the description of the security schema","in_":"header","name":"passed_api_key","type":"apiKey"},"url":"https://errors.pydantic.dev/2.11/v/missing"},{"type":"literal_error","loc":["securitySchemes","api-key","OpenIdConnectSecurityScheme","type"],"msg":"Input should be 'openIdConnect'","input":"apiKey","ctx":{"expected":"'openIdConnect'"},"url":"https://errors.pydantic.dev/2.11/v/literal_error"}]

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions