시크릿(Secret) 로테이션은 값을 업데이트하는 것만으로는 끝나지 않는다
요약
LLM 서비스 사용 증가에 따라 API 키 관리 및 로테이션이 중요해졌습니다. 환경 변수 방식은 인스턴스 재부팅 없이는 업데이트 반영이 어렵고, 파일 마운트 역시 애플리케이션 레벨의 주기적 읽기 메커니즘이 필요합니다. 따라서 '듀얼 키 구성'이나 시크릿 매니저 API 직접 호출 등 무정지 전환 전략을 수립해야 합니다.
핵심 포인트
- API 키 로테이션은 단순히 값 업데이트만으로는 부족하다.
- 환경 변수 방식은 인스턴스 재부팅이 필요하여 서비스 중단 위험이 있다.
- 듀얼 키 구성(신구키 병존)은 무정지 전환에 효과적인 방법이다.
- 파일 마운트 시에도 애플리케이션 코드 레벨에서 주기적 업데이트 로직이 필요하다.
서론
LLM 서비스의 보급으로 API 키를 다루는 기회가 늘어났습니다.
하지만, 이를 기반으로 하는 코딩 에이전트 등으로 개발할 경우 로컬 환경이 외부로 전송되는 기회가 증가하고, 기존 소프트웨어의 분석 속도도 빨라졌습니다.
API 키나 비밀번호는 유출될 것을 전제로 개발을 진행해야 하며, 부정 사용이 확인된 경우에는 신속하게 로테이션(rotation)을 수행해야 합니다.
그리고 안정적인 운영을 위해서는 API 키를 변경했을 때 현재 작동 중인 애플리케이션에 어떤 영향을 미치는지 파악하고 있어야 합니다.
시크릿과 컴퓨팅의 라이프사이클
많은 가상 머신(VM)에서는 관리형 시크릿 서비스(managed secret service)의 값을 참조할 수 있습니다.
이때 환경 변수(environment variable)로 전달되는 경우, 기본적으로 머신이 시작될 때 한 번만 로드됩니다.

즉, 값을 변경하더라도 당분간은 이전 값을 환경 변수로 유지한 인스턴스가 남아있습니다.
API 키 업데이트와 같은 임시적인 작업에서는 인스턴스를 재부팅하는 것까지 수동으로 할 것이라고 생각하지만, API 키의 만료 시점과 재부팅 시점이 어긋나면 그 사이에는 실질적으로 서비스가 멈추게 됩니다.
대부분의 경우 이 정도는 허용 범위일 것이라 생각하지만, '절대로 서비스를 중단해서는 안 된다!'라고 근성론을 주장하는 사람이 있다면 다른 수단을 마련해야 합니다.
듀얼 키 구성
외부 서비스 측에서 여러 API 키를 동시에 활성화할 수 있는 경우, 신구(新舊) 키가 모두 사용 가능한 기간을 설정할 수 있습니다.
이를 통해 모든 인스턴스가 일제히 키를 전환할 필요가 없어집니다.
절차는 다음과 같습니다.
- 이전 키 A를 활성화한 상태로 새로운 키 B를 발행합니다.
- 시크릿 매니저에 키 B를 등록합니다.
- 애플리케이션을 순차적으로 재시작 및 재배포하여 키 B로 전환합니다.
- 이전 인스턴스나 배치 작업까지 포함하여 전환되었는지 확인하고, 외부 서비스 측에서 키 A를 만료시킵니다.
환경 변수로 전달하는 구성이라도 로링 업데이트(rolling update) 등과 결합하면 전환 중의 인증 오류를 피하기 쉽습니다.
Azure Storage처럼 두 개의 액세스 키를 번갈아 가며 업데이트할 수 있는 서비스도 있습니다.
다만, 시크릿 매니저에 새로운 값을 저장하는 것과 외부 서비스 측에서 이전 키를 만료시키는 것은 별개의 작업입니다. 단순히 저장만 한다고 해서 유출된 키가 사용할 수 없게 되는 것은 아닙니다.
또한, 부정 사용이 진행 중인 경우에는 무정지 전환을 기다리지 않고 이전 키를 만료시킬 판단도 필요합니다. 신구 키의 병존 기간은 길다고 좋은 것이 아닙니다.
파일 마운트
시크릿을 환경 변수가 아닌 파일로 전달하여 애플리케이션에서 다시 읽어오는 방법도 있습니다.
실행 기반이 시크릿 업데이트를 파일 읽기에 반영할 수 있다면, 인스턴스를 재부팅하지 않고 새로운 값을 얻을 수 있습니다.
예를 들어 Cloud Run에서는 시크릿을 볼륨으로 마운트할 수 있습니다. 버전에 latest를 지정하면 파일 읽기 시점에 최신 시크릿을 가져올 수 있습니다. 특정 버전 번호로 고정하는 경우, 새로운 버전을 추가해도 참조 위치는 변하지 않습니다.
다만, 파일을 마운트했다고 해서 애플리케이션 설정이 자동으로 업데이트되는 것은 아닙니다.
시작 시점에 한 번만 파일을 읽어 API 클라이언트 초기화에 사용하는 경우라면, 결국 이전 키를 계속 유지하게 됩니다. 주기적으로 다시 읽거나, 클라이언트를 새로 만드는 등 애플리케이션 측에서도 업데이트를 받아들이는 메커니즘이 필요합니다.
또한, 업데이트 반영 방법이나 타이밍은 실행 기반마다 다릅니다. 읽기에 실패했을 경우의 처리까지 확인해 두어야 합니다.
시크릿 매니저의 API를 앱에서 호출하기
애플리케이션 자체가 시크릿 매니저의 API로부터 값을 가져오는 방법입니다.
획득과 업데이트 타이밍을 직접 제어할 수 있기 때문에, 실행 기반의 환경 변수나 파일 마운트 메커니즘에 의존하지 않고 구현할 수 있습니다.
다만, 시작 시점에 한 번만 획득한다면, 업데이트 추적이라는 점에서는 환경 변수와 같습니다.
주기적으로 다시 획득하는 등 작동 중에 값을 업데이트하는 설계가 필요합니다.
매 요청마다 가져오는 것이 좋을 것 같기도 하지만, 통신 지연이나 접근 횟수에 따른 요금, API 할당 제한이 신경 쓰입니다. 시크릿 매니저 측의 장애도 애플리케이션 처리에 직접적인 영향을 줍니다.
따라서 일정 시간은 메모리에 캐시하고, 기한이 되면 다시 가져오는 구성이 생각됩니다.
이 경우, 다음 사항들을 결정해 두어야 합니다.
- 캐시의 유효 기간과, 모든 인스턴스에 새로운 값이 전달될 때까지 걸리는 시간
- 가져오기에 실패했을 때 이전 값을 계속 사용할지, 아니면 처리를 멈출지
- 키가 변경되었을 때 API 클라이언트나 연결 풀(connection pool)을 다시 만들어야 하는지
- 새로운 값으로 문제가 발생했을 경우, 어떤 버전으로 되돌릴지
최신 버전을 자동으로 참조하면 잘못된 값도 구동 중인 애플리케이션에 반영됩니다. 버전을 고정하면 전환을 제어하기 쉽지만, 그 참조 대상을 업데이트하는 메커니즘이 별도로 필요합니다.
또한, 시크릿(secret)을 가져오기 위한 인증에는 가능하면 실행 환경에 연결된 서비스 계정 등을 이용합니다. 가져오는 데 사용되는 장기 키를 따로 내장하게 되면 관리해야 할 시크릿이 하나 더 늘어나게 됩니다.
파일 마운트나 API 경유의 가져오기는 '새로운 키를 구동 중인 애플리케이션에 전달하는 방법'이며, 듀얼 키 구성(dual key configuration)은 '전환 중에 신규/구 버전의 키를 사용할 수 있도록 하는 방법'입니다. 이 둘을 조합하여 사용하고, 업데이트가 완료될 때까지 걸리는 시간을 확인한 후 이전 키를 비활성화하면 절차를 정리하기 쉽습니다.
맺음말
운영 부하(operational load), 가용성(availability), 그리고 보안(security) 사이에는 어느 정도의 트레이드오프가 존재합니다.
가용성 요구 사항이 엄격하지 않다면, 부정 사용이 발각된 후 수동 업데이트만으로도 충분할 것입니다.
근성이 아닌, 시스템적인 메커니즘으로 스마트하게 해결합시다.
논의
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기