Replies: 10 comments 14 replies
-
I defintely see a need for that! But I'd argue that an X.509 public‐key certificate from a trusted CA may be a better route than GPG. In my experience, X.509 is a more widely adopted industry standard. |
Beta Was this translation helpful? Give feedback.
-
Hey, I was just curious on this topic and decided to come over here. I think Sigstore is likely a good match here. I will have a look into this and see what a prototype would look like. |
Beta Was this translation helpful? Give feedback.
-
If we’re going to add a digital signature to the AgentCard, how about defining a schema like the following that supports various signature formats? It’s still a draft, so the details haven’t been finalized yet: {
"title": "AgentSignature",
"type": "object",
"description": "Represents a digital signature attached to an agent card.",
"properties": {
"type": {
"type": "string",
"enum": ["pgp", "x509", "sigstore"],
"description": "Type of signature used: PGP, X.509, or Sigstore."
},
"value": {
"type": "string",
"description": "The raw signature value."
},
"keyId": {
"type": "string",
"description": "Identifier of the key used to sign."
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the signature was created."
}
// Optional: Specific fields for each signatures.
// :
},
"required": ["type", "value"]
} |
Beta Was this translation helpful? Give feedback.
-
CoSAI's supply chain workstream has a SIG on model signing and a SIG on secure model (here agent) cards. They are both building on the https://github.com/sigstore/model-transparency solution (demo'ed at https://colab.sandbox.google.com/drive/18IB_uipduXYq0ohMxJv2xHfeihLIcGMT). Happy to collaborate on this! |
Beta Was this translation helpful? Give feedback.
-
@robomotic @lukehinds @mihaimaruseac Adopting out-of-band digital signature methods such as C2PA or DSSE seems like a better approach, as it would keep the protocol simple and intact. In that case, would we document the signing and verification flow as best practices in the official documentation, and provide concrete examples in a notebook or similar format? |
Beta Was this translation helpful? Give feedback.
-
Anyone unfamiliar with DSSE, it would be something along these lines: {
"payloadType": "application/vnd.sigstore.a2a.agentcard+json",
"payload": "eyJuYW1lIjogIlJlY2lwZSB...", // base64-encoded AgentCard JSON
"signatures": [
{
"keyid": "sha256:abc123...",
"sig": "MEUCIQC8FsU9iOCr1LfU...=="
}
]
} A step further would be to wrap the AgentCard in an intoto wrapper {
"_type": "https://in-toto.io/Statement/vx.x",
"subject": [
{
"name": "agentcard-id",
"digest": {
"sha256": "e3b0c4..."
}
}
],
"predicateType": "https://acme.dev/agentcard/v0.1",
"predicate": {
"name": "Recipe Agent",
"description": "Agent that helps users with recipes and cooking",
"url": "https://agents.acme.com/recipe/.well-known/agent.json",
...
}
} b64 this, sign and Rekor stores a log of the signature for transparency and auditability. p.s. not fully defining the spec here, more helping folks grok the application of it |
Beta Was this translation helpful? Give feedback.
-
An emerging standard coming out of OWASP: https://arxiv.org/pdf/2505.10609 For an Agent Name Service & Agent Discovery. Its requiring X.509 certs from a trusted CA: {
"certificate": {
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "Certificate Subject"
},
"issuer": {
"type": "string",
"description": "Certificate Issuer"
},
"pem": {
"type": "string",
"description": "PEM-encoded Certificate (strongly recommended to use a secure vault reference instead)",
"readOnly": false
}
},
"required": ["subject", "issuer", "pem"]
},
}, |
Beta Was this translation helpful? Give feedback.
-
Hey all, love to see this discussion ongoing. I don't have any direct updates to share yet, but wanted to drop a note to let you know this is on my radar and I'm hoping to have a concrete proposal on signing and authenticity soon. I'm in agreement with you that there's work to be done here. In the mean time, hearing use cases, requirements, and possible implementations is super useful to me, so keep those coming. |
Beta Was this translation helpful? Give feedback.
-
Alright so a month later and I've had time to try to work up a proposal. I had a few thoughts based on the discussions here and elsewhere:
Those desires led me to a pretty straightforward option: JSON Web Signatures (JWS). So, here's the proposal. Please let me know if you believe this would solve what you're looking for with signed agent cards. A2A: Agent Card Signingmikeas@ / Draft: 2025-07-14PublicOverviewWe propose adding signatures to the AgentCard to allow verifying the integrity of the AgentCard content. This is an optional feature of AgentCards. We will use the standard JSON Web Signatures (JWS) format for representing the signature. Trust in the signature can be established via standard JWS fields that indicate the source of keys used to create the signature. AgentCard SignatureWe will extend the AgentCard to include a interface JSONWebSignature {
// The JWS protected header. A base-64 encoded JSON object containing JWS header values. This value is included
// in the signing payload, therefore it is protected from alteration.
protected: string;
// The base64-encoded signature, computed according to the algorithm specified in the JWS header.
signature: string;
// The unprotected JWS header. This contains information for applications interpreting the signature, but
// is not included in the signature and therefore can be tampered with.
header?: { [string]: string };
} Alternative: We could collapse the signature down to a single string by using the compact serialization format with a detached payload. All header values would need to be placed in the protected header for this to work. The resulting signature is a string of the form A full AgentCard example that includes signatures might look like this: {
"protocolVersion": "0.2.9",
"name": "GeoSpatial Route Planner Agent",
"description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.",
"url": "https://georoute-agent.example.com/a2a/v1",
"preferredTransport": "JSONRPC",
"additionalInterfaces" : [
{"url": "https://georoute-agent.example.com/a2a/grpc", "transport": "GRPC"},
{"url": "https://georoute-agent.example.com/a2a/json", "transport": "HTTP+JSON"}
],
"provider": {
"organization": "Example Geo Services Inc.",
"url": "https://www.examplegeoservices.com"
},
"iconUrl": "https://georoute-agent.example.com/icon.png",
"version": "1.2.0",
"documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": false
},
"securitySchemes": {
"google": {
"type": "openIdConnect",
"openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"
}
},
"security": [{ "google": ["openid", "profile", "email"] }],
"defaultInputModes": ["application/json", "text/plain"],
"defaultOutputModes": ["application/json", "image/png"],
"skills": [
{
"id": "route-optimizer-traffic",
"name": "Traffic-Aware Route Optimizer",
"description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).",
"tags": ["maps", "routing", "navigation", "directions", "traffic"],
"examples": [
"Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.",
"{\"origin\": {\"lat\": 37.422, \"lng\": -122.084}, \"destination\": {\"lat\": 37.7749, \"lng\": -122.4194}, \"preferences\": [\"avoid_ferries\"]}"
],
"inputModes": ["application/json", "text/plain"],
"outputModes": [
"application/json",
"application/vnd.geo+json",
"text/html"
]
},
{
"id": "custom-map-generator",
"name": "Personalized Map Generator",
"description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.",
"tags": ["maps", "customization", "visualization", "cartography"],
"examples": [
"Generate a map of my upcoming road trip with all planned stops highlighted.",
"Show me a map visualizing all coffee shops within a 1-mile radius of my current location."
],
"inputModes": ["application/json"],
"outputModes": [
"image/png",
"image/jpeg",
"application/json",
"text/html"
]
}
],
"supportsAuthenticatedExtendedCard": true
//////// Key addition:
"signatures": [
{
"protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0",
"signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ"
}
]
} Verification ProcessThe signatures contained in the AgentCard are standard JWS format. However, the process for verifying the signature deviates from the norm. This is because the most common version of JWS seen in the wild is presented in the “compact serialization” format. The process I propose here is composed of known standards, and so is not particularly novel. It just stitches them together for our use case. The primary challenge to be addressed in verifying a signature is how to create the signature input. Crucially, how to represent the AgentCard data in a way that both signers and verifiers can reliably construct to come up with an accurate signature. The problem here is that verifying an AgentCard requires 4 steps:
The issue is step 3: the signing input includes the payload, but doesn’t include the signature itself, and so we’re faced with an issue where everyone must agree on how to take their parsed AgentCard data, perform some transformation, and turn it into the exact same set of bytes that act as the payload input. Just serializing to JSON is insufficient: any whitespace differences or field ordering differences would produce different input. This is a problem that has been addressed before, and there is a standard that provides the answer: RFC 8785: JSON Canonicalization Scheme (JCS). This is a standard specifically developed to solve the problem of producing JSON appropriate for input to cryptographic verification. So, the process is as follows:
Note that "following the standard JWS process" could mean constructing the compact serialization form ( Roughly, in python: # Verify all the signatures on an AgentCard.
# key_locator is a function that retrieves the JWKS necessary to verify the signature.
def verify_agent_card_signatures(card: AgentCard, key_locator):
signatures = card.signatures
card_dict = card.model_dump(exclude=['signatures'])
card_jcs = Canonicalize.canonicalize(card_dict)
jws_payload = jwcrypto.common.base64_urlencode(card_jcs)
for sig in signatures:
jws = jwcrypto.JWS.from_jose_token({'signature': sig.model_dump()})
jwks = key_locator(jws.jose_header)
jws.verify(jwks, detached_payload=jws_payload)
# Likely want to emit a record of this signature being verified, including
# details like the source of the key. Callers can use that to make policy/trust
# decisions, such as "agent card must be signed by my-favorite-registry".
# A key locator that uses JWS fields to identify the key.
def jws_key_locator(jws_header):
if jku := jws_header.get('jku'):
# The JWS header indicates a JWKS URL. Fetch it and use that.
if jwk := jws_header.get('jwk'):
# The JWS header directly specifies the JWK.
if x5u := jws_header.get('x5u'):
# The JWS header indicates a URL for an x.509 cert. Fetch it and use that.
if x5c := jws_header.get('x5c'):
# The JWS header includes an x.509 cert.
raise UnknownKeyError('cannot determine key to use') Optional: CountersigningRecommendation: do not include countersigning in the initial version. One of the limitations of the proposed structure for attaching signatures to the AgentCard is that the process of countersigning becomes impossible. Countersigning is the inclusion of a signature as input to another signature. This proves that the countersigner observed that the original signature was present. I’m not entirely clear on the value of countersigning for AgentCards, however I feel it’s important to call out the limitation. Perhaps a scenario where the agent deployment platform (such as Agent Engine) countersigns the AgentCard that’s signed by the agent developer. The key limitation preventing countersigning is that there is no indication in the JWS of what other signatures would be included in the signing input. This is normally handled via a process of wrapping a full JWS in another JWS, where a JWS becomes the payload to another JWS. This is a simple matter when the JWS embeds the payload to be signed. Our design reverses this and embeds the signature in the payload itself, which prevents wrapping. So, if we want countersigning, we need a means for one signature to indicate that another signature should be included in the signing input. There is no existing standard for this, so we’d be defining a custom extension to JWS to make it work. However, the actual process is relatively simple:
Alternative: A more standard form of countersigning with JWS is performed via nesting, where the payload to be signed is itself a JWS. We could alter the above process to match this. In essence, the difference is in the production of the signing input: the payload for a countersignature becomes the full compact JWS of the signature to be countersigned. One limitation of this option is that it is not possible to countersign two or more signatures (i.e. signature S3 verifies that it saw both S1 and S2, but S1 and S2 are unrelated). Where do the keys come from?To verify the signature, the verifier must be able to retrieve the key used for validating the signature. A few options are:
For this initial version of agent card signing, we will go with option 1: the In the future, it may be necessary to add other fields to the AgentCard that can indicate sources of keys (such as DIDs or Sigstore bundles). This should be done carefully, as addition of fields like this is technically backwards compatible for the data object, but may not be backwards compatible for signature verification. Connection to Trust and Identity {#connection-to-trust-and-identity}Including a signature offers one gateway into establishing trust. This is done via the connection between the JWS and the keys used to create the signature. If you can establish a connection between the signing keys and an identity, you can establish a basis for trust. There are a few ways this is accomplished:
Note that these strategies are available, but not required or strictly specified. Tying identity to a JWKS URL is not directly solved by the AgentCard and must be established separately. Similarly, signatures do not fully address the idea of establishing an agent identity and corresponding trust. I discuss this more below. What’s missing/What does this prove?This section contains overall thoughts on how signatures fit into the A2A landscape. Adding signatures to AgentCards is a necessary step for ensuring integrity, but simply having a signature alone is insufficient for proving certain useful properties. On its own, a signature proves only one thing: the content of the AgentCard was not changed from when the holder of the signing key added a signature. What should we take away from this? Let’s consider a few properties we might want to know about an AgentCard:
Property 1 is the most directly provable with a signature. If you can tie the signing key to the source of the AgentCard (an agent registry, for example), you can prove the AgentCard has not been tampered with. Establishing a link between the source of an AgentCard (such as a URL, or an RPC response from a server) is not specified by the protocol. With enough trust in the source of the AgentCard, this is sufficient evidence for the remaining properties (“I trust that you vetted properties 2-4 and wouldn’t be serving me this AgentCard otherwise”). This is the primary property targeted for this version of AgentCard signatures. Abstractly, properties 2-4 are restatements of the same idea: the AgentCard contains a set of claims (the URL the agent is served from, the skills the agent possesses, and the provider of the agent, respectively), and we’d like to verify those claims somehow. Signatures can help with establishing these properties, however in each case some additional information is required. We could establish property 2 if we had a means to tie a signing key to the agent URL referenced by the AgentCard. We do not have a direct solution for establishing this property. It is up to verifiers to decide what is sufficient for them. One clear way that agent publishers could opt for is serving their JWKS off of the same path as the agent (I mention this in Connection to Trust and Identity). Another option is to add protocol-level support for this by adding a protocol RPC for retrieving a key set. Something like: To establish property 3 with signatures, we need two pieces of information:
There are a few ways of accomplishing this:
Property 4 is significantly more nebulous and intersects directly with larger questions of trust and abuse. Assuming we have established that an AgentCard has not been modified (property 1) and that it actually comes from the referenced agent (property 2), determining if an agent can actually perform the skills it claims requires an additional framework for validating agent skills, for which we do not have a direct answer. Some form of trusted credential, where a trusted third-party issues a credential attesting that the agent implements the claimed skill, or validation framework, where a client has the means to directly test and verify the capability, is required. Stated another way, verifiers require either someone they trust to attest that the agent can perform the skill, or they need a means of proving that themselves. Establishing the root of trust for skill validation is beyond the scope of A2A. In general, the primary property that should be asserted with a signature is integrity. Other properties are possible, but require verifiers to decide on more complicated problems, such as trust frameworks. Out of Band Signing {#out-of-band-signing}Out of band signing refers to associating a signature with an AgentCard through a means other than including it directly on the AgentCard. This proposal does not eliminate the possibility of out-of-band signing. However, there’s usually some need to communicate to consumers of an AgentCard that out-of-band signatures are available (unless the verifier wants to just blindly test). We do not currently plan to add any fields to the AgentCard to support this at this time. Instead, if you are interested in out-of-band signing, I would recommend you implement it via Extensions. Relation to Other ProtocolsANSAgent Name Service (ANS) is an OWASP protocol that supports secure agent discovery. Agents registering with ANS provide their identity and a public key (as part of a Certificate Signing Request), and successful registration results in an x.509 certificate that is associated with the agent. This certificate asserts the agent’s identity and establishes a chain of trust. Agent Registries return details of registered agents (called an Endpoint), including the agent’s certificate and a registry-created signature verifying the integrity of the agent details. It does not appear that the agent certificate is used to create a signature. AgentCard signatures are similar to the signatures included on the Endpoint object returned by Agent Registries. An ANS Agent Registry can attach a signature to an AgentCard (if an AgentCard is included in the Endpoint data) using a key controlled by the registry. C2PAC2PA provides a framework for asserting content authenticity. It is largely targeted for content provenance, to aid in proving that, e.g., a photo was captured by a device and is unaltered. Included in the protocol is a much more comprehensive provenance and claim verification framework than what is proposed here. C2PA leverages a manifest as the data vehicle for storing claims and signatures, which can be served separately from the content itself. Leveraging C2PA in this way is entirely possible, and matches the idea of Out of Band Signing. AgentCard signatures are intended to be a relatively lightweight option for adding signatures. When applications require the robustness of C2PA, they can use it. SigstoreSigstore provides a way for software developers to include signatures on their published artifacts to prove integrity and authenticity. It does so via a combination of a system for issuing certificates that tie to identities, a transparency log for “witnessing” signatures, and tooling for bringing these pieces together in one package. As mentioned above, sigstore and AgentCard signatures are compatible. Additional work could be done to make use of sigstore simpler, if this becomes a popular choice for producing signatures. |
Beta Was this translation helpful? Give feedback.
-
Moving this to feature request #916. Let's take further discussion there. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
The assumption so far is that the protocol will assume the owner of the agent belongs to the owner of the domain FQDN where is deployed but there are a number of cases where this will be violated for example a hosting provider may not allow the user to write the agent card or the application logic is in another domain and the card on another subdomain.
In terms of security a malicious threat actor may even overwrite the agent card to point to its malicious services.
The solution is quite simple and will be to include a field for digitally signing the card with a GPG/PGP key, in that way you can figure out which organization/person owns the card.
Cheers!
Beta Was this translation helpful? Give feedback.
All reactions