본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 20. 23:28

AI 에이전트를 위한 사용자별 OAuth: 중요성과 고려해야 할 사항

요약

AI 에이전트가 사용자의 개인 데이터와 서비스에 안전하게 접근하기 위해서는 단일 API 키 방식이 아닌 사용자별 OAuth 방식이 필수적입니다. 본 글은 공유 자격 증명 사용 시 발생하는 보안 취약점인 '혼동된 대리인 문제'를 설명하고, 명시적 동의와 범위 제한 권한을 통해 이를 해결하는 사용자별 OAuth의 중요성을 분석합니다.

핵심 포인트

  • 단일 API 키 방식은 사용자 식별 및 개별 권한 취소가 불가능하여 보안에 취약함
  • 사용자별 OAuth는 명시적 동의, 범위 제한 권한(Scoped Permissions), 짧은 토큰 유효 기간을 제공함
  • 공유 자격 증명 사용 시 발생하는 '혼동된 대리인 문제(Confused Deputy Problem)'를 방지해야 함
  • 에이전트가 사용자의 신원(Identity)을 바탕으로 승인된 범위 내에서만 동작하도록 설계해야 함

AI 에이전트(AI agents)는 기존 소프트웨어가 결코 넘지 않았던 선을 넘고 있습니다. 이들은 사용자의 Slack을 읽고, 이메일 초안을 작성하며, 코드를 푸시하고, CRM을 업데이트하며, 송장(invoices)을 결제합니다. 이를 수행하기 위해서는 애플리케이션이나 회사가 아닌, 특정 개인에게 속한 시스템에 대한 접근 권한(keys)이 필요합니다. 이것이 바로 에이전트 맥락에서 사용자별 OAuth (per-user OAuth)가 존재하는 근본적인 이유이며, 사이드 프로젝트와 고객이 자신의 Gmail 계정을 믿고 맡길 수 있는 서비스 사이의 차이점입니다. 이 글에서는 AI 에이전트에게 사용자별 OAuth가 무엇을 의미하는지, 공유 자격 증명(shared credentials)이 규모가 커질 때 왜 무너지는지, 새롭게 등장하는 표준은 어떤 모습인지, 그리고 이를 처리할 플랫폼을 선택할 때 사용할 정확한 체크리스트를 분석합니다. 또한, 여러분이 직접 스택을 구축할 필요가 없도록 Composio가 이러한 각 문제에 어떻게 접근하는지도 보여드릴 것입니다.

대부분의 팀이 시작하는 방식의 문제점
대부분의 에이전트 프로토타입(prototypes)은 환경 변수(environment variable)에 있는 단일 API 키로 시작합니다. 이는 한 명의 개발자가, 한 대의 머신에서, 하나의 데모를 위해 사용할 때는 작동합니다. 하지만 실제 사용자가 나타나는 순간, 모델은 무너집니다. API 키는 동작 뒤에 있는 사용자가 아니라 호출하는 애플리케이션을 식별합니다. 에이전트의 모든 요청은 다운스트림 서비스(downstream service)에 동일하게 보입니다. 동의(consent)의 개념이 없고, 사용자별 스코핑(scoping)이 없으며, 모든 사람의 권한을 무효화하지 않고 한 사람의 액세스만 취소할 방법이 없고, "이 동작은 Sarah가 에이전트에게 요청했기 때문에 발생했다"라고 말해줄 감사 추적(audit trail)도 없습니다.

이는 빠르게 심각한 보안 문제로 이어집니다. 만약 에이전트 코드가 실수로 잘못된 사용자 식별자(user identifier)를 전달하거나, 공격자가 에이전트를 속여 권한을 부여하지 않은 사용자의 데이터를 요청하게 만든다면, 에이전트에게는 프로토콜 수준의 방어 기제가 없습니다. 이것이 전형적인 혼동된 대리인 문제(confused deputy problem)이며, 작업당 수십 개의 도구 호출(tool calls)을 체이닝하는 자율 시스템(autonomous systems)에서는 끔찍하게 확장됩니다. AI 에이전트 인프라에 관한 Composio의 자체 가이드에서는 이를 "인증의 벽(Authentication Wall)"에 부딪히는 것이라고 부릅니다. 이는 유망했던 프로토타입이 더 이상 유망하지 않게 되는 순간입니다.

사용자별 OAuth가 실제로 해결하는 것
사용자별 OAuth는 모델을 뒤집습니다.

에이전트가 하나의 마스터 자격 증명 (Master Credential)을 보유하는 대신, 각 사용자가 자신의 계정과 연결된 범위가 제한되고 취소 가능한 토큰 (Scoped, Revocable Token)을 에이전트에게 부여합니다. 에이전트는 사용자가 승인한 범위 내에서, 사용자가 허용하는 동안 해당 사용자의 신원 (Identity)으로 동작합니다. 구체적으로, 이를 통해 다음과 같은 이점을 얻을 수 있습니다:

  • 명시적 동의 (Explicit Consent): 사용자는 에이전트가 무엇을 요청하는지 확인하고 이를 승인합니다.
  • 접근 권한 가정 금지 (No Assumed Access).
  • 범위 제한 권한 (Scoped Permissions): 토큰을 전체 계정 제어 대신 특정 리소스에 대한 읽기 전용 (Read-only) 액세스로 제한할 수 있습니다. 에이전트에게 읽기 권한만 필요하다면, 딱 그만큼의 권한만 부여됩니다.
  • 짧은 유효 기간 (Short Lifetimes): 액세스 토큰 (Access Tokens)은 몇 분에서 한 시간 내에 만료됩니다. 리프레시 토큰 (Refresh Tokens)은 순환 (Rotate)됩니다. 유출된 토큰은 짧은 시간 동안만 위험할 뿐, 영구적이지 않습니다.
  • 선택적 취소 (Selective Revocation): 한 사용자의 권한 부여를 취소해도 다른 모든 사용자에게 영향을 주지 않습니다.
  • 감사 로그 내 신원 확인 (Identity in the Audit Log): 모든 작업은 특정 사용자로 추적되며, 이는 SOC 2, HIPAA, ISO 27001에서 실제로 요구하는 사항입니다.
  • 멀티테넌트 격리 (Multi-tenant Isolation): 각 사용자의 토큰은 자체 버킷에 저장되며, 저장 시 암호화 (Encrypted at rest)됩니다. 한 테넌트 (Tenant)의 워크플로에서 발생한 버그가 다른 테넌트의 데이터를 노출시키지 않습니다. 마지막 항목은 사람들이 생각하는 것보다 훨씬 중요합니다.

Composio의 사용자 및 세션 모델은 정확히 이 아이디어를 중심으로 구축되었습니다. 즉, 사용자는 귀하의 앱에서 제공하는 식별자 (Identifier)이며, 모든 연결은 해당 사용자의 ID 아래에 존재하고, 연결은 사용자 간에 완전히 격리됩니다. 동일한 에이전트 코드가 수천 명의 사용자에게 서비스를 제공하면서도, 그 누구도 서로의 데이터에 접근할 수 없게 합니다.

이러한 흐름을 실제로 형성하고 있는 표준들
프로토콜 계층 (Protocol Layer)은 빠르게 움직이고 있습니다. 알아둘 가치가 있는 세 가지 사항이 있습니다.

PKCE가 필수인 OAuth 2.1
OAuth 2.1은 OAuth 2.0을 현재의 베스트 프랙티스(Best-practice)에 맞춰 통합한 것입니다. 이는 PKCE (Proof Key for Code Exchange)를 필수 사항으로 만들고, 보안성이 낮은 오래된 흐름을 제거합니다. PKCE는 특히 에이전트에게 중요한데, 대부분의 에이전트는 클라이언트 비밀 (Client Secret)을 안정적으로 숨길 수 없는 환경에서 실행되는 퍼블릭 클라이언트 (Public Clients)이기 때문입니다. PKCE는 공격자가 흐름 중간에 권한 부여 코드 (Authorization Code)를 가로채는 것을 방지합니다.

평가 중인 플랫폼이 PKCE를 강제하지 않는다면, 이는 위험 신호(red flag)입니다. MCP 권한 부여 사양 (The MCP Authorization spec): Model Context Protocol 권한 부여 사양은 2025년에 OAuth를 표준으로 공식화했습니다. 이 사양은 PKCE를 포함한 OAuth 2.1을 의무화하며, RFC 8414를 통한 권한 부여 서버 메타데이터 (Authorization Server Metadata) 검색을 요구하고, RFC 7591을 통한 동적 클라이언트 등록 (Dynamic Client Registration)을 지원합니다. 2025년 11월 업데이트에서는 단계별 권한 부여 (step-up authorization) 기능이 추가되어, 초기 토큰에 과도한 권한을 부여하는 대신 실제 작업이 필요할 때만 클라이언트가 추가적인 스코프 (scopes)를 요청할 수 있도록 했습니다. 또한 이 사양은 해결해야 할 실제 보안 위기 상황을 겪기도 했습니다. 2025년 말, Obsidian Security의 보안 연구원들은 여러 유명 조직의 원격 MCP 서버에서 원클릭 계정 탈취 (account takeover) 취약점을 공개했습니다. 근본 원인은 많은 MCP 서버가 상위 SaaS 권한 부여 서버와 통신하기 위해 단일 정적 client_id를 사용하는 OAuth 프록시 (proxy)로 구현되었기 때문입니다. 어떤 사용자가 해당 공유 client_id에 대해 동의하면, SaaS 권한 부여 서버는 그 결정을 캐싱(cache)합니다. 공격자는 MCP 계층의 동의 과정을 직접 완료한 뒤, 조작된 권한 부여 링크를 피해자에게 보낼 수 있으며, 상위 서버는 해당 client_id를 이전에 본 적이 있기 때문에 동의 프롬프트를 완전히 건너뛰게 됩니다. 결과적으로 권한 부여 코드 (authorization code)가 공격자의 리다이렉트 URI (redirect URI)로 발급됩니다. 해결책은 프록시 계층에서의 클라이언트별 식별 (per-client identity) 및 엄격한 동의 처리입니다. Composio의 툴 라우터 (Tool Router)는 공유 엔드포인트 대신 각 세션에 보안이 적용된 사용자 범위 MCP URL을 제공함으로써, 구조적으로 이러한 유형의 공격을 회피합니다. AI 에이전트를 위한 IETF "On-Behalf-Of" 초안: 에이전트 위임을 위해 OAuth를 구체적으로 확장하는 활발한 IETF 초안인 draft-oauth-ai-agents-on-behalf-of-user가 있습니다. 이 초안은 동의 화면에 (앱뿐만 아니라) 에이전트의 신원을 표시할 수 있도록 requested_actor 파라미터를 추가하고, 에이전트가 권한 부여 코드를 교환할 때 스스로를 인증할 수 있도록 actor_token 파라미터를 추가합니다.

그 결과, 전체 위임 체인(delegation chain)을 기록하는 액세스 토큰(access token)이 생성됩니다. 즉, 사용자가 이 클라이언트 애플리케이션에 권한을 위임했고, 이 애플리케이션이 다시 이 특정 에이전트에게 권한을 위임했다는 사실이 문서화됩니다. 이러한 체인 덕분에 사후 감사(after-the-fact auditing)가 가능해집니다. 해당 초안은 2025년 8월 기준 리비전(revision) 02 상태이며 아직 워킹 그룹(working group)에서 채택되지는 않았으나, 프로토콜 계층이 나아갈 방향을 명확히 제시하고 있습니다. 멀티홉 위임(Multi-hop delegation, 동일한 사용자를 대신하여 에이전트 A가 에이전트 B를 호출하는 방식)은 여전히 명세(spec) 내에서 해결되지 않은 문제입니다.

프로덕션 아키텍처: 팀들이 실패하는 지점
액세스 토큰을 얻는 것은 쉬운 부분입니다. 프로덕션 규모(production scale)에서 운영하는 것이 대부분의 자체 구축 OAuth 구현체가 무너지는 지점입니다. 주로 다음 다섯 가지 사항에서 문제가 발생합니다.

토큰 저장(Token storage). 토큰은 저장 시 암호화(encrypted at rest)되어야 하며, 테넌트(tenant)별로 격리되어야 하고, 절대 로그에 남겨서는 안 되며, LLM 컨텍스트(context)에 포함되어서도 안 됩니다. 마지막 항목은 직관적이지 않지만 매우 중요합니다. 만약 프롬프트(prompt)에 리프레시 토큰(refresh token)을 넣는다면, 프롬프트 인젝션(prompt injection) 공격을 통해 토큰이 유출될 수 있습니다. 이때 사용해야 하는 패턴은 브로커 자격 증명(brokered credentials)입니다. 이 방식에서는 LLM이 토큰을 전혀 보지 못하며, 별도의 서비스가 실제 API 호출을 수행합니다. Composio의 보안 인프라 가이드는 이 패턴을 직접적으로 설명합니다. 즉, LLM이 Composio에 특정 동작 수행을 요청하면, Composio가 저장된 자격 증명을 사용하여 업스트림 API(upstream API)를 호출하며, 토큰은 모델의 컨텍스트 윈도우(context window)에 절대 들어가지 않습니다.

리프레시 처리(Refresh handling). 리프레시 토큰은 선제적인 조정(proactive coordination)이 필요합니다. 401 에러를 기다렸다가 리프레시를 시도하는 방식은 레이스 컨디션(race conditions), 연쇄적인 재시도(cascading retries), 그리고 불안정한 백그라운드 작업(background jobs)을 유발합니다. Composio의 인증 문서에 따르면, Composio는 리프레시를 자동으로 처리하며 여러 번의 리프레시 시도가 실패한 후에만 연결을 만료(EXPIRED) 상태로 표시합니다.

스코프 규율(Scope discipline). Composio는 각 툴킷(toolkit)에 대해 합리적인 기본 스코프(default scopes)를 요청하지만, 사용자 정의 인증 설정(custom auth configs)을 통해 이를 재정의할 수 있도록 허용합니다. 스코프를 엄격하게 제한하면 문제가 발생했을 때 피해 범위(blast radius)를 줄일 수 있습니다. 대부분의 API는 여전히 세분화되지 않은 거친 입도(coarse-grained)의 스코프를 가지고 있으며, 이는 규율을 지키더라도 에이전트가 과도한 권한을 부여받는 경향이 있음을 의미합니다.

이에 대한 완화 방법은 토큰 수명을 짧게 유지하는 것과 API가 지원하는 경우 도구별 스코프 (per-tool scoping)를 적용하는 것입니다. 브랜딩 및 동의 화면(consent screens) 또한 중요합니다. 사용자가 OAuth 동의 화면에서 "YourProduct가 귀하의 Gmail에 액세스하려고 합니다" 대신 "Composio가 귀하의 Gmail에 액세스하려고 합니다"라는 문구를 보게 되면, 전환율이 떨어지고 신뢰도가 타격을 입습니다. Composio의 화이트 라벨링 (white-labeling) 지원을 통해 귀하의 OAuth 앱 자격 증명을 가져올 수 있으며, 이를 통해 동의 화면에 귀하의 브랜드가 표시되도록 할 수 있습니다. 프로토타이핑에는 관리형 앱 (managed apps)을 사용하고, 프로덕션 환경에는 귀하의 자체 자격 증명을 사용하십시오. 사용자당 다중 계정 (Multi-account per user) 문제도 있습니다. 일부 사용자는 개인용 Gmail과 업무용 Gmail을 모두 연결합니다. 플랫폼은 사용자가 두 계정 간에 사용자 ID (user ID)를 공유하도록 강제하지 않으면서도 이를 모델링할 수 있어야 합니다. Composio는 사용자 ID 아래에 연결된 계정 ID (connected account ID)를 계층화하여 이를 처리하므로, 사용자 및 세션 가이드에 문서화된 바와 같이 단일 사용자가 동일한 툴킷에서 여러 계정을 가질 수 있습니다.

에이전트를 위한 사용자별 OAuth 플랫폼을 선택할 때 고려해야 할 사항: 만약 제공업체를 평가하고 있다면, 다음은 타협할 수 없는 필수 사항들입니다:

  • 저장 시 암호화 (encryption at rest)를 포함한 사용자별 토큰 격리 및 테넌트 간 누출(cross-tenant leakage) 방지
  • 모든 OAuth 흐름에 PKCE가 필수적으로 적용된 OAuth 2.1
  • 클라이언트에 의존하지 않는 자동적이고 선제적인 토큰 갱신 (token refresh)
  • 회전하는 리프레시 토큰 (rotating refresh tokens)을 사용하는 짧은 수명의 액세스 토큰
  • 각 통합(integration)이 최소 권한을 사용하도록 하는 세밀한 스코프 (granular scope) 구성
  • LLM이 원시 토큰을 절대 볼 수 없도록 하는 중개된 자격 증명 (Brokered credentials)
  • 다른 사용자에게 영향을 주지 않는 선택적 사용자별 권한 취소 (revocation)
  • 컴플라이언스를 위한 위임 체인 (delegation chain) 상의 감사 추적 (Audit trail)
  • 프로덕션 신뢰를 위한 화이트 라벨 OAuth 동의 화면
  • 필요할 때만 새로운 스코프를 요청하는 단계별 인증 (Step-up authorization)
  • 동일한 앱 내 개인 및 업무용 계정을 위한 사용자당 다중 계정 지원
  • 모든 MCP 호환 클라이언트가 동일한 인증 레이어를 사용할 수 있는 MCP 네이티브 배포
  • 엔터프라이즈 고객을 위한 기본 요건인 SOC 2 Type 2 및 ISO 27001 준수
  • 주요 프레임워크(LangChain, CrewAI, OpenAI Agents SDK, Claude Agent SDK, Mastra, Vercel AI SDK, LlamaIndex) 전반에 걸친 SDK 지원

Composio는 현재 이 목록의 모든 항목을 충족합니다.

Composio는 500개 이상의 툴킷 (toolkits)을 지원하며, 사용자 범위 토큰 (user-scoped tokens)을 통해 엔드 투 엔드 (end-to-end) OAuth를 처리합니다. 또한 SOC 2 Type 2 및 ISO 27001을 준수하며, 직접적인 SDK 및 MCP 서버 (MCP server)로 모두 작동합니다. 전체 기능 상세 내역은 AgentAuth 제품 페이지와 비교 가이드에서 확인할 수 있습니다.

코드로 보는 구현 방식

Composio를 사용한 사용자별 OAuth (Per-user OAuth)는 단 몇 줄의 코드로 압축됩니다. 아래 패턴은 Composio의 인증 도구 가이드 (authenticating tools guide)에 문서화된 현재 SDK를 따릅니다.

먼저, SDK를 설치하고 API 키를 설정하세요:

pip install composio
export COMPOSIO_API_KEY = your_api_key_here

특정 사용자에 대한 OAuth 흐름 (OAuth flow)을 트리거하려면, 호스팅된 연결 링크 (Connect Link) 패턴을 사용합니다. 이는 사용자가 브라우저에서 인증을 완료하기 위해 열어야 하는 리다이렉트 URL (redirect URL)을 반환합니다:

from composio import Composio
composio = Composio ( api_key = " your_api_key " )

Composio 대시보드에서 "AUTH CONFIG ID"를 사용하세요

auth_config_id = " your_auth_config_id "

애플리케이션 내 각 사용자에 대한 고유 식별자를 사용하세요

user_id = " user_1349_129_12 "
connection_request = composio . connected_accounts . link ( user_id = user_id , auth_config_id = auth_config_id , callback_url = " https://your-app.com/callback " )
redirect_url = connection_request . redirect_url
print ( f " 계정 인증을 위해 다음을 방문하세요: { redirect_url } " )

사용자가 흐름을 완료하면, Composio는 토큰 (tokens)을 저장하고 이를 해당 사용자 ID (user ID)와 연결하며 리프레시 (refresh)를 자동으로 처리합니다. 에이전트 (agent) 코드는 토큰에 직접 접근하지 않습니다.

특정 사용자에게 범위가 지정된 도구 (tools)를 가져오려면, 동일한 사용자 ID를 전달하면 됩니다:

from composio import Composio
composio = Composio ( api_key = " your_api_key " )
user_id = " user_1349_129_12 "

도구는 이 사용자의 연결된 계정에 자동으로 범위가 지정됩니다

tools = composio . tools . get ( user_id = user_id , toolkits = [ " GITHUB " , " GMAIL " ])

동일한 워크플로 (workflow)를 실행하는 두 사용자는 투명하게 적용된 서로 다른 두 세트의 자격 증명 (credentials)을 받게 됩니다:

tools_user_1 = composio . tools .

get ( user_id = " user_1 " , toolkits = [ " GITHUB " ]) tools_user_2 = composio . tools . get ( user_id = " user_2 " , toolkits = [ " GITHUB " ]) # 에이전트가 호출될 때 각 도구 세트는 해당 사용자의 자격 증명 (credentials)을 사용합니다.

이것이 사용자별 OAuth (per-user OAuth)의 핵심입니다. 인증 (auth) 레이어가 플랫폼 내부로 사라지기 때문에, 에이전트 코드는 수천 명의 사용자에게 서비스를 제공하는 중일지라도 마치 단 한 명의 사용자와 대화하는 것처럼 읽힙니다. LLM 프레임워크를 사용한 전체 작동 예제는 Composio 문서의 프레임워크별 퀵스타트 (quickstart) 가이드를 참조하십시오.

핵심 요약 (The takeaway)
사용자별 OAuth는 에이전트 제품에 나중에 덧붙이는 기능이 아닙니다. 이는 귀하의 에이전트가 실제로 실제 고객에게 서비스를 제공할 수 있는지 여부를 결정하는 기반입니다. 공유 API 키 (Shared API keys)는 귀하의 한계를 단일 사용자 데모 수준으로 제한합니다. 반면 사용자별 OAuth는

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0