내 에이전트가 인스타그램 비밀번호를 요구했을 때, 설정이 잘못되었음을 깨달았다
요약
에이전트에게 직접적인 로그인 정보를 제공하는 대신 API와 커넥터 계층을 구축해야 함을 강조합니다. 브라우저 자동화 방식은 보안과 안정성 측면에서 취약하며, OAuth와 같은 공식적인 API 흐름을 사용하는 것이 프로덕션 환경에 적합합니다.
핵심 포인트
- 에이전트에게 인간의 계정 정보를 직접 주는 것은 보안상 위험함
- 브라우저 클릭 방식은 MFA, 캡차, 세션 만료 등에 취약함
- Make.com, n8n, MCP 등을 활용한 커넥터 계층 구축 권장
- Instagram 사례처럼 공식 API와 OAuth를 통한 권한 관리가 필수적임
만약 당신의 에이전트(Agent)가 Instagram, Linktree, Carrd 또는 내부 관리 도구(internal admin tool)를 다뤄야 한다면, 비밀번호를 주지 마세요.
커넥터(Connectors)를 제공하세요.
말로 하면 당연하게 들릴 것입니다. 하지만 많은 에이전트 설정들이 여전히 브라우저 로그인, 저장된 세션, 그리고 "그냥 모델이 클릭하게 두자"식의 자동화에 조용히 의존하고 있습니다.
이 방식은 문제가 발생하는 바로 그 순간 전까지는 잘 작동합니다.
저는 r/openclaw에서 누군가가 매우 정상적인 질문을 던진 스레드를 읽고 있었습니다: "내가 모든 것을 수동으로 하는 대신, 에이전트가 일종의 브릿지(bridge)를 통해 앱에 접속할 수 있을까요?"
한 답변은 직설적이고 정확했습니다:
저는 Make.com을 사용합니다. 간단한 작업에만 필요해서 무료 티어를 사용 중입니다.
또 다른 답변은 한 발 더 나아갔습니다:
n8n을 셀프 호스팅(self-host)하고 MCP, 스킬(skill), API 액세스를 추가하면 마법 같은 일이 일어납니다.
이것이 성숙한 답변입니다.
잠이 부족한 인턴처럼 에이전트에게 웹사이트에 로그인하는 법을 가르치는 것이 아닙니다.
커넥터 계층(connector layer)을 구축하세요.
냄새 테스트(The smell test): 인간의 로그인이 필요하다면, 설계가 잘못되었을 가능성이 높다
팀들이 왜 이렇게 하는지 이해합니다.
당신은 Claude, GPT-5, OpenClaw 또는 커스텀 에이전트 루프(agent loop)를 가지고 있습니다. 당신은 이것이 다음을 수행하기를 원합니다:
- Instagram 게시물 발행
- Linktree 페이지 업데이트
- Carrd 사이트 수정
- 내부 관리 패널(internal admin panel) 클릭
가장 빨라 보이는 경로는 다음과 같습니다:
- 브라우저 열기
- 사용자 이름/비밀번호 저장
- 에이전트가 버튼을 클릭하게 두기
데모용으로는 마법처럼 보일 수 있습니다.
하지만 프로덕션(production) 환경에서는 중요한 모든 지루한 방식으로 취약합니다:
- MFA(다요소 인증) 프롬프트
- Captcha(캡차)
- 만료된 세션
- DOM 변경
- 안티 봇(anti-bot) 체크
- 보이지 않는 속도 제한(rate limits)
- 이상한 부분적 실패
그리고 보안 모델이 좋지 않습니다.
당신은 에이전트에게 범위가 지정된 권한(scoped permission)을 주는 것이 아닙니다.
당신은 에이전트에게 인간의 정체성(human identity)을 주고 있는 것입니다.
이것은 엄청난 차이입니다.
Instagram은 이 문제를 명확하게 보여준다
Instagram은 사람들이 단순하다고 가정하기 때문에 좋은 예시입니다.
"그냥 에이전트가 캡션과 함께 이미지를 게시하게 하고 싶어"라는 말은 쉬워 보입니다.
하지만 Meta의 공식적인 경로는 "로그인해서 게시 버튼을 클릭하는 것"이 아닙니다. 안정적인 무언가를 원한다면, 실제 API 흐름(API flow)이 필요합니다.
그것은 다음을 의미합니다:
- Instagram 프로페셔널 계정 (Instagram professional account)
- OAuth
- 적절한 권한 범위 (the right scopes)
- 2단계 게시 흐름 (a two-step publish flow)
최신 Instagram 로그인 권한 범위 (Login scopes)에는 다음이 포함됩니다:
instagram_business_basicinstagram_business_content_publishinstagram_business_manage_messagesinstagram_business_manage_comments
그리고 Meta는 2025년 1월 27일에 이전 권한 범위 (scope) 값들을 지원 중단 (deprecated)했습니다.
이 사실 하나만으로도, 이것이 프롬프트 (prompt) 안에 묻어두고 운 좋게 잘 되길 바랄 만한 일이 아니라는 점을 알 수 있습니다.
대부분의 브라우저 봇이 무시하는 할당량 (quota)
Instagram에는 실제 게시 할당량 (publishing quota)이 존재합니다:
- 계정당
24시간동안50개의 게시된 IG 컨테이너 (IG containers)
Meta는 이를 직접 노출합니다:
GET https://graph.facebook.com/<API_VERSION>/<IG_USER_ID>/content_publishing_limit?fields=quota_usage&access_token=<ACCESS_TOKEN>
적절한 커넥터 (connector)는 게시하기 전에 할당량 (quota)을 확인할 수 있습니다.
브라우저 봇은 보통 일이 벌어진 후에야 이를 알게 되며, 당신에게 스크린샷을 읽게 만들 뿐입니다.
대신 커넥터가 해야 할 일
당신의 에이전트 (agent)는 다음과 같은 것을 호출해야 합니다:
await tools.publish_instagram_post({
imageUrl: "https://cdn.example.com/launch.png",
caption: "Shipping today."
...
그러면 커넥터 계층 (connector layer)이 지저분하지만 필수적인 작업을 수행해야 합니다:
- 미디어 URL (media URL) 검증
- 할당량 사용량 (quota usage) 확인
- 미디어 컨테이너 (media container) 생성
- 컨테이너 게시
- 구조화된 성공 또는 실패 결과 반환
에이전트는 도구 (tool)를 얻습니다.
커넥터는 그 혼란을 책임집니다.
모든 앱이 동일한 통합 전략을 가질 필요는 없다
이 지점에서 팀들이 문제에 봉착합니다.
앱마다 노출하는 인터페이스 (interface)의 종류가 다르기 때문입니다.
Linktree는 Instagram이 아니다
Linktree의 공개 개발자 접점 (developer surface)은 LinkApps를 중심으로 구성되어 있습니다.
다음과 같이 하나를 구축 (scaffold)할 수 있습니다:
npx @linktr.ee/create-linkapp my-app
cd my-app
npm run dev
유용하냐고요? 네.
임의의 프로필 편집을 위한 광범위한 공개 API (public API)와 동등하냐고요? 아니요.
Carrd는 훨씬 더 빈약하다
Carrd는 공개 도움말과 제품 문서가 있지만, 에이전트가 의존할 만한 명확한 범용 공개 사이트 편집 API (public site editing API)는 존재하지 않습니다.
그러한 비대칭성은 중요합니다.
어떤 앱들은 실제 API를 가지고 있습니다.
어떤 것들은 워크플로 래퍼 (workflow wrappers)가 필요합니다.
어떤 것들은 커스텀 내부 엔드포인트 (custom internal endpoints)가 필요합니다.
일부 엣지 케이스 (edge cases)는 여전히 브라우저 자동화 (browser automation)가 필요합니다.
하지만 브라우저 자동화는 커넥터 경계 (connector boundary) 뒤로 격리되어야 하며, 에이전트의 기본 동작 모드가 되어서는 안 됩니다.
내가 실제로 배포할 커넥터 계층 (connector layer)
이것이 실질적인 아키텍처입니다.
| 접근 방식 | 실제 의미 |
|---|---|
| 브라우저 로그인 자동화 | 사용자의 자격 증명(credentials) 또는 세션 쿠키를 사용함; MFA, 캡차(captchas), UI 변경 및 정책 검사 시 취약함 |
| ... |
시스템이 실제 사용 환경에서 견뎌내기를 기대한다면, 나는 거의 매번 중간이나 하단 행을 선택합니다.
진지한 에이전트 스택에 n8n이 계속 등장하는 이유
n8n은 혼합된 환경을 잘 다루기 때문에 이 패턴에 잘 부합합니다.
실제 자동화 스택은 결코 깔끔하지 않습니다. 보통 다음과 같은 모습입니다:
- 하나의 공식 API
- 하나의 내부 REST 엔드포인트 (REST endpoint)
- 하나의 웹훅 (webhook)
- 아무도 건드리고 싶어 하지 않는 하나의 레거시 시스템 (legacy system)
- 하나의 저주받은 브라우저 폴백 (browser fallback)
n8n은 대부분의 도구보다 이러한 짜깁기된 환경을 더 잘 처리합니다.
HTTP Request 노드는 주요 탈출구 (escape hatch)입니다. 이를 에이전트 워크플로에 연결하여 거의 모든 REST API를 호출할 수 있습니다.
확장성을 위해, n8n은 Redis 기반 워커 (workers)를 사용하는 큐 모드 (queue mode)에 대해서도 문서화하고 있습니다:
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=<redis-host>
QUEUE_BULL_REDIS_PORT=6379
그리고 운영상의 제약 사항이 명시되어 있는데, 이는 매우 긍정적입니다. 제한 사항이야말로 아키텍처가 실질적으로 작동하는 지점이기 때문입니다:
- Postgres 13 이상
- 워커 간 공유 암호화 키
- 분산 실행을 위한 큐 모드
- 프로덕션 환경에 투입하기 전 반드시 알아야 할 페이로드 (payload) 및 타임아웃 (timeout) 제한
예시:
N8N_PAYLOAD_SIZE_MAX=16
N8N_FORMDATA_FILE_SIZE_MAX=200
EXECUTIONS_TIMEOUT_MAX=3600
...
이런 것들은 화려하지 않습니다.
하지만 바로 이런 것들이 화요일 밤에 당신의 에이전트가 쓰러지는 것을 막아줍니다.
MCP는 유용하지만, 사람들은 계속해서 잘못된 역할을 부여하고 있다
MCP는 인터페이스 표준 (interface standard)입니다.
이것은 AI 클라이언트가 도구 (tools)와 통신하는 방식입니다.
그것은 도구 구현 (tool implementation) 자체가 아닙니다.
그 차이는 매우 중요합니다.
좋은 패턴 (Good pattern)
에이전트 (Agent) -> MCP 서버 (MCP server) -> n8n 워크플로 (n8n workflow) 또는 내부 백엔드 (internal backend) -> 범위가 제한된 API/OAuth/서비스 계정 (scoped API/OAuth/service account)
나쁜 패턴 (Bad pattern)
에이전트 (Agent) -> 브라우저 (browser) -> 사용자 로그인 (human login) -> 캡차 (captcha) -> 사고 (incident)
만약 당신의 에이전트가 publish_instagram_post를 호출한다면, MCP는 해당 메서드 (method)를 노출할 수 있습니다.
하지만 다른 무언가가 여전히 이를 안전하게 구현해야 합니다.
그 구현체가 바로 당신의 커넥터 계층 (connector layer)입니다.
내부 도구는 가장 쉬운 선택입니다: 서비스 계정을 사용하세요
내부 시스템의 경우, 이것은 논쟁의 여지가 없다고 생각합니다.
직원의 자격 증명 (credentials)이 아닌 서비스 ID (service identities)를 사용하세요.
당신의 에이전트는 운영팀(Ops)의 Sarah가 사용하는 비밀번호를 알아서는 안 됩니다.
에이전트는 다음과 같이 범위가 좁은 동작을 호출하는 방법만 알아야 합니다:
{
"tool": "create_customer_credit",
"input": {
...
그러면 당신의 백엔드 (backend)에서 다음 사항들을 강제할 수 있습니다:
- 권한 부여 (authorization)
- 유효성 검사 (validation)
- 감사 로그 (audit logging)
- 속도 제한 (rate limiting)
- 필요 시 승인 (approvals)
이것이 바로 프로덕션 환경에서 안전한 에이전트 툴링 (agent tooling)의 모습입니다.
브라우저 자동화가 불가피하다면, 격리하세요
때로는 정말로 API가 없는 경우가 있습니다.
괜찮습니다.
어쩔 수 없다면 Playwright나 Puppeteer를 사용하세요. 하지만 격리해야 합니다.
다음 요소들 뒤에 배치하세요:
- 워커 (worker)
- 웹훅 (webhook)
- MCP로 노출된 커넥터 (MCP-exposed connector)
- n8n 또는 Make의 워크플로 경계 (workflow boundary)
이를 범위가 좁고, 모니터링되며, 언제든 교체 가능한 컴포넌트 (component)로 취급하세요.
"직원 자격 증명으로 무작위 웹사이트를 브라우징하기"를 에이전트 설계의 일급 기본 요소 (first-class primitive)로 만들지 마세요.
그것은 아키텍처 (architecture)가 아닙니다.
그것은 사고가 발생하기 직전의 행동입니다.
이번 주에 바로 구현할 수 있는 구체적인 패턴
만약 제가 OpenClaw, Claude, GPT-5 또는 커스텀 에이전트 프레임워크 (custom agent framework)를 사용하는 팀을 위해 이것을 구축한다면, 다음과 같이 구조를 잡을 것입니다:
- 에이전트가 필요한 동작을 결정합니다.
- MCP가 깔끔한 도구 이름 (tool name)을 노출합니다.
- n8n 또는 Make가 워크플로 (workflow)를 실행합니다.
- API 자격 증명 (API credentials), OAuth 또는 서비스 계정 (service accounts)이 실제 동작을 수행합니다.
- 브라우저 자동화는 오직 폴백 (fallback) 용도로만 존재합니다.
예시: 인스타그램 게시 (Instagram publishing)
// agent-side tool call
await tools.publish_instagram_post({
imageUrl: "https://cdn.example.com/post.png",
...
// connector-side pseudo implementation
async function publishInstagramPost(input) {
await assertPublicMediaUrl(input.imageUrl)
...
예시: 내부 관리자 작업 (internal admin action)
await tools.create_status_update({
incidentId: "inc_456",
message: "Mitigation deployed, monitoring recovery"
...
// backend uses service account credentials, not a human login
async function createStatusUpdate(input) {
await requirePolicyCheck(input)
...
에이전트는 동사(verbs)를 봅니다.
비밀번호는 보지 않습니다.
이것이 비용에도 중요한 이유, 단순히 신뢰성 문제만이 아닙니다
이것은 사람들이 에이전트를 지속적으로 실행하기 시작할 때 놓치는 부분입니다.
나쁜 커넥터 설계는 단지 사고를 일으키는 것 이상을 합니다. 낭비도 만듭니다.
불안정한 브라우저 단계 하나하나가 다음으로 바뀝니다:
- 재시도(retries)
- 더 긴 실행 시간
- 반복적인 계획 루프
- 추가 모델 호출
- 더 많은 모니터링 오버헤드
토큰당 비용을 지불하고 에이전트 스택이 동일한 실패한 상호작용을 끊임없이 재고할 때, 이것은 빠르게 비싸집니다.
이것이 자동화 중심 팀에게 예측 가능한 컴퓨팅(predictable compute)이 중요한 이유 중 하나입니다.
만약 n8n, Make, OpenClaw 또는 사용자 지정 워크플로우에서 하루 종일 에이전트를 실행하고 있다면, 평생 비용제 API 액세스가 워크플로우가 루프를 돌 때마다 모든 토큰에 집착하는 것보다 훨씬 적합합니다.
Standard Compute는 여기서 흥미롭습니다. 왜냐하면 GPT-5.4, Claude Opus 4.6, Grok 4.20과 같은 모델을 백그라운드에서 라우팅하면서 무제한 사용량을 월별 고정 가격으로 제공하는 OpenAI 호환 API를 제공하기 때문입니다.
이것이 나쁜 아키텍처를 고치는 것은 아닙니다.
하지만 일단 아키텍처가 비밀번호 중심(password-first)이 아니라 커넥터 우선(connector-first)이 되면, 예측 가능한 가격 책정은 장기 실행 자동화를 운영하는 것을 훨씬 쉽게 만듭니다.
특히 대안이 버튼 레이블 때문에 브라우저 봇이 혼란을 겪어 토큰 지출이 급증하는 것을 지켜보는 것이 아닐 때 더욱 그렇습니다.
저의 의견 (My opinionated takeaway)
만약 당신의 에이전트가 Instagram, Linktree, Carrd 또는 내부 도구 (internal tools)를 다뤄야 한다면, 다음과 같은 질문은 멈추십시오:
"로그인할 수 있나요?"
대신 이렇게 물으십시오:
"이 동작을 소유한 커넥터 (connector)는 무엇인가요?"
저의 기본 설정 (defaults)은 다음과 같습니다:
- Instagram: 공식 API (official API)
- 내부 도구 (internal tools): 서비스 계정 (service accounts) 및 제한된 API (narrow APIs)
- 오케스트레이션 (orchestration): n8n 또는 Make
- 에이전트/도구 인터페이스 (agent/tool interface): MCP
- API가 없는 예외 사례 (no-API edge cases): 격리된 브라우저 자동화 (isolated browser automation)만 사용
이러한 설정은 에이전트에게 브라우저와 비밀번호를 주는 것보다 덜 화려해 보일 수 있습니다.
하지만 이것이 현실과 맞닥뜨렸을 때 살아남는 설정입니다.
그리고 일단 당신의 에이전트가 웹사이트를 돌아다니며 클릭하는 인간인 척하는 것을 멈추면, 에이전트는 보통 능력이 떨어지는 것이 아니라 오히려 더 유능해집니다.
왜냐하면 이제 에이전트는 봇을 차단하기 위해 설계된 시스템과 싸우는 대신, 자동화를 위해 설계된 시스템을 통해 작동할 수 있기 때문입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기