Connections: managed credentials and per-caller identity for Managed Deep Agents
Quick Summary
Managed Deep Agents v0.7.0+의 Connections는 자격 증명을 LangSmith 워크스페이스에서 관리하고, 공유 계정과 호출자별 신원을 구분하면서 OAuth 인증 처리를 대신한다.
🖼️ 인포그래픽

🖼️ 4컷 인포그래픽

💡 한 줄 요약
Managed Deep Agents v0.7.0+의 Connections는 자격 증명을 LangSmith 워크스페이스에서 관리하고, 공유 계정과 호출자별 신원을 구분하면서 OAuth 인증 처리를 대신한다.
📌 핵심 요약
- Connections는 이름인 slug로 실행 시 조회하는 자격 증명을 LangSmith 워크스페이스에 저장하며, 저장된 비밀값을 교체하거나 폐기할 때 코드 수정이나 재배포가 필요하지 않다.
- 연결의 소유자와 자격 증명 유형은 독립적이다. 에이전트 소유는 배포의 모든 호출자가 공유하고 사용자 소유는 호출자별로 결정되며, 각각 정적 비밀값과 OAuth 권한 부여를 사용할 수 있다.
- Tavily 예시는 공유 검색 키를 사용하고, GitHub 예시는 사용자별 OAuth 토큰으로 비공개 저장소 접근과 이슈 작성자를 구분한다. GitHub의 --scope repo는 기본 read:user에 추가되는 것이 아니라 전체 범위를 대체한다.
- Linear MCP처럼 OAuth 클라이언트를 자동 등록하는 서버는 URL만으로 연결할 수 있다. Managed Deep Agents는 필요한 권한 부여를 한 번의 중단으로 모아 요청하며, 프로젝트에 콜백 경로·토큰 저장소·갱신 로직·동의 화면을 구현할 필요가 없다.
- Connections는 Managed Deep Agents v0.7.0+ 프리릴리스에서 제공된다. 연결을 읽는 코드를 반영하려면 재배포가 필요하고, 로컬 개발도 지원하며, --authorize로 공유 OAuth 계정을 지정하고 --allowed-scope로 이후 요청 가능한 권한 범위를 제한할 수 있다.
🧩 주요 포인트
- 자격 증명과 배포 코드의 분리 → 비밀값 교체는 저장소에서 처리하고, 연결을 사용하는 코드 변경은 재배포로 반영하는 운영 경계가 생긴다.
- 소유자와 자격 증명 유형의 독립성 → Tavily의 공용 기능, GitHub의 개인별 접근, 공유 OAuth 계정을 같은 연결 모델로 표현할 수 있다.
- OAuth 처리와 MCP 도구 제공의 관리형 전환 → 인증 구현 부담은 줄지만, 호출자 신원과 --scope repo·--allowed-scope 같은 권한 설정은 여전히 동작을 결정한다.
🧠 상세 정리
1. 공유 API 키가 해결하지 못하는 호출자 신원
원문은 에이전트가 웹을 검색하거나 티켓을 등록하고 풀 리퀘스트를 여는 과정에서 누군가를 대신해 행동해야 한다는 문제로 시작한다. 기존 방식에서는 하나의 API 키가 여러 배포에 고정되어 사용되고, 모든 작업이 서비스 계정 명의로 기록되는 경우가 일반적이라고 설명한다. .env에 있는 키는 에이전트가 무엇을 할 수 있는지는 나타내지만, 누가 작업을 요청했는지는 나타내지 못한다. Connections는 LangSmith 워크스페이스에 이름을 가진 자격 증명을 두고, 도구가 실행 시 slug를 통해 한 번의 호출로 읽도록 하는 방식으로 이 문제를 다룬다. 따라서 핵심 변화는 비밀값을 코드와 빌드에서 분리하는 것과 함께, 공유 기능에 필요한 자격 증명과 개인을 대신하는 자격 증명을 구분하는 데 있다.
2. 소유자와 자격 증명 유형이라는 두 축
연결은 소유자와 자격 증명 유형이라는 서로 독립적인 두 축으로 정의된다. 에이전트 소유 자격 증명은 배포에 속해 모든 호출자가 공유하지만, 사용자 소유 자격 증명은 실행 시 요청한 사람에 따라 결정된다. 자격 증명 유형은 정적 비밀값 또는 OAuth 권한 부여이므로, 에이전트가 OAuth 권한을 보유하거나 사용자가 비밀값을 보유하는 조합도 가능하다. 소유권은 mda connections create로 연결을 생성할 때 고정되며, connections.get()은 이미 존재하는 자격 증명 중에서 선택하는 역할만 한다. 이 구분은 OAuth를 반드시 개인 계정과 연결하거나 비밀값을 반드시 공용 계정과 연결해서 이해하면 안 된다는 의미이며, 뒤의 사례들은 이 모델에서 서로 다른 조합을 보여 준다.
3. Tavily로 구현하는 에이전트 소유 비밀값
에이전트 소유 비밀값은 웹 검색, 지오코더, 가격 정보처럼 사람마다 달라질 필요가 없는 기능에 적합하다고 원문은 설명한다. Tavily 예시에서는 TAVILY_API_KEY 환경 변수의 값을 읽어 tavily-agent라는 slug의 연결을 만들고, 그 값을 LangSmith 워크스페이스에 저장한다. slug는 개발자가 정하는 이름으로 공급자 목록과 대조되지 않으며, 저장된 값은 빌드에 포함되거나 mda deploy가 .env를 배포 비밀값으로 가져오는 방식으로 수집되지 않는다. 일반 LangChain 도구는 connections.get()에 tavily-agent와 에이전트 유형을 전달해 키를 읽고, Tavily 검색 API 요청에 사용한다. 이후 같은 연결에 저장된 비밀값을 교체하면 향후 에이전트 요청이 새 키를 자동으로 사용하므로, 키 교체를 위해 코드를 수정하거나 재배포할 필요가 없다.
4. 자체 GitHub 앱으로 구성하는 사용자별 OAuth
GitHub는 다른 22개 서비스와 함께 연결 카탈로그에 포함되어 있어, 자체 OAuth 앱의 클라이언트 ID와 비밀값을 제공하면 인증 URL이나 토큰 URL 등을 별도로 조사하지 않아도 된다. 예시의 github-issues는 코드가 참조할 slug이고, github는 채워 넣을 엔드포인트를 결정하는 카탈로그 서비스 이름이다. --scope repo는 기본 권한에 추가되는 설정이 아니라 전체 권한 목록을 대체하며, GitHub의 기본값인 read:user만으로는 이슈를 열 수 없다. 도구의 공통 헬퍼는 connections.get()에 사용자 유형을 지정하여 호출자별 토큰을 얻고 GitHub API를 호출한다. 생성 단계에는 개인 토큰이 아니라 앱 등록 정보만 저장되며, 처음 사용하는 호출자이거나 토큰이 만료된 경우에는 실행을 중단하고 권한 부여를 요청한다고 설명한다. 같은 헬퍼를 사용하는 검색 도구는 개인의 비공개 저장소 접근 권한에 따라 결과가 달라지고, 이슈 생성 도구는 요청자의 GitHub 계정 명의로 이슈를 등록한다.
5. 앱 등록 없이 연결하는 Linear MCP
일부 MCP 서버는 OAuth 클라이언트 등록을 자체적으로 지원하므로, 연결 설정에 서버 URL만 있으면 된다. 원문은 https://mcp.linear.app/mcp를 사용해 linear-mcp 연결을 만들고, define_mcp의 서버 설정에서 사용자 소유 연결을 참조하는 예시를 제시한다. 이 경우 클라이언트 ID와 비밀값, 별도의 앱 등록이 필요하지 않으며, 서버가 공개하는 OAuth 메타데이터에 따라 클라이언트 등록이 처리된다. 예시에서는 권한 범위도 직접 지정하지 않았고, 서버의 메타데이터를 통해 read와 write가 협의되어 연결에 포함되었다. 자체 앱을 등록하는 GitHub와 준비 과정은 다르지만 자격 증명을 읽는 방식은 동일하며, MCP에서는 개별 API 도구를 직접 작성하는 대신 서버에서 도구를 제공받는다는 차이가 있다.
6. 누락된 권한을 모아 요청하고 실행 재개
두 서비스를 함께 사용하는 작업을 에이전트에 요청하면, 원문에 따르면 첫 모델 턴 전에 실행이 중단되고 호출자가 아직 부여하지 않은 모든 연결의 권한이 하나의 인터럽트에 표시된다. 호출자가 필요한 권한을 승인하면 실행은 멈췄던 지점에서 이어진다. 이 인증 흐름을 위해 프로젝트에 콜백 경로, 토큰 저장소, 토큰 갱신 로직, 동의 화면을 구현할 필요가 없으며 호출자가 LangSmith를 열 필요도 없다. 다른 호출자가 같은 작업을 수행하면 동일한 에이전트, slug, 워크스페이스 항목을 사용하면서도 다른 작성자 명의의 이슈가 생성된다. 이는 모든 사람이 동일한 키를 쓰도록 설계한 Tavily 연결과 구별되며, 워크스페이스에 개발자들이 추가한 연결은 mda connections list로 확인할 수 있다.
7. 버전 조건과 생성·배포·로컬 개발 절차
Connections는 Managed Deep Agents v0.7.0+에서 사용할 수 있으며, 원문은 해당 기능이 프리릴리스에 포함되어 있다고 명시한다. OAuth 카탈로그는 바이너리 안에 포함되므로 설치된 버전이 --oauth에서 허용하는 서비스 목록을 결정하고, mda connections catalog로 이를 확인할 수 있다. 에이전트 소유 자격 증명은 배포에 속하기 때문에 처음 생성하기 전에 에이전트의 기본 구조를 만들고 한 차례 배포해야 한다. 이후에는 연결을 생성하고 connections.get()으로 읽는 코드를 작성한 뒤, 그 코드를 반영하도록 재배포하는 세 단계를 따른다. 로컬에서는 에이전트 소유 연결을 .env의 MDA_DEV_<SLUG>에서 읽되 slug를 대문자로 바꾸고 하이픈을 밑줄로 치환하며, 사용자 소유 연결은 mda dev에 로그인한 개발자의 실제 신원을 사용하므로 로컬 인증 중단으로 저장되는 권한 부여도 실제 권한 부여다.
8. 공유 OAuth와 권한 제한으로 확장되는 모델
원문은 앞선 세 흐름 외에도 --authorize를 사용하면 하나의 OAuth 권한 부여를 배포에 저장할 수 있다고 설명한다. 이 경우 모든 호출자는 동일한 공유 계정으로 행동하므로, 개인별 신원 대신 전용 팀 계정을 사용하려는 상황에 적합하다. 이는 소유자와 자격 증명 유형을 조합한 모델에서 에이전트 소유 OAuth에 해당하며, OAuth 사용 여부만으로 개인별 신원이 보장되는 것은 아니라는 점을 보여 준다. --allowed-scope는 이후의 권한 부여가 요청할 수 있는 범위에 상한을 두고, 카탈로그에 없는 공급자는 --authorize-url과 --token-url을 직접 지정해 연결할 수 있다. 따라서 Connections는 카탈로그와 자동 등록을 활용하는 간단한 구성부터 공유 계정이나 별도 OAuth 공급자를 쓰는 구성까지 지원하며, 원문은 추가 설명과 예제를 Connections 문서로 안내한다.
🧾 핵심 주장 / 시사점
- 호출자별 신원은 작업 작성자 표시뿐 아니라 읽기 결과에도 영향을 준다. GitHub 비공개 저장소 권한 차이 때문에 같은 배포와 같은 검색어에서도 결과가 달라질 수 있다.
- 자격 증명을 분리하면 비밀값 교체와 코드 배포의 주기가 분리된다. 저장된 키의 변경은 향후 요청에 적용되지만, 연결을 읽는 코드의 추가는 재배포가 필요하다.
- 인증 흐름을 관리형으로 처리해도 소유권과 권한 범위의 선택은 남는다. 개인 계정과 공유 계정 중 무엇을 사용할지에 따라 같은 OAuth 방식의 실제 동작이 달라진다.
✅ 액션 아이템
- Tavily의 공용 기능과 GitHub의 개인별 접근을 기준으로 연결의 소유자 및 자격 증명 유형을 구분.
- GitHub의 --scope repo가 전체 범위를 대체한다는 점을 반영하고, --allowed-scope로 이후 요청 가능한 권한 범위를 검토.
- Managed Deep Agents v0.7.0+ 사용 여부를 확인하고, 비밀값 교체와 연결을 읽는 코드 변경의 재배포 필요 여부를 구분.
❓ 열린 질문
- GitHub 작업은 호출자별 신원으로 수행해야 하는가, 아니면 --authorize를 통한 공유 OAuth 계정이 적합한가?
- GitHub의 --scope repo와 --allowed-scope는 필요한 작업 및 이후 요청 가능한 권한 범위에 맞게 설정되어 있는가?
- 현재 변경은 LangSmith 워크스페이스의 비밀값 교체인가, 아니면 재배포가 필요한 연결 사용 코드의 변경인가?