
A2A 프로토콜 인증 분석: 왜 명세가 빈약하며 그로 인해 어떤 허점이 발생하는가
요약
AI 에이전트 간 통신을 위한 A2A 프로토콜의 인증(authn) 및 인가(authz) 명세가 가진 한계와 구조적 특징을 분석합니다. A2A는 자체 인증 메커니즘 대신 기존 표준을 위임하는 프레임워크 역할을 수행하며, 이 과정에서 발생하는 보안 허점과 Agent Card의 역할을 다룹니다.
핵심 포인트
- A2A 프로토콜은 자체 인증 대신 OAuth2, mTLS 등 기존 표준을 위임함
- 인증 메커니즘의 부재가 의도적인 설계인지, 보안 허점을 만드는지 분석
- Agent Card는 에이전트 호출에 필요한 자격 증명 요구사항을 정의하는 핵심 요소임
- 토큰 발행은 A2A 외부의 IdP(Identity Provider)에 의해 수행됨
시작하게 된 계기: 인증 섹션을 열었더니 거의 비어 있었습니다
A2A (Agent2Agent)는 AI 에이전트들이 서로 통신할 수 있게 해주는 프로토콜로 계속해서 등장하고 있습니다. Google은 2025년 4월에 이를 발표했으며, 현재는 Linux Foundation에서 운영하고 있습니다.
"한 에이전트가 다른 에이전트를 호출한다면, 그 안에는 반드시 인증 (authn)과 인가 (authz)가 있어야 한다"고 생각하며 명세의 인증 섹션을 열었습니다. 하지만 결과는 허무했습니다. 어디에도 새로운 인증 메커니즘이 정의되어 있지 않았습니다. 명세에 적힌 내용은 다음과 같습니다: "OAuth2 또는 OpenID Connect 또는 mTLS를 사용하십시오", "HTTP 헤더에 자격 증명 (credentials)을 전송하십시오", "Agent Card에 요구 사항을 공지하십시오". 그것이 전부였습니다.
저의 첫 반응은 "그저 게으른 것인가?"였습니다. 하지만 읽으면 읽을수록, 이러한 빈약함이 의도적이라는 사실이 명확해졌습니다. A2A는 인증 (authn)과 인가 (authz)를 위한 **프레임 (frame)**만을 정의하고, 그 내용은 기존 표준에 위임합니다. 문제는 그 위임 방식이 허점 (holes)을 만든다는 점입니다.
제가 이전에 AI 에이전트 인증에 대해 작성했던 모든 내용 (WIMSE, SPIFFE, ID-JAG, Identity Chaining, Transaction Tokens)이 이곳에서 A2A의 "위임 대상 (delegation target)"으로 나타납니다.
배경: 기억해야 할 세 명의 플레이어
인증 세부 사항을 살펴보기 전에, 최소한의 등장인물을 소개합니다. A2A는 한 에이전트가 다른 에이전트에게 작업을 전달하기 위한 프로토콜입니다. 전송 방식은 HTTP 기반의 JSON-RPC입니다 (gRPC 및 HTTP+JSON 바인딩도 존재합니다).
| 플레이어 | 역할 |
|---|---|
| Client Agent (호출자) | 작업을 전달하는 에이전트. HTTP 요청의 소스 |
| ... |
Agent Card는 반드시 내재화해야 할 요소입니다. "이 에이전트를 호출하기 위해 어떤 자격 증명이 필요한가?"에 대한 답이 전적으로 이 카드에 적혀 있습니다. Client는 먼저 카드를 읽고, 적절한 인증 (auth)을 설정한 다음, 실제 요청을 보냅니다.
A2A 인증의 핵심은 이미 이 그림에 나와 있습니다. 토큰은 A2A 외부에서(외부 IdP에 의해) 발행되며, A2A 자체는 단지 "카드에 요구사항을 명시"하고 "헤더를 통해 자격 증명 (credentials)을 수신"할 뿐입니다.
언제 실제로 A2A라고 부르는가: 일반적인 API 호출과의 차이점
인증 내부 구조를 살펴보기 전에, 무엇이 A2A이고 무엇이 아닌지를 명확히 정의해 봅시다. 이 개념이 혼란스러운 상태로 계속 읽는다면 이후의 설계 결정 사항들이 공중에 붕 뜬 것처럼 느껴질 것입니다. 흔히 하나로 뭉뚱그려 취급되는 세 가지 요소는 다음과 같습니다.
| 당신이 부르는 것 | 전달하는 것 | 명칭 | A2A인가? |
|---|---|---|---|
| LLM (추론 API) | 프롬프트 (prompt) | 단순 모델 API | 아니오. 상대방이 에이전트 (agent)가 아님 |
| ... |
LLM을 직접 호출하는 것은 "모델이 생각하게 만드는 것"입니다. 상대방은 에이전트가 아닙니다. MCP는 "당신의 손과 발(도구, tools)을 사용하는 것"으로, 상대방이 종속적입니다. 오직 A2A만이 "다른 사람의 에이전트에게 일을 맡기는 것"입니다.
일반적인 API 호출과 다른 점
솔직히 말해서, 기계적인 관점에서 A2A는 HTTP + JSON-RPC 그 이상도 이하도 아닙니다. "서비스가 서비스를 호출한다"는 것 외에 마법 같은 일은 일어나지 않습니다. 차이점은 연결 방식이 아니라 상대방이 누구인지, 그리고 어떻게 요청하는지에 있습니다. "이 비용(420 EUR, 고객 접대비)이 규정에 맞는지 확인하고, 하는 김에 USD로 환전해 줘"라는 동일한 작업이라도, 작성 방식에 따라 다르게 보입니다.
일반적인 API 방식 (전체 계약 내용을 알고 있으며 직접 긴밀하게 연결하는 방식):
GET fx-api.com/rate?from=EUR&to=USD
POST policy-service/check {amount: 420, category: "entertainment"}
A2A 방식 (내부 구조를 알지 못하며, 런타임 (runtime)에 카드를 읽고 의도 (intent)를 전달하는 방식):
1. 런타임에 상대방의 에이전트 카드 (Agent Card)를 읽음
(다른 팀 또는 다른 회사의 "비용 준수 에이전트")
-> "나는 규정 확인과 통화 변환을 할 수 있습니다. 인증은 Bearer 토큰을 사용합니다."
...
차이점은 다음 세 가지입니다:
차이점은 다음 세 가지입니다:
- 당신은 정확한 명령이 아닌 "의도(intent)"를 보냅니다.
?from=EUR&to=USD와 같은 단계를 일일이 나열하지 않습니다. 당신은 목표를 전달하고, 상대방(LLM을 보유하고 있으므로)이 그 단계를 스스로 계산합니다. - 내부 구조를 알지 못하며 / 미리 연결(pre-wire)하지 않습니다. 상대방의 API 계약(API contract)에 맞춰 구축하지 않습니다. 런타임(runtime)에 에이전트 카드(Agent Card)를 읽어
솔직히 말해서, 2026년 현재까지도 "이것이 바로 A2A 유스케이스(use case)다"라고 명확히 짚어줄 수 있는 사례는 여전히 적습니다. 실제 운영 환경(Production)에서의 도입은 150개 이상의 조직을 넘어섰으며 공급망(supply chain), 금융 서비스, 보험, 그리고 IT 운영 분야에서 나타나고 있지만, 공개된 자료들은 도입 수치나 산업 분야(verticals)에 머물러 있으며 구체적인 워크플로(workflow) 사례 연구는 부족한 실정입니다. 대표적인 데모는 벤더 간 위임(cross-vendor delegation)입니다: 여행 예약(플래너가 서로 다른 회사의 항공사, 호텔, 렌터카 에이전트에게 위임)과 채용(매니저가 소싱 및 스케줄링 에이전트에게 위임)이 그것입니다. 오늘날 대부분의 "멀티 에이전트(multi-agent)"는 프로세스 내부의 서브 에이전트(sub-agents) 형태이며, 이 경우에는 A2A가 필요하지 않습니다. A2A는 "조직 경계를 넘나드는 에이전트 간의 대화"가 실현될 때 가치를 발휘하며, 이 표준은 바로 그 미래에 베팅하고 있는 것입니다.
이것으로 "A2A가 무엇이며 언제 사용하는가"에 대한 설명은 끝났습니다. 이제 진짜 주제인 인증(authn)과 인가(authz)로 넘어가겠습니다. 인증 설계가 현재와 같은 형태를 띠는 이유는 바로 경계를 넘나드는 것이 전제 조건이기 때문입니다.
설계 철학: "에이전트를 일반적인 앱처럼 취급하라"
A2A의 인증 설계는 단 하나의 원칙에서 비롯됩니다.
에이전트를 특별한 무언가가 아니라 **일반적인 엔터프라이즈 애플리케이션(enterprise applications)**으로 취급하라.
일반적인 웹 앱들이 서로의 API를 호출할 때 어떻게 인증할까요? Authorization: Bearer 헤더에 OAuth 토큰을 넣거나, 헤더에 API 키를 넣거나, mTLS와 함께 클라이언트 인증서(client cert)를 제시합니다. A2A는 이를 에이전트에 그대로 적용할 뿐입니다. 새로운 것을 발명하지 않습니다.
이 원칙으로부터 네 가지 구체적인 설계 결정이 도출됩니다. 이것이 A2A 인증의 전체적인 모습입니다. 순서대로 살펴보겠습니다:
- 페이로드(payload)에 신원(identity)을 담지 마라. HTTP 전송 계층(transport layer)에서 신원을 확립하라.
- 에이전트 카드(Agent Card)에 인증 요구사항을 공지하라.
- 자격 증명(credentials)은 대역 외(out-of-band, A2A의 범위를 벗어난 방식)로 획득하라.
- 인가(Authorization)는 스킬별 범위(per-skill scope)를 기반으로 한다. 하지만 실제 강제 집행(enforcement)은 외부 인프라에 맡긴다.
결정 1: 페이로드에 신원을 담지 마라
명세(spec)는 다음과 같이 규정합니다.
A2A 프로토콜 페이로드(JSON-RPC 메시지)는 사용자 또는 클라이언트의 신원 정보를 직접 포함하지 않는다.
"페이로드에 포함되지 않음(Not in the payload)"이라는 표현은 오해하기 쉬우므로, 실제 HTTP 요청을 확인해야 합니다. A2A 트래픽은 HTTP를 통해 전달되는 JSON-RPC이며, 다음과 같이 분리됩니다.
POST /a2a HTTP/1.1
Host: remote-agent.example.com
Authorization: Bearer eyJhbGci... # "누가 호출하는가" (신원 정보)가 여기에 위치함
...
페이로드(JSON-RPC 본문)는 오직 "무엇을 수행하고 싶은가"만을 담습니다. "누구인가"는 HTTP 헤더의 Authorization 토큰(또는 mTLS 클라이언트 인증서)에 의해 전달됩니다. 이것이 바로 "페이로드에 신원 정보를 넣지 마라"는 말의 의미입니다.
A2A가 사용하지 않는 설계 방식과 대조해 보면 명확해집니다. 만약 페이로드에 신원 정보를 넣었다면 다음과 같은 형태였을 것입니다.
{
"jsonrpc": "2.0",
"method": "message/send",
...
A2A는 이러한 형태를 피했습니다. 여기에는 세 가지 이유가 있으며, 이것이 바로 "설계 결정(design decision)"을 구성하는 요소입니다.
- 본문 내부의 "누구"는 자기주장에 불과합니다. 누구나
callerId: "admin"이라고 작성할 수 있습니다. 반면, 헤더 토큰은 IDP(Identity Provider)에 의해 서명되므로 위조할 수 없습니다. 실제로 검증 가능한 신원은 오직 헤더 측에만 실려 있습니다. - 검증 작업을 인프라로 오프로딩(offload)할 수 있습니다.
Authorization헤더를 읽는 것은 API 게이트웨이(API Gateway) / 리버스 프록시(reverse proxy) / IAM의 전문 분야입니다. 본문(애플리케이션 특정 JSON)을 파싱할 필요가 없습니다. 따라서 A2A SDK 자체는 "누가 호출하는지"를 알 필요가 없습니다(신원 불가지론적(identity-agnostic) 상태를 유지합니다). - 이중 장부(double bookkeeping)를 방지합니다. HTTP에는 이미 인증을 위한 자리(헤더)가 있습니다. 본문에도 이를 넣으면 서로 일치하지 않을 수 있는 두 개의 지점이 생기게 됩니다.
여기서 "전송 계층(transport layer)"은 엄격한 의미의 OSI L4를 의미하지 않습니다. 이는 "애플리케이션 메시지(JSON-RPC)를 감싸는 HTTP 요청 봉투(헤더)"에 가깝습니다. 봉투에는 ID를, 내용물에는 비즈니스 로직을 담는 것입니다.
이러한 분리는 나중에 발생하는 "허점(holes)"의 원인이 되기도 합니다. 만약 신원(identity) 정보가 페이로드(payload)에 포함되지 않는다면, A2A 메시지 자체는 "user-123을 대신하여 동작 중"이라는 컨텍스트(context)를 전달할 수 없습니다. 따라서 A에서 B로, B에서 C로 홉(hop)을 거치며 권한을 위임할 때, "원래 사용자가 누구인지"를 전달하는 작업은 A2A의 범위를 벗어나게 됩니다 (신원 체이닝 (Identity Chaining) / 트랜잭션 토큰 (Transaction Tokens)).
결정 2: 에이전트 카드(Agent Card)에 인증 요구사항 광고
"이 에이전트를 호출하려면 Bearer 토큰(scope read:tasks)이 필요합니다" 또는 "아니요, 우리는 API 키를 사용합니다"와 같이, 요구사항은 에이전트마다 다릅니다. A2A는 에이전트 카드의 securitySchemes 및 security 필드에 이를 선언하도록 합니다. 카드를 읽으면 무엇을 준비해야 할지 알 수 있습니다. 자세한 내용은 아래와 같습니다.
결정 3: 대역 외(out-of-band) 방식으로 자격 증명 획득
명세(spec)는 자격 증명(credentials)이 어떻게 "사용"되는지는 결정하지만, 어떻게 "획득"되는지는 결정하지 않습니다.
클라이언트 에이전트가 원격 에이전트에 연결하기 위한 자격 증명은 A2A 프로토콜의 범위를 벗어난 대역 외(out-of-band) 프로세스를 통해 클라이언트 에이전트에 의해 획득됩니다.
토큰을 얻는 방법(OAuth 권한 부여 코드 흐름(authorization-code flow)을 실행하거나, 클라이언트 자격 증명(client credentials)으로 가져오는 방식 등)은 A2A 외부의 일입니다. 에이전트는 "이미 토큰을 가지고 있다"는 전제하에 동작합니다.
결정 4: 스킬별 범위 권한 부여(per-skill scope authorization), 외부에서 강제
A2A 에이전트는 에이전트 카드에 자신의 "스킬(skills)"(할 수 있는 일)을 나열합니다. 권한 부여(Authorization)는 스킬별로 적용될 수 있습니다.
액세스는 스킬 단위로 제어될 수 있습니다 ... 특정 OAuth 스코프(scopes)는 인증된 클라이언트가 특정 스킬은 호출할 수 있지만 다른 스킬은 호출할 수 없도록 허용해야 합니다.
하지만 "스코프를 확인하고 거부"하는 구현은 A2A가 수행하는 일이 아닙니다. 이 또한 외부 작업(게이트웨이(Gateway), IAM, 또는 앱의 미들웨어(middleware))입니다. A2A 명세는 단지 "그렇게 하라"고만 명시합니다.
"A2A가 정의하는 것"과 "A2A가 위임하는 것" 분류하기
지금까지의 결정 사항들을 "A2A가 직접 결정하는 것"과 "외부 표준으로 위임하는 것"으로 깔끔하게 분류하면, A2A 인증의 본질이 드러납니다.
왼쪽(초록색)은 A2A의 "프레임 (frame)"이며, 오른쪽(노란색)은 "위임 대상 (delegation targets)"입니다. A2A 인증을 이해한다는 것은 거의 전적으로 왼쪽의 프레임을 이해하는 것과 같습니다. 오른쪽은 다른 기사들에서 다루는 표준들(ID-JAG, Identity Chaining, WIMSE 등) 그 자체입니다.
이제부터 왼쪽 프레임을 순서대로 해부해 보겠습니다.
에이전트 카드 (Agent Card) 해부: 5가지 보안 스킴 (SecurityScheme) 유형
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기