OpenCode Console 보안 사고 공지 후 API 키 교체 순서와 로컬 키 고정
2026년 10월 18일 새벽 2시 56분(KST), OpenCode 공식 X 계정에 OpenCode Console 사용자 1.4%가 영향을 받은 보안 사고 공지가 올라왔습니다. Console에 외부 제공자 키를 연결해 쓰던 분이라면 지금 할 일은 원인을 추측하는 것이 아니라 키를 정리하는 것입니다. 공식 공지는 사고가 진행 중이라 세부 내용을 공유할 수 없다고 밝혔고, 원인으로 짐작할 만한 내용은 대상자가 받은 이메일에 대한 보도에만 나옵니다. 그래서 이 글은 공지 원문과 보도 내용을 구분해 옮긴 다음, 각 제공자 문서가 권하는 키 폐기·교체 절차와 OpenCode CLI를 로컬 키만 쓰도록 묶는 설정을 정리합니다.
설정 부분은 OpenCode CLI 1.19.3을 격리된 HOME에 새로 설치해 실제로 적용하고 확인했습니다. 화면에 나오는 키는 전부 sk-ant-DUMMY처럼 시험용 가짜 값입니다. 그래서 모델 목록은 설정이 어떤 제공자를 불러오는지를 보여 주는 용도로 읽어야 하고, 그 키로 호출이 된다는 뜻은 아닙니다.
공지 원문과 확인한 시각
공지는 처음 올라온 뒤 12분 만에 수정됐습니다. 아래는 현재 보이는 수정본의 전문이고, 링크는 OpenCode 공지 게시물입니다(확인일 2026-10-18, 10:28 KST 조회).
We had a security breach last night related to a large scale distillation attack that impacted 1.4% of OpenCode Console users
We have notified them all this morning via email. If you did not get an email you were not impacted, it was a subset of users who had external providers linked
The incident is ongoing so we cannot share more details at this point but we are working with Anthropic, OpenAI, and Google to remediate
02:56 KST에 올라온 처음 판과 비교하면, 03:08 KST 수정본은 둘째 문단에 “이메일을 받지 못했다면 영향이 없으며, 외부 제공자를 연결해 둔 일부 사용자였다”는 설명을 덧붙였고, 사고가 진행 중이며 Anthropic, OpenAI, Google과 함께 대응하고 있다는 마지막 문단은 그대로 두었습니다. 공지가 밝힌 사실은 영향받은 비율이 Console 사용자의 1.4%라는 것, 대상자에게 이메일로 알렸다는 것, 대상이 외부 제공자를 연결한 사용자 중 일부라는 것, 그리고 사고가 아직 진행 중이라는 것입니다.
대상자가 받은 이메일은 보도로 내용이 알려졌습니다. TechCityAuthority 보도에 따르면 “Action Required: Potential provider key breach”라는 제목의 이 이메일은 회사가 “identified unauthorized access to a legacy system that we were in the process of decommissioning”했고, “third party provider keys (eg OpenAI, Anthropic) saved in your workspace may have been exposed”라고 알리면서 키를 폐기하고 교체하라고 요청했습니다(확인일 2026-10-18). 보도는 OpenCode가 대상자에게 이메일을 보낸 사실을 확인했다고 전하지만, 이메일 원문은 사용자들이 공유한 화면을 근거로 한 것입니다. 결국 노출 가능성이 있는 것은 Console 워크스페이스에 저장해 둔 제공자 키라는 점까지가 지금 알려진 범위이고, 그 이상은 회사의 다음 공지를 기다려야 합니다.
| 항목 | 값 |
|---|---|
| 공지 | @opencode, 2026-10-18 02:56 KST 게시, 03:08 KST 수정(둘째 문단 보완, 진행 중 문단 유지) |
| OS | Debian GNU/Linux 13 (trixie), x86_64 |
| OpenCode CLI | 1.19.3 (공식 설치 스크립트, PATH 수정 없이) |
| 실험 HOME | 새로 만든 빈 HOME, 자격 증명 0개에서 시작 |
| 키 | 전부 시험용 가짜 값 |
| 확인일 | 2026-10-18 KST |
이메일을 받았든 아니든 먼저 정할 교체 순서
키를 바꾸는 순서는 제공자마다 권고가 조금씩 다릅니다. Anthropic 도움말은 키가 노출됐다고 의심되면 Console의 API keys 화면에서 즉시 폐기(Delete API Key)하고 같은 화면에서 새 키를 만들라고 합니다. OpenAI의 키 안전 수칙은 유출이 의심되면 API Keys 페이지에서 곧바로 교체하라고 하고, 평소의 교체 절차로는 대체 키를 먼저 만들어 앱에 반영하고 동작을 확인한 다음 옛 키를 폐기하라고 적었습니다. Google Gemini API 키 문서의 유출 대응 체크리스트는 새 키 생성, 애플리케이션 갱신, 새 키 확인 후 옛 키 비활성화 또는 삭제, 사용량과 결제 기록 점검 순서입니다(세 문서 모두 확인일 2026-10-18).
세 문서를 겹쳐 보면 갈리는 지점은 하나입니다. 서비스 중단을 감수하고 먼저 끊을지, 새 키를 깔아 둔 다음 끊을지입니다. 제 판단은 이렇습니다. OpenCode에서 이메일을 받았다면 해당 키는 노출된 것으로 보고 먼저 폐기합니다. 몇 분 동안 앱이 멈추는 비용보다 남이 그 키로 호출하는 비용이 큽니다. 이메일은 받지 않았지만 Console에 키를 저장해 둔 적이 있다면, 새 키를 만들어 반영한 뒤 옛 키를 끊는 순서로 진행해도 됩니다. 공지대로라면 영향은 없지만, 진행 중인 사고에서 쓰던 키를 계속 쓸 이유도 없기 때문입니다.
한 가지는 분명히 해 두어야 합니다. OpenCode Console이나 CLI에서 키를 지우는 것은 그 도구가 키를 더 이상 쓰지 않게 할 뿐, 이미 밖으로 나간 키를 무효로 만들지 못합니다. 키를 실제로 끊는 곳은 각 제공자의 대시보드(Anthropic Console, OpenAI API Keys 페이지, Google AI Studio나 Cloud console)입니다. 이 단계가 빠지면 나머지 정리는 의미가 없습니다.
어느 쪽이든 마지막 단계는 같습니다. 각 제공자 콘솔에서 공지 시각 앞뒤의 사용량과 결제 내역을 확인합니다. OpenAI 문서는 조직이나 프로젝트에 월 지출 한도를 걸고 강제 차단을 켜 두라고 권하는데, 지출 알림만으로는 트래픽이 멈추지 않는다는 점도 함께 짚고 있습니다. 새 키를 만들 때는 키를 쓰는 곳마다 따로 발급하고, 만료일을 둘 수 있는 제공자라면 만료일을 넣어 둡니다. 키 하나가 여러 곳에 퍼져 있으면 다음 사고 때 무엇을 끊어야 할지 정하는 데만 시간이 걸립니다.
로컬 CLI에 남아 있는 키부터 찾아 정리하기
키를 교체하기 전에 먼저 할 일은 지금 이 기계에서 OpenCode가 어떤 키를 쓰고 있는지 아는 것입니다. 설치 직후 상태부터 확인했습니다. 자격 증명이 0개인데도 모델 목록에는 opencode 제공자 모델이 나왔습니다. 키를 하나도 넣지 않아도 OpenCode 자체 제공자의 모델은 기본으로 목록에 올라온다는 뜻입니다. 개수는 시점마다 달랐습니다. 설치 직후인 09:58에는 12개, 10:04와 10:27에 다시 셌을 때는 10개였고, 아래 캡처를 찍은 10:43에는 다시 12개였습니다. 시점에 따라 10개와 12개 사이에서 달라진 셈입니다.

OpenCode CLI가 키를 읽는 곳은 두 군데입니다. /connect로 입력한 키는 제공자 문서에 적힌 대로 ~/.local/share/opencode/auth.json에 저장되고, ANTHROPIC_API_KEY 같은 환경 변수도 그대로 읽힙니다. 두 경로에 가짜 키를 하나씩 넣고 opencode auth list를 실행하면 두 출처가 따로 표시됩니다.

Credentials 아래가 auth.json에 저장된 키, Environment 아래가 셸 환경 변수에서 읽은 키입니다. 환경 변수 쪽은 값이 아니라 변수 이름만 보여 주므로, 화면을 공유하며 점검해도 키가 드러나지 않습니다. opencode auth logout openai를 실행하자 “Logout successful”이 나왔고, 다시 조회하면 저장된 자격 증명이 0개, 파일 내용은 {}였습니다. 다만 logout은 auth.json만 정리합니다. 환경 변수로 들어온 키는 셸 설정 파일이나 CI 비밀 변수에서 직접 지워야 하고, 그 키도 교체 대상 목록에 넣어야 합니다.
enabled_providers로 로컬 키 제공자만 남기기
키를 새로 받았다면 CLI가 그 키만 쓰도록 범위를 좁혀 두는 것이 좋습니다. OpenCode 설정 문서는 enabled_providers로 쓸 제공자를 지정하고 disabled_providers로 특정 제공자를 막을 수 있다고 설명합니다. 둘이 겹치면 disabled_providers가 우선하고, 막힌 제공자는 환경 변수나 /connect로 키가 들어와 있어도 불러오지 않는다고 적혀 있습니다. 키 값은 설정 파일에 직접 쓰지 않고 {file:경로} 치환으로 권한 600짜리 파일에서 읽게 했습니다. 이렇게 하면 프로젝트의 opencode.json을 저장소에 커밋해도 키가 따라 들어가지 않습니다.
{
"$schema": "https://opencode.ai/config.json",
"enabled_providers": ["anthropic"],
"disabled_providers": ["opencode"],
"provider": {
"anthropic": {
"options": { "apiKey": "{file:~/.secrets/anthropic-key}" }
}
},
"autoupdate": false
}
autoupdate를 끈 이유는 사고가 진행 중인 동안 CLI가 스스로 버전을 바꾸지 않게 하려는 것입니다. 갱신은 릴리스 노트를 읽고 직접 올리는 쪽이 지금은 낫다고 봅니다. 이 설정을 둔 디렉터리에서 모델 목록과 실행을 다시 확인했습니다.

모델 목록에서 opencode 모델이 모두 사라지고 anthropic 20개만 남았습니다. opencode debug config로 최종 병합된 설정을 보면 두 목록이 의도대로 들어가 있고, apiKey 자리는 ***로 가려져 나옵니다. 덕분에 장애 대응 채널에 이 출력을 그대로 붙여 넣어도 키 값은 따라가지 않습니다.
막은 제공자의 모델을 일부러 지정해 실행하면 CLI는 아래처럼 모호한 오류만 냅니다.
$ opencode run -m opencode/big-pickle "hello"; echo "exit=$?"
Error: {
"name": "UnknownError",
"data": {
"message": "Unexpected server error. Check server logs for details.",
"ref": "err_c20cb1d9"
}
}
exit=1
“Unexpected server error”만 보면 OpenCode 서버 쪽 장애로 오해하기 쉽습니다. --print-logs를 붙여 같은 명령을 다시 실행하면 진짜 원인이 나옵니다. ProviderModelNotFoundError: Model not found: opencode/big-pickle입니다. 제공자를 막았기 때문에 모델을 찾는 단계에서 실행이 끝난 것입니다. 팀원이 이 설정을 받은 뒤 예전 모델 이름으로 실행했다가 이 오류를 만나면, 서버 장애가 아니라 설정이 의도대로 동작한 결과라고 알려 주면 됩니다.
교체한 뒤 남은 흔적과 권한 점검
새 키를 넣고 나면 옛 키나 새 키가 엉뚱한 곳에 남지 않았는지 훑어봅니다. 제공자 키 접두어로 OpenCode 데이터 디렉터리, 설정 디렉터리, 키 파일 디렉터리를 검색하고, 권한을 확인하고, 로그에 키 문자열이 찍혔는지 셉니다.

키 문자열이 나온 곳은 의도한 키 파일 하나뿐이었습니다. 키 디렉터리는 700, 키 파일과 auth.json은 600이었고, 지금까지의 실행으로 쌓인 OpenCode 로그에서 가짜 키 문자열이 들어간 파일은 0개였습니다. 실제 서버에서 같은 점검을 할 때는 검색 대상에 셸 설정 파일과 CI 설정 디렉터리도 넣어야 합니다. 환경 변수로 넣던 키는 OpenCode 디렉터리 밖에 있기 때문입니다.
상황별로 정리한 제 대응
| 상황 | 키 처리 순서 | CLI 설정 |
|---|---|---|
| OpenCode 이메일을 받음 | 제공자 대시보드에서 즉시 폐기 → 새 키 발급 → 앱 갱신 → 사용량·결제 확인 | auth logout, 환경 변수 제거 후 {file:}로 새 키 |
| 이메일은 없지만 Console에 키를 저장했음 | 새 키 발급 → 앱 갱신 → 옛 키 폐기 → 사용량 확인 | 같음 |
| Console을 쓰지 않고 CLI에 로컬 키만 씀 | 공지 대상 밖, 정기 교체 일정대로 | enabled_providers로 범위 고정, autoupdate 끔 |
| 막은 제공자 모델로 실행 | 해당 없음 | UnknownError가 나오면 --print-logs로 ProviderModelNotFoundError 확인 |
이번 공지에서 가장 먼저 해야 할 판단은 내가 Console에 외부 제공자 키를 저장한 적이 있는지입니다. 공지가 대상을 외부 제공자를 연결한 Console 사용자 일부로 좁혀 두었으니, 그 질문에 아니라고 답할 수 있다면 급하게 움직일 일은 아닙니다.
키를 저장한 적이 있다면 이메일 수신 여부와 상관없이 그 키를 교체하기를 권합니다. 이메일을 받았다면 폐기가 먼저이고, 받지 않았다면 새 키를 깔고 끊는 순서를 택해도 충분합니다. 어느 쪽이든 마무리는 제공자 콘솔의 사용량 확인입니다.
CLI 쪽은 이번 기회에 키 위치를 한 곳으로 모아 두는 것이 제 선택입니다. auth.json과 환경 변수, 설정 파일에 흩어진 키는 사고 때 어디를 지워야 하는지부터 헷갈리게 만듭니다. enabled_providers로 쓸 제공자만 열고, 키는 권한 600 파일에서 {file:}로 읽고, 점검은 debug config와 auth list로 끝내는 구성이면 다음 교체도 파일 하나만 바꾸면 됩니다.
보도된 이메일이 Console 워크스페이스에 저장된 키를 지목하고 있으니, 순서는 제공자 대시보드에서 그 키를 끊는 것, 새 키를 로컬 파일로만 들이는 것, 공지 시각 앞뒤의 사용량을 확인하는 것입니다. 원인에 대한 더 자세한 설명은 OpenCode의 다음 공지가 나오면 그때 맞춰 보면 됩니다.





