API 키를 지워도 GitHub 푸시가 막힐 때, 커밋에서 제거하는 법
코드에서 API 키를 지우고 삭제 커밋까지 만들었는데, GitHub는 여전히 같은 키를 지목하며 푸시를 막는다. 파일 어디에도 없는 키를 GitHub는 어디서 찾아낸 걸까?

- 키를 지운 새 커밋을 만들어도 전송할 이전 커밋에 값이 남으면 푸시가 막힐 수 있다.
- 마지막 커밋에만 있다면 amend, 앞선 커밋에도 있다면 해당 기록을 수정해야 한다.
- Anthropic의 두 API 키 유형이 기본 차단 대상에 추가됐다. 이미 노출된 키는 발급사에서 폐기해야 한다.
푸시는 현재 파일만 보내는 작업이 아니다
API 키를 코드에서 지웠는데 GitHub의 push protection이 계속 차단한다면, 오류 메시지에 나온 커밋 ID와 파일 경로를 확인해야 한다. 현재 파일에 키가 없어도 전송할 이전 커밋에 남아 있을 수 있다. GitHub의 차단 해제 절차는 키가 들어 있는 모든 해당 커밋에서 값을 제거하도록 안내한다.
10월 13일 변경으로 Anthropic의 서비스 API 키와 사용자 API 키도 기본 푸시 차단 대상에 추가됐다. Claude API 연동 코드를 올리다가 막혔다면, 차단을 우회하기 전에 키가 들어간 기록부터 고쳐야 한다.
마지막 커밋에만 있다면 새 커밋 대신 원래 커밋을 고친다
키를 처음 넣은 것이 가장 최근 커밋이고 앞선 커밋에는 없다면, 코드에서 키를 제거한 뒤 그 커밋을 수정한다. GitHub가 안내하는 명령은 다음과 같다.
git commit --amend --all
git push --amend는 키가 든 원래 커밋을 갱신한다. 반대로 ‘키 삭제’라는 새 커밋만 덧붙이면 그 앞의 커밋은 남는다. 오류 메시지가 더 오래된 커밋도 가리킨다면 마지막 커밋만 수정하는 방법으로는 부족하다.
이전 커밋에 있다면 처음 들어간 위치부터 되짚는다
GitHub는 차단 메시지의 커밋 목록을 git log와 대조해 키가 들어 있는 가장 이른 커밋을 찾도록 안내한다. 그 커밋에 부모가 있고, 아직 전송하지 못한 로컬 기록을 정리하는 경우에는 다음과 같이 대화형 rebase를 시작한다.
git rebase -i <COMMIT-ID>~1 <COMMIT-ID>는 앞에서 찾은 커밋 ID로 바꾼다. 편집기에서 해당 커밋의 pick을 edit으로 바꾸고, 중단된 지점에서 키를 제거한 뒤 변경 파일을 스테이징하고 커밋을 수정한다. 이후 git rebase --continue로 진행한다. 뒤의 변경이 키를 다시 넣는다면 그 부분까지 정리해야 한다.
충돌이 생기면 Git의 rebase 문서에 따라 충돌 내용을 수정하고 해당 파일을 git add한 뒤 계속한다. 작업을 취소해 시작 전 브랜치 상태로 돌아가는 명령은 git rebase --abort다. 루트 커밋에는 부모가 없으므로 위의 ~1 예제를 그대로 적용할 수 없다.
핵심은 최신 파일에서만 키를 없애는 것이 아니라, 이번에 보낼 기록에서도 없애는 데 있다. 정리 후 다시 푸시했을 때 다른 커밋이 차단 메시지에 나온다면 그 위치를 이어서 확인한다.
이미 공개된 키는 커밋 수정과 별도로 폐기한다
키가 이미 저장소에 올라갔거나 노출이 의심된다면 기록 수정만으로 끝낼 수 없다. Anthropic은 해당 키를 즉시 폐기하도록 안내한다. Claude Console의 API keys 페이지에서 키 옆 메뉴의 Delete API key를 선택하고, 필요한 새 키는 Create key로 발급한다.
새 값은 앱의 비밀 저장소나 환경변수 설정에 반영한다. Anthropic의 키 관리 안내는 로컬 dotenv를 사용한다면 .env를 버전 관리 제외 목록에 넣고, 클라우드에서는 암호화된 비밀 저장소를 쓰도록 권한다. 과거 커밋 정리와 앞으로의 저장 방법을 함께 바꿔야 한다.
GitHub가 공개 저장소에서 Claude API 키를 발견해 통보하면 Anthropic이 해당 키를 자동 비활성화하는 연동도 있다. 이는 공개 저장소 감지에 대한 조치다. 노출을 알고 있는 개발자가 통보를 기다릴 이유는 없으며, 직접 키를 폐기하고 새 값으로 교체해야 한다.
키 유형의 기본 차단과 저장소 보호 설정은 구분한다
이번에 추가된 패턴은 anthropic_service_api_key와 anthropic_user_api_key다. 모든 비공개 저장소의 보안 설정이 자동으로 켜졌다는 뜻은 아니다.
GitHub는 보호를 두 종류로 나눈다. 사용자용 푸시 보호는 GitHub.com 계정에서 기본 활성화돼 공개 저장소로의 비밀값 전송을 막는다. 저장소용 푸시 보호는 GitHub Secret Protection이 활성화된 곳에서 관리자가 설정하며, 기본 상태는 비활성이다.
따라서 비공개 저장소의 보호 여부는 해당 저장소 설정으로 확인해야 한다. 이미 차단된 개발자의 다음 단계는 명확하다. 오류가 지목한 기록을 고치고, 노출된 값은 발급사에서 폐기한 뒤, 새 키를 소스 코드 밖에서 관리한다.