OpenCode 키 유출: Synthorai Trusted IPs로 악용 차단하기
목차
2026년 10월 17일, OpenCode는 호스팅 서비스인 OpenCode Console의 레거시 시스템에 침입자가 접근했으며, 여기에 저장된 외부 공급자 키가 “노출됐을 수 있다”고 사용자에게 알렸다. 이후 사용자들은 OpenAI, Anthropic, Google 계정에 수백 달러에서 최대 $1,700의 요금이 청구됐다고 보고했다. 공급자 키는 OpenAI나 Anthropic에서 발급받는 API 키다. 호스팅 도구가 사용자를 대신해 공급자 API를 호출하도록 이 키를 맡기는 방식을 BYOK(bring your own key)라고 한다. 키 유출로 발생하는 비용은 두 가지에 달려 있다. 어디에서 키를 사용할 수 있는지, 그리고 사용이 차단되기 전까지 얼마를 쓸 수 있는지다.
TL;DR
- OpenCode에 따르면 Console 침해 사고는 Console 사용자 1.4%에 영향을 줬다. 로컬 OpenCode CLI에 저장된 키는 영향을 받지 않았다.
- 게이트웨이의 IP 규칙과 지출 한도는 게이트웨이를 거치는 트래픽에만 적용된다. 공급자 키 유출에 대비하려면 공급자 측에 강제 한도를 설정해야 한다.
- Synthorai에서 ‘새 IP 승인 필요’를 켜면 해당 키에 승인되지 않은 주소의 API 호출을 HTTP 403과
ip_not_trusted로 거부한다. - Synthorai 키마다 지출 한도, 분당 요청 및 token 한도, 만료일을 설정할 수 있다.
OpenCode Console에서는 무슨 일이 있었나?
OpenCode가 피해 사용자에게 보낸 이메일에 따르면, 외부인이 “폐기 절차를 진행 중이던 레거시 시스템”에 무단 접근했다. 이 과정에서 해당 사용자의 Console 워크스페이스에 저장된 공급자 키를 읽었을 가능성이 있다. OpenCode는 노출이 시작됐을 수 있는 가장 이른 시점을 10월 17일 00:30 UTC로 밝혔다. OpenCode 게시물, 공급자 직원 게시물, 언론 보도를 바탕으로 정리한 경과는 다음과 같다.
| 시각(UTC) | 내용 |
|---|---|
| 10월 17일 약 06:00 | 한 사용자의 설명에 따르면 이때부터 해당 사용자의 키에 요금 발생: OpenAI $281, Anthropic $168 |
| 10월 17일 오전 | OpenCode가 피해 사용자에게 이메일 발송: 각 공급자에서 키를 폐기하고 최근 사용 내역을 확인하라고 안내 |
| 10월 17일 18:08 | OpenCode의 X 게시물: Console 사용자 1.4%에 영향을 준 “대규모 증류 공격과 관련된” 침해 사고라고 발표 |
| 10월 17일 저녁 | Anthropic이 피해를 본 것으로 판단한 Claude API 키를 폐기하고, Google이 노출된 키를 차단 |
| 10월 19일 | OpenAI 발표: OpenCode와 협력해 피해 고객의 이용을 복구하고 공격으로 소모된 크레딧을 환급 |
증류 공격은 한 모델의 응답을 대량으로 수집해 다른 모델을 학습시키는 행위다. 탈취한 키는 이런 공격의 호출 비용을 충당하는 수단 중 하나다. OpenCode는 이번 침해와 증류 공격이 어떻게 연결되는지 설명하지 않았다. 공동 창업자 Dax Raad는 이번 사고가 “OpenCode 자체가 아니라 OpenCode Console”에서 발생했으며, 로컬 CLI에 추가한 키는 회사로 전송되지 않는다고 밝혔다. 10월 21일 기준으로 OpenCode는 근본 원인, 저장된 키의 암호화 여부, 1.4%에 해당하는 실제 피해 계정 수, 보상 정책, 사후 분석 보고서를 공개하지 않았다(The Hacker News, BleepingComputer).
어떤 키가 노출됐고, 어떤 통제가 효과가 있나?
노출된 것은 공급자 키다. 탈취한 공급자 키는 그 키를 보관하던 도구를 거치지 않고 공급자에 직접 사용할 수 있다. 따라서 LLM 게이트웨이가 대응할 수 있는 범위에는 한계가 있다. 게이트웨이는 애플리케이션 코드와 모델 공급자 사이에서 요청을 전달하는 서비스다. 자신을 거치는 트래픽만 확인하고 제한할 수 있다. 두 종류의 키를 구분하면 이해하기 쉽다.
| 키 | 유출될 수 있는 곳 | 악용을 차단하거나 제한하는 수단 |
|---|---|---|
사용자가 보유한 게이트웨이 키(Synthorai는 sk-syn-...) | 코드, CI 로그, 노트북, 설정 파일 | 게이트웨이의 IP 규칙, 지출 한도, 요청 제한, 만료 설정 |
| 호스팅 서비스에 저장한 공급자 키(BYOK) | OpenCode 사례처럼 서비스 자체 시스템 | 공급자 측 조치만 가능: 키 폐기와 지출 한도 |
다음 두 절에서 설명하는 Trusted IPs와 지출 한도는 첫 번째 유형을 보호한다. 두 번째 유형의 최종 방어선은 OpenAI, Anthropic, Google에서 설정한 강제 한도다. 해당 설정은 그 뒤의 절에서 정리한다.
Synthorai는 플랫폼 키와 BYOK 키를 어떻게 보호하나?
BYOK Vault에 추가한 공급자 키는 표준 인증 암호화 알고리즘인 AES-256-GCM으로 저장 시 암호화된다. 한 번 저장한 키는 API, MCP 도구, 콘솔 페이지 어디에서도 다시 반환하지 않는다. 콘솔에는 마지막 네 글자만 표시된다. 게이트웨이는 해당 키를 사용하는 요청을 처리할 때만 메모리에서 키를 복호화한다. 키 추가, 교체, 삭제는 워크스페이스 소유자만 할 수 있다. Synthorai가 자체 제공 용량에 사용하는 공급자 키도 같은 방식으로 저장되며, 관리자 콘솔을 포함한 어떤 콘솔 페이지나 API에도 노출되지 않는다. 암호화는 데이터베이스 사본을 보호한다. 실행 중인 서비스가 침해되면 사용 중인 키에 접근할 수 있으므로, BYOK 키의 최종 방어선은 아래에서 설명할 공급자 측 한도다.
Synthorai가 사용자에게 발급하는 API 키는 해시로만 저장한다. 해시는 원래 키를 복원할 수 없는 단방향 지문이다. 전체 키는 생성 시 한 번만 표시된다. 이후 콘솔, 관리 API, MCP 서버에서 조회하면 접두사만 반환한다. 추론 키는 모델 호출만 할 수 있다. 관리 API는 추론 키를 거부하므로, 추론 키를 탈취해도 로그, 사용량, 다른 키를 조회할 수 없다 (API keys, admin keys).
Trusted IPs는 유출된 키를 어떻게 차단하나?
Trusted IPs는 해당 API 키에 승인되지 않은 주소에서 오는 호출을 거부한다. CI 로그나 노트북에서 복사한 키를 다른 곳에서 사용하면 응답 대신 오류가 반환된다. 소유자나 관리자는 Settings › Security에서 ‘새 IP 승인 필요’를 켤 수 있다. 대화 상자에는 지난 7일 동안 각 키를 사용한 주소가 표시되며, 처음에는 모두 승인 대상으로 선택돼 있다. 확인하기 전에 목록을 살펴보고 모르는 주소는 선택을 해제해야 한다. 키가 이미 유출돼 사용됐다면 공격자의 주소도 이 목록에 들어 있다.

이후 새 주소에서 호출하면 HTTP 403이 반환된다. 아래 주소는 문서용 예시다.
{
"error": {
"type": "permission_error",
"code": "ip_not_trusted",
"ip": "203.0.113.9",
"message": "Requests from IP address 203.0.113.9 are held until this address is approved for the key. ...",
"approve_url": "https://synthorai.io/console/settings?tab=security"
}
}
키 생성자에게는 주소, 위치, 클라이언트, 요청한 모델이 담긴 이메일이 전송된다. 승인은 로그인 후 콘솔에서 진행하므로 이메일을 전달하는 것만으로는 아무것도 승인되지 않는다. 주소가 바뀌는 클라이언트라면 단일 주소 또는 해당 주소의 /24 범위(인접한 IPv4 주소 256개)를 승인할 수 있다. 게이트웨이는 자체 프록시에서 확인한 연결 정보를 기준으로 호출자 주소를 읽는다. 따라서 클라이언트가 임의의 X-Forwarded-For 헤더를 보내 다른 주소로 위장할 수 없다. 이 헤더는 프록시가 원래 클라이언트 주소를 전달할 때 사용한다. 위조한 헤더로 직접 확인했으며, 거부 응답에는 여전히 실제 주소가 표시됐다.
# From an address not yet approved for the key, with a forged header:
curl -s https://synthorai.io/v1/models \
-H "Authorization: Bearer $SYNTHORAI_API_KEY" \
-H "X-Forwarded-For: 203.0.113.9"
# The 403's "ip" field is the caller's real address, not 203.0.113.9.
키를 생성할 때 고정된 ip_allowlist를 지정할 수도 있다. 다만 이 목록은 키 설정의 일부이므로 사무실, 서버, VPN 출구가 추가될 때마다 키를 수정해야 한다. 삭제를 잊은 항목은 계속 허용된다. Trusted IPs는 키가 이미 사용되고 있는 주소에서 시작해 새 주소를 신뢰하기 전에 승인을 요청한다. 모든 키의 주소를 한 목록에서 관리하며, 아는 주소는 한 번의 클릭으로 신뢰할 수 있다. 자체 허용 목록이 있는 키는 그 목록만으로 허용 여부를 결정하므로, 키마다 둘 중 하나만 사용해야 한다.
신뢰 여부는 키별로 적용된다. 실행할 때마다 새 주소를 사용하는 서버리스 함수나 CI runner는 매번 승인을 기다리게 된다. 호스팅 CI 공급자가 공개한 주소 범위 전체를 신뢰해서는 안 된다. 이 주소들은 해당 공급자의 모든 고객이 공유하므로, 그곳에서 작업을 실행하는 누구나 통과할 수 있다. 이런 호출은 자체 호스팅 runner나 NAT 게이트웨이처럼 고정된 송신 주소를 거치게 하고 해당 주소를 신뢰하거나, 한도가 낮고 유효 기간이 짧은 키를 발급해야 한다.
지출 한도는 키 탈취 피해를 어떻게 제한하나?
모든 Synthorai API 키에는 개별 지출 한도를 설정할 수 있다. 키가 유출되더라도 미리 정한 금액에 도달하면 사용이 중단된다. 콘솔에서는 키를 생성할 때 한도, 허용 모델, 만료일을 설정한다.

키별 요청 제한과 아래의 다른 설정은 관리 API로 지정한다.
| 설정 | 기능 |
|---|---|
limit_usd 및 limit_reset | 달러 기준 지출 한도. 초기화 없음, 매일, 매주, 매월 중 선택하며, 한도에 도달하면 초기화될 때까지 해당 키의 호출을 거부 |
rate_limit (rpm, tpm) | 해당 키의 분당 요청 수와 token 수 상한 |
allowed_models | 해당 키로 호출할 수 있는 모델 목록 |
ip_allowlist | 주소 범위가 바뀌지 않는 호출자를 위해 키 사용을 허용할 주소 또는 범위(예: 198.51.100.0/24)를 고정 목록으로 지정 |
expires_at | 키 사용이 중단되는 시각 |
include_byok_in_limit | 사용자 소유의 공급자 키로 처리한 요청을 한도에 포함할지 여부 |
아래는 관리자 키로 특정 서비스에 필요한 권한만 갖춘 키를 생성하는 예다. 관리자 키는 키 생성과 한도 설정은 할 수 있지만 모델을 호출할 수는 없는 관리용 키다.
curl https://synthorai.io/api/v1/keys \
-H "Authorization: Bearer sk-syn-admin-..." \
-H "Content-Type: application/json" \
-d '{
"name": "support-bot prod",
"limit_usd": 50,
"limit_reset": "daily",
"rate_limit": {"rpm": 60, "tpm": 200000},
"allowed_models": ["claude-haiku-5-5"],
"expires_at": "2027-01-31T00:00:00Z"
}'
워크스페이스 소유자는 구성원별 일간 및 월간 지출 상한도 설정할 수 있다. 월간 상한에 도달한 구성원에게는 다음 달까지 HTTP 402가 반환된다. 이 한도는 Synthorai를 거치는 트래픽에 적용된다. BYOK를 한도에 포함하면 게이트웨이를 거치는 BYOK 요청도 제한하지만, 유출된 공급자 키를 직접 사용하는 경우에는 적용되지 않는다.
이 통제로 막을 수 없는 것은 무엇인가?
Trusted IPs는 새로운 위치에서의 키 사용을 차단한다. 이미 신뢰하는 장비에서 키를 사용하면 막지 못한다. 흔한 키 탈취 사고는 바로 이런 환경에서 발생한다. 개발자 노트북의 악성코드, 침해된 CI 작업, 공격자의 요청을 대신 보내도록 속은 서버가 그 예다. 이런 경우에는 키의 지출 한도, 허용 모델 목록, 짧은 유효 기간이 피해를 제한한다.
승인은 사람이 결정한다. 공격자는 보류되는 요청을 일부러 발생시킨 뒤 사용자가 습관적으로 승인하기를 기대할 수 있다. 승인 페이지에는 주소, 위치, 클라이언트, 모델이 표시된다. 직접 보낸 호출과 일치할 때만 승인해야 한다.
매일 초기화되는 지출 한도는 누군가 알아차릴 때까지 탈취된 키가 매일 그 한도만큼 비용을 쓰도록 허용한다. 한도와 탐지를 함께 사용해야 한다. 주소가 보류될 때마다 발송되는 이메일, 콘솔의 키별 지출, 키 변경 감사 로그를 확인하자. 키 유출이 의심되면 콘솔에서 삭제하고 새 키를 생성해야 한다. 유출 전에 키를 찾아내려면 코드 호스팅 서비스에 sk-syn- 접두사를 탐지하는 비밀정보 검사 패턴을 추가하자. 예를 들어 GitHub에서는 push protection을 적용한 사용자 지정 패턴을 사용할 수 있다.
BYOK 키는 공급자 측에서 무엇을 설정해야 하나?
도구마다 별도 프로젝트나 워크스페이스에 전용 공급자 키를 발급하고 강제 지출 한도를 설정하자. 그러면 키 하나가 유출돼도 해당 프로젝트의 예산까지만 사용할 수 있다. 유출된 키는 공급자 대시보드에서 폐기해야 한다. 키를 저장한 도구에서 삭제하는 것만으로는 폐기되지 않는다. 세 공급자 모두 개별 키 단위의 한도를 제공하지 않는다. 최소 단위는 프로젝트 또는 워크스페이스다.
| 공급자 | 키를 분리할 수 있는 최소 단위 | 강제 한도 |
|---|---|---|
| OpenAI | 프로젝트 | ”Enforce a hard limit”를 켠 월간 프로젝트 지출 한도. 소폭 초과할 수 있으며, 이후 호출은 429 project_spend_limit_exceeded로 실패 |
| Anthropic | 워크스페이스 | 월간 워크스페이스 지출 한도. 이후 호출은 400 invalid_request_error로 실패. 기본 워크스페이스에는 설정할 수 없으므로 키를 두지 않아야 함 |
| Google (Gemini API) | Cloud 프로젝트 | 결제 계정 등급별 상한에 도달하면 연결된 모든 프로젝트가 다음 달까지 중지됨. 프로젝트 지출 상한은 실험적 기능이며 약 10분 동안 초과 사용이 발생할 수 있음 |
이메일만 보내는 지출 알림과 예산 설정은 진행 중인 공격을 멈추지 못한다. 강제 한도를 설정한 뒤 보조 탐지 수단으로 유지할 가치는 있다. Synthorai 콘솔의 BYOK 페이지에는 키 아래에 각 공급자의 한도 설정 링크가 있다.

OpenCode를 Synthorai와 함께 사용할 수 있나?
가능하다. 로컬 OpenCode CLI에서 사용하는 키는 사용자 장비에 남으며, 이번 침해 사고의 영향을 받지 않은 구성이다. opencode auth login https://synthorai.io를 실행하면 일회용 코드로 브라우저에서 OpenCode 로그인을 진행한다. OpenCode에는 7일, 30일, 90일 중 선택한 기간 후 만료되는 전용 API 키가 발급된다(설정 안내). ‘새 IP 승인 필요’가 켜져 있고 같은 네트워크에서 로그인을 허용하면, 로그인한 주소가 해당 키의 신뢰 주소로 자동 등록된다. 다른 주소에서의 호출은 승인을 기다린다. 로그인 요청이 브라우저와 다른 네트워크에서 오면 확인 페이지에 경고가 표시되며, 첫 호출을 승인하기 전까지 해당 주소는 신뢰되지 않는다. 직접 명령을 실행하지 않았다면 요청을 취소해야 한다.

API 키 페이지에는 이 키가 “OpenCode”로 표시된다. 여기에서 지출 한도를 추가하거나 키를 삭제할 수 있다. 노트북에 보관한 키도 해당 노트북의 악성코드에 탈취될 수 있다. 따라서 유효 기간을 7일 또는 30일로 정하고 ‘새 IP 승인 필요’를 켜 두자. 복사된 키는 다른 주소에서 사용할 수 없고, 오래 지나지 않아 만료된다.
자주 묻는 질문
OpenCode CLI에 저장된 키도 이번 사고로 노출됐나?
아니다. OpenCode는 침해 범위가 OpenCode Console에 한정된다고 밝혔다. 로컬 CLI나 데스크톱 앱에 추가한 키는 사용자 장비에 저장되며 OpenCode로 전송되지 않는다.
호스팅 도구에서 공급자 키를 삭제하면 키가 폐기되나?
아니다. 도구에서 키를 삭제하면 그 도구가 보관하던 사본만 지워진다. 공급자 대시보드에서 키를 폐기하고 새 키를 만들기 전까지 기존 키는 계속 사용할 수 있다.
게이트웨이의 지출 한도로 유출된 공급자 키를 보호할 수 있나?
아니다. 게이트웨이 한도는 게이트웨이를 통과한 요청만 집계한다. 유출된 공급자 키는 공급자에 직접 사용되므로, 이때 적용되는 것은 공급자 자체의 지출 한도다.
관련 문서: Trusted IPs, BYOK Vault, 관리자 키와 키 한도, OpenCode 설정.
2026년 10월 21일 확인한 자료: 언론이 인용한 OpenCode 게시물과 이메일, 공급자 직원 게시물, 위에 링크한 공급자 문서. 위조 헤더 테스트는 2026년 10월 21일 Synthorai 운영 게이트웨이에서 수행했다.