Agent Card란 무엇인가? 발견(discovery), 지원 인터페이스 및 서명 검증에 대해 설명합니다
요약
Agent Card는 Agent2Agent(A2A) 프로토콜에서 에이전트 간의 협업을 위해 필수적인 공개 문서입니다. 이 카드는 에이전트가 자신의 위치, 기능, 대화 방식을 명시하며, 발견 과정의 보안 및 신뢰성을 확보하는 것이 중요합니다. 또한, 스킬 설명과 지원 인터페이스 정의는 실제 운영상의 핵심 요소로 작용합니다.
핵심 포인트
- Agent Card는 A2A 협업을 위한 에이전트의 공개 프로필입니다.
- 발견(Discovery) 과정은 보안을 위해 인증 전에도 가능해야 합니다.
- 최소한 'name'과 'skills' 필드가 필수적이며, 스킬 설명은 명확해야 합니다.
- supportedInterfaces는 JSONRPC, HTTP+JSON, gRPC 등 접근 방식을 정의합니다.
두 에이전트가 협업하려면 호출자(caller)는 사적인 소개 없이 세 가지 질문에 답해야 합니다. 바로 '그 에이전트가 어디에 있는지', '무엇을 할 수 있는지', 그리고 '어떻게 대화할 수 있는지'입니다. Agent2Agent 프로토콜에서 이 세 가지 답변은 하나의 공개 문서인 Agent Card로 제공되며, 이는 잘 알려진(well-known) URL에서 서비스됩니다. 이 카드는 A2A에 있어 가장 중요한 부분인데, 왜냐하면 다운스트림의 모든 것, 전송 방식 선택을 포함하여, 이것으로부터 파생되기 때문입니다.
카드가 위치하는 곳
에이전트는 고정되고 인증되지 않은 경로에 자신의 카드를 게시합니다:
curl https://expense-agent.example.com/.well-known/agent-card.json
발견(Discovery) 과정은 의도적으로 공개적이어야 합니다. 클라이언트는 보호된 작업을 호출하기 전에 OpenAPI 문서를 읽을 수 있는 것처럼, 에이전트가 인증하기 전에 그 에이전트의 기술과 엔드포인트를 알아낼 수 있어야 합니다. 카드는 신뢰가 확립되기 전에 가져와지기 때문에, 이 가져오는 행위 자체는 보수적이어야 합니다. 실제로는 다음을 의미합니다:
http와httpsURL만 허용하며, URL에 자격 증명(credentials)이 포함되어서는 안 됩니다 (예:https://user:pass@host/...).- 발견 과정 중 쿠키를 사용하거나 리디렉션 추적을 해서는 안 됩니다. 다른 곳으로 리디렉션하는 카드는 조용히 따라가기보다는 알려줄 가치가 있는 신호입니다.
- 악의적인 엔드포인트가 클라이언트로 무한한 본문(unbounded body)을 스트리밍할 수 없도록, 명시적인 응답 크기 제한(1 MiB 상한선이 합리적임)이 필요합니다.
- 명시적인
Accept: application/json과 짧은 타임아웃이 필요합니다.
파서 수준에서는 이 카드를 단순히 네트워크 레벨의 것이 아니라 신뢰할 수 없는 입력으로 취급해야 합니다.
카드를 유효하게 만드는 최소한의 조건
유용한 검증기(validator)는 핵심적인 필드에 대해서는 엄격하고 나머지 부분에 대해서는 관대합니다. 최소한 카드에는 문자열 형태의 name과 배열 형태의 skills가 있어야 하며, 이 두 가지 확인을 통과하지 못하는 것은 에이전트 카드가 아니므로 절반만 렌더링하기보다는 거부되어야 합니다.
실제 카드는 다음과 같습니다:
{
"name": "Expense Agent",
"description": "경비 보고서를 생성, 검토 및 상환합니다"
...
skills 배열은 역량 이력서 역할을 합니다. 각 스킬의 id, name, 그리고 사람이 읽기 쉬운 description이 라우팅 에이전트가 해당 피어가 적절한 목적지인지 결정하는 데 사용됩니다. 모호한 스킬 설명은 실제 운영상의 문제입니다. 세 개의 에이전트가 모두 '요청 지원'을 광고할 경우, 위임(delegation)은 동전 던지기와 같습니다. 독자가 다른 맥락 정보 없이도 이해할 수 있도록 OpenAPI 문서에 작업 요약본을 작성하는 방식으로 스킬 설명을 작성해야 합니다.
supportedInterfaces는 전송 방식 선택을 결정합니다
supportedInterfaces 배열은 클라이언트에게 에이전트에 어떻게 접근할 수 있는지 알려줍니다. 각 항목은 프로토콜 버전과 바인딩(binding), 그리고 URL을 쌍으로 묶습니다. A2A 1.0은 세 가지 바인딩을 정의합니다:
- JSONRPC: HTTP를 통한 방식이며, 가장 일반적인 옵션입니다. 표준
jsonrpc/id/method/params엔벨로프(envelope)를 사용합니다. - HTTP+JSON (REST): 요청 본문 자체가 params 객체이며, JSON-RPC 래퍼가 없습니다.
- GRPC: 수동으로 인코딩된 메시지 대신 공식 서비스 디스크립터(service descriptor)를 사용하는 네이티브 gRPC 방식입니다.
잘 구축된 클라이언트는 이 배열을 읽고 자신을 구성합니다. 네트워크 경로와 일치하는 바인딩을 선택하고, 엔드포인트와 버전을 채우며, 적절한 요청 템플릿을 생성합니다. JSON-RPC에서 REST로 전환하는 것은 단순히 헤더를 변경하는 것이 아닙니다. 엔벨로프 자체가 사라지기 때문에 본문 템플릿도 재생성되어야 합니다. 이전의 0.3 버전 라인은 JSON-RPC 전용이며, 1.0과 와이어 호환(wire compatible)되지 않습니다. 메서드 이름, 파트 모양(part shapes), 그리고 역할 열거형(role enum)이 모두 다릅니다. 카드에 있는 protocolVersion이 권위적입니다.
서명되지 않은 카드가 단독으로 충분하지 않은 이유
발견(Discovery)은 그 카드가 _무엇을 말하는지_에 대한 답만 제공합니다. 누가 그것을 게시했는지에 대해서는 답하지 않습니다. 손상된 경로를 통해 가져오거나, 조용히 재포인팅된 호스트에서 가져온 카드는 설득력 있는 스킬과 함께 공격자가 통제하는 엔드포인트를 광고할 수 있습니다. 이것이 전형적인 에이전트 간 신뢰 문제(agent-to-agent trust problem)입니다. 작업을 보낼 위치를 알려주는 문서 자체가 공격자가 가장 재작성하고 싶어 하는 대상인 것입니다.
방어책은 서명된 카드와 고정된 신뢰 공개 키 세트를 결합한 것입니다. 이 카드는 signatures 배열을 포함하며, 클라이언트는 서비스 레지스트리나 사용자가 제어하는 설정과 같은 신뢰할 수 있는 외부 채널을 통해 이미 얻은 JWKS(JSON Web Key Set)에 대해 적어도 하나의 서명을 검증합니다.
순서대로 중요한 검증 규칙들은 다음과 같습니다:
- 카드 자체의 key-URL 힌트를 절대 따르지 마십시오.
jku,x5u와 같은 헤더나 내장된jwk는 공격자가 카드를 재작성할 수 있는 정확한 지렛대입니다. 신뢰하는 키는 오직 고정된 JWKS에서만 가져와야 합니다. - 비대칭 공개 키만 허용합니다. 대칭 키(
kty: oct)나 사설 필드(d,p,q및 기타 CRT 매개변수)를 포함하는 모든 JSON은 거부되어야 합니다. 검증자는 절대 비밀 정보를 보유해서는 안 됩니다. - 알고리즘을 고정합니다.
ES256,ES384,ES512,RS256,PS256,EdDSA와 같은 명시적인 허용 목록(allowlist)을 사용하고, 분리된 페이로드(b64: false)는 거부해야 합니다. - 원시 바이트가 아닌 정규화된 카드를 검증합니다. 서명된 페이로드는 카드에 대한 표준 JSON 형식이기 때문에, 재형식 지정(reformatting), 공백, 또는 키 순서 변경으로는 합법적인 서명을 무효화할 수 없으며, 단일 스킬 URL을 변경하는 것만으로도 서명이 깨집니다.
kid로 일치시키고 로테이션을 지원합니다. 카드는 회전하는 키에 대한 여러 개의 서명을 포함할 수 있습니다. 클라이언트는 이들을 순회하며 신뢰하는 키 ID와 일치하여 검증되는 첫 번째 서명을 채택합니다. 하나의 좋은 서명만으로 충분하며, 일치하는 것이 없다는 것은 카드가 수정되었거나 신뢰할 수 없는 발행자로부터 왔음을 의미합니다.
고정된 JWKS는 고유한 키 ID와 공개 키만을 가진 익숙한 형태를 가집니다:
{
"keys": [
{
...
이러한 운영상의 이점은 카드 자체가 수정할 수 없는 무언가에 신뢰를 고정한다는 것입니다. 서비스 ID에 이미 신뢰하는 채널을 통해 공개 JWKS를 배포하고, 중첩 기간 동안 이전 키와 새 키 모두로 서명된 새로운 카드를 게시하여 키를 순환하며, '서명되지 않음' 또는 '일치하는 서명이 없음'을 녹색 체크 표시가 아닌 명시적이고 눈에 보이는 상태로 취급합니다.
사전 위임 점검 목록 (A pre-delegation checklist)
실제 작업을 에이전트에게 라우팅하기 전에 다음 사항들을 확인해야 합니다:
- 카드가 예상되는 호스트로부터 HTTPS를 통해 가져와졌으며, 임베디드 자격 증명이나 리다이렉트 추적(redirect chase)이 없었는지.
name과 비어있지 않은skills배열이 깔끔하게 파싱되며, 본문 크기 제한을 초과하지 않았는지.- 최소한 하나의
supportedInterfaces항목이 클라이언트가 사용하는 버전 및 바인딩과 일치하며, 도달 가능한 URL을 가지고 있는지. - 스킬 설명이 라우팅하기에 충분히 구체적인지.
- 카드가 사용자의 고정된 JWKS의 키로 서명되었거나, UI에서 명확하게 서명되지 않았고 신뢰할 수 없음을 표시하는지.
마지막 줄을 건너뛰는 것은 서비스 디스커버리(service discovery)와 낯선 사람의 지도를 맹목적으로 따르는 것 사이의 차이입니다.
The Powerduck 작업 공간은 이 흐름을 직접 구현합니다: 알려진 URL에서 카드를 로드하고, 스킬과 바인딩을 검사하며, 지원되는 인터페이스로부터 활성 전송(active transport)을 전환하고, 알고리즘 및 키 ID가 성공 시 표시되는 JWKS를 사용하여 서명을 검증합니다. 이 뒤에 숨겨진 사양 기반의 로컬 우선 모델은 온라인 데모에서 살펴볼 수 있으며, 에이전트 대상 디자인 컨텍스트는 AI 에이전트를 위한 API 설계에서 확인할 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기