AI SDK 7의 스코프가 지정된 도구 컨텍스트(Scoped Tool Context) 학습: 두 도구 간의 비밀 경계 설정
요약
Vercel AI SDK 7에서 도입된 '스코프가 지정된 도구 컨텍스트(Scoped Tool Context)' 기능을 소개합니다. 이 기능은 각 도구에 필요한 데이터만 선언적으로 제공하여, 제3자 도구가 불필요한 비밀 정보나 설정값에 접근하는 것을 방지하는 보안 경계를 설정합니다.
핵심 포인트
- contextSchema를 통해 도구별로 필요한 데이터 구조를 정의할 수 있음
- 도구 간 데이터 격리를 통해 보안 사고 및 권한 확장 위험 방지
- 전역 환경 변수(process.env)를 통째로 전달하는 위험한 패턴 지양
- 도구 실행 전 컨텍스트 검증을 통해 잘못된 데이터 유입 차단
Vercel의 AI SDK 7은 스코프가 지정된 도구 컨텍스트(scoped tool context)를 추가했습니다. 즉, 도구는 contextSchema를 선언할 수 있고, 호출자는 toolsContext를 통해 도구별 값을 제공할 수 있습니다. 이 기능의 목적은 실용적입니다. 제3자 도구(third-party tools)가 에이전트가 보유한 모든 비밀 정보나 설정 값을 받을 필요가 없도록 하기 위함입니다.
주요 출처: Vercel, “AI SDK 7 is now available”.
이 기능을 작은 보안 연습으로 바꾸어 보겠습니다. 우리는 두 개의 도구를 만들 것입니다:
lookupOrder는 내부 주문 서비스(order-service) URL을 받을 수 있습니다.createTicket은 지원 토큰(support token)을 받을 수 있습니다.- 두 도구 모두 서로의 값을 받아서는 안 됩니다.
설정 (Setup)
새 프로젝트를 사용하고, lockfile에 실제로 설치된 버전을 고정하세요:
mkdir scoped-tools && cd scoped-tools
npm init -y
npm install ai zod
...
demo.ts를 생성합니다:
import { tool } from 'ai';
import { z } from 'zod';
...
정확한 실행 콜백(execution callback) 타입은 SDK 릴리스에 따라 진화할 수 있으므로, 현재의 AI SDK 7 문서와 lockfile을 신뢰할 수 있는 소스로 사용하십시오. 중요한 형태는 경계(boundary)입니다. 각 컨텍스트 객체는 하나의 도구에 대해 검증됩니다.
실행하세요:
npx tsx demo.ts
예상 출력 형태는 다음과 같습니다:
{
"order": {
"orderId": "A-17",
...
네트워크 요청은 수행되지 않습니다. 이 레슨은 외부 서비스가 아닌 데이터 흐름(data flow)을 테스트합니다.
실패 연습 추가 (Add the failure exercise)
이제 의도적으로 잘못된 컨텍스트를 제공해 봅니다:
const wrong = { supportToken: 'support_demo_token' };
const parsed = z.object({ baseUrl: z.string().url() }).safeParse(wrong);
console.log(parsed.success); // false
원하는 결과는 도구 실행 **전(before)**에 거부되는 것입니다. 만약 오케스트레이션 레이어(orchestration layer)가 전역 환경 객체(global environment object)를 조용히 제공한다면, 두 도구 모두 두 비밀 정보를 보게 될 것이며 연습은 실패한 것입니다.
리뷰 중에 이 표를 작성하세요:
| 도구 (Tool) | 허용된 컨텍스트 (Allowed context) | 금지된 컨텍스트 (Forbidden context) | 컨텍스트 누락 시 동작 (Missing-context behavior) |
|---|---|---|---|
| lookupOrder | base URL | support token | 호출 전 거부 (reject before call) |
| createTicket | support token | order URL, 데이터베이스 자격 증명 (database credentials) | 호출 전 거부 (reject before call) |
왜 process.env를 전달하면 안 되나요?
이 방식은 편리하지만 위험합니다:
// 이 패턴을 피하세요
execute(input, { context: process.env })
이는 향후 도구가 변경될 때 암묵적인 권한 확장 (privilege expansion)을 초래합니다. 날씨 API 키만 필요했던 패키지가 갑자기 데이터베이스, 배포, 결제 자격 증명 (credentials)을 읽을 수 있게 될 수 있습니다.
스코프가 지정된 컨텍스트 (Scoped context)는 코드 리뷰어에게 가시적인 권한 목록 (capability list)을 제공합니다. 이것이 비밀 정보를 암호화하거나, 허용된 도구가 자신의 토큰을 유출하는 것을 방지하거나, 샌드박싱 (sandboxing)을 대체하는 것은 아닙니다. 여전히 로그 마스킹 (log redaction), 아웃바운드 네트워크 제어 (outbound network controls), 토큰 로테이션 (token rotation), 그리고 테스트가 필요합니다.
확장 연습
다음만을 포함하는 sendEmail 도구를 추가하세요:
{ senderId: string; allowedDomains: string[] }
그 다음 세 가지 케이스를 테스트하세요:
- 허용된 목적지로의 전송이 성공하는 경우;
- 목록에 없는 도메인에 대해 전송 전 실패하는 경우;
allowedDomains필드가 누락되어 스키마 검증 (schema validation)에 실패하는 경우.
세 가지 경우 모두에 대해 구조화된 증거 (structured evidence)를 출력하세요. 실제 이메일 자격 증명 (credential)을 사용하지 마세요.
더 넓은 교훈은 AI 도구가 하나의 권한 경계 (capability boundary)라는 점입니다. AI SDK 7은 그 경계를 더 쉽게 표현할 수 있게 해주지만, 컨텍스트를 좁고, 검증 가능하며, 관찰 가능한 (observable) 상태로 유지할지 여부는 여전히 개발자가 결정해야 합니다.
현재 사용 중인 에이전트의 전역 환경 (global environment) 값 중, 대부분의 도구 호출에서 제거하기 가장 쉬운 값은 무엇인가요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기