NEW: RSAC 2026 NHI 현장 리포트 — 비인간 아이덴티티가 사이버보안의 중심축이 된 이유
블로그로 돌아가기
보안산업 인사이트

NHI Kill Chain: Aged Key — 3년간 로테이션 없이 프로덕션을 지탱한 열쇠의 결말

3년간 로테이션 없이 7개 시스템에 퍼진 AWS 키 하나. 공급망 공격으로 이 키가 탈취되었을 때, 공격자는 인프라 전체에 접근할 수 있었습니다. Aged Key 킬체인 분석과 단계적 로테이션 대응 가이드.

김동현
작성자
김동현
14
Share:
NHI Kill Chain: Aged Key — 3년간 로테이션 없이 프로덕션을 지탱한 열쇠의 결말

Key Takeaways

  • Aged Key는 로테이션 없이 장기간 유지된 NHI 크리덴셜로, 시간이 지날수록 권한 범위, 복사본 수, 의존 시스템이 누적되어 폭발 반경이 기하급수적으로 커진다
  • OWASP NHI Top 10은 부적절한 크리덴셜 로테이션(Inadequate Credential Rotation)을 핵심 리스크로 선정했으며, CSA 2026 보고서에 따르면 체계적 로테이션 정책을 운용하는 조직은 소수에 불과하다
  • 장기 미로테이션 키는 "이거 건드리면 프로덕션 죽는다"는 공포를 만들어내며, 이 공포가 로테이션을 계속 미루는 악순환의 원인이 된다
  • 하나의 키가 Terraform state, CI/CD 파이프라인, 로컬 .env, Slack 런북 등 여러 곳에 복사되면 공격 표면이 N배로 확대되고, 로테이션 시 의존 시스템 전부가 장애 위험에 노출된다
  • CodeCov 2021, CircleCI 2023, Travis CI 토큰 유출 등 실제 침해 사례에서 장기 미로테이션 크리덴셜이 핵심 공격 벡터로 작동했다
  • Aged Key 대응의 핵심은 단계적 로테이션 전략으로, 의존 관계를 먼저 매핑한 뒤 blast radius가 작은 시스템부터 순차적으로 교체해야 한다
  • Cremit Argus는 크리덴셜 수명(age) 모니터링과 복사본 확산(sprawl) 탐지를 자동화하여 Aged Key가 임계점에 도달하기 전에 식별한다

"이 키를 바꾸면 프로덕션이 죽습니다"

2022년 봄, 서울의 한 SaaS 스타트업. 시리즈 A를 막 마감했고, 직원은 12명이었습니다. CTO가 직접 Terraform으로 AWS 인프라를 세팅하고 있었습니다. VPC, RDS, ECS, S3, CloudFront — 프로덕션 인프라 전체를 이 한 명이 구축했습니다. 이때 만든 IAM Access Key 하나가 이 글의 주인공입니다.

그 키는 AdministratorAccess에 가까운 권한을 가지고 있었습니다. 스타트업 초기에 흔한 일입니다. 리소스별로 최소 권한을 설정하고 역할을 분리할 여유가 없었습니다. "일단 돌아가게 만들자"는 것이 최우선이었고, 권한 분리는 "나중에"로 밀렸습니다. 그 "나중에"는 오지 않았습니다.

3년이 흘렀습니다. 2025년. 회사는 50명으로 성장했습니다. 시리즈 B를 준비 중이었고, 인프라팀도 5명으로 늘어났습니다. 하지만 그 키는 여전히 거기 있었습니다. 한 번도 로테이션된 적 없이.

3년 동안 이 키가 퍼진 경로를 추적하면 소름이 돋습니다.

첫째, Terraform state backend의 인증 수단. 이 키가 없으면 Terraform이 state를 읽지 못하고, state를 읽지 못하면 인프라 변경이 불가능합니다. 둘째, Jenkins 파이프라인 3개에 환경변수로 하드코딩. 배포가 이 키에 의존하고 있었습니다. 셋째, 프론트엔드팀과 데이터팀의 로컬 `.env` 파일에 복사본이 존재. "AWS 접근이 필요해서" 슬랙으로 전달받은 것이었습니다. 넷째, Slack의 장애 대응 런북에 "긴급 상황 시 이 키로 AWS 콘솔에 접속하세요"라는 메모와 함께 평문으로 기록.

한 개의 키가 최소 7개 지점에 존재하고 있었습니다.

그리고 아무도 이 키를 바꾸려 하지 않았습니다. 이유는 하나였습니다.

"이거 건드리면 프로덕션 죽어요."

이 한마디가 3년간 로테이션을 막았습니다. 실제로 Terraform state backend의 키를 교체하려면 모든 환경의 backend 설정을 동시에 업데이트해야 합니다. Jenkins 파이프라인의 키를 바꾸면 배포가 멈춥니다. `.env`에 복사된 키를 바꾸면 각 팀의 로컬 개발 환경이 깨집니다. 한 곳이라도 빠뜨리면 장애입니다. 그래서 아무도 건드리지 않았고, 키는 하루하루 더 위험해졌습니다.

2025년 가을, 파국이 찾아왔습니다. 인프라팀이 사용하던 Terraform CI 플러그인 — 커뮤니티가 관리하는 서드파티 provider — 이 공급망 공격에 노출되었습니다. 공격자가 이 플러그인의 새 버전에 악성 코드를 삽입했고, CI 파이프라인이 이 버전을 자동으로 다운로드해 실행했습니다. 악성 코드의 동작은 단순했습니다. 실행 환경의 환경변수에서 AWS 크리덴셜을 읽어 외부 서버로 전송하는 것.

Jenkins 파이프라인에 하드코딩된 그 키가 유출되었습니다. 3년간 AdministratorAccess 권한을 가진, 한 번도 로테이션 되지 않은 키가.

공격자는 이 키로 프로덕션 RDS의 스냅샷을 생성해 외부 계정으로 복사했습니다. S3 버킷에 저장된 고객 데이터에 접근했습니다. CloudTrail 로그를 삭제하려 시도했습니다(다행히 별도 계정에 로그가 백업되어 있었지만). 3년간 권한 축소 없이 유지된 키의 폭발 반경은 인프라 전체였습니다.

침해를 인지한 후 대응 과정도 고통스러웠습니다. 키를 즉시 로테이션해야 했지만, 이 키에 의존하는 시스템이 너무 많았습니다. 키를 폐기하면 Terraform이 멈추고, Jenkins 배포가 중단되고, 두 팀의 개발 환경이 깨집니다. 침해 대응과 서비스 가용성 사이에서 선택해야 하는 최악의 상황. "건드리면 프로덕션 죽는다"는 공포가 3년간 쌓아온 기술 부채가, 침해 순간에 한꺼번에 청구서로 돌아온 겁니다.

이 키는 왜 위험한가

Aged Key는 로테이션 없이 장기간 유지된 NHI 크리덴셜입니다. Public Key(공개 노출)나 Ghost Key(퇴사자 방치)와는 위험의 성격이 다릅니다. Aged Key의 위험은 시간에 비례해서 누적됩니다. 키가 존재하는 날 수가 하루 늘 때마다 세 가지가 동시에 커집니다: 복사본의 수, 의존 시스템의 수, 그리고 로테이션에 대한 공포.

OWASP NHI Top 10은 부적절한 크리덴셜 로테이션(Inadequate Credential Rotation)을 핵심 리스크 항목으로 선정했습니다. 키를 주기적으로 교체하지 않으면 단순히 "오래된 키가 존재한다" 수준이 아니라, 조직 전체의 보안 태세가 구조적으로 약화된다는 의미입니다. CSA의 2026 State of NHI Security 보고서에서도 크리덴셜 수명 관리의 실패가 NHI 보안의 가장 큰 취약점 중 하나로 꼽혔습니다.

복사본 확산(Credential Sprawl)이 첫 번째 구조적 위험입니다. 키가 오래 살아남을수록 더 많은 사람과 시스템에 복사됩니다. 처음에는 CTO 한 명의 Terraform 설정에만 있던 키가, 1년 후에는 CI/CD 파이프라인에, 2년 후에는 다른 팀의 `.env`에, 3년 후에는 Slack 런북에까지 퍼져 있습니다. 키 하나가 N개 지점에 존재하면 공격 표면이 N배로 확대됩니다. 공급망 공격이 어느 한 지점만 뚫어도 키가 유출됩니다.

권한 고착화(Permission Ossification)가 두 번째 문제입니다. 키가 처음 생성될 때는 "당장 필요하니까"라는 이유로 넓은 권한이 부여됩니다. 문제는 그 넓은 권한이 시간이 지나도 줄어들지 않는다는 점입니다. 최소 권한 원칙(Principle of Least Privilege)은 보안의 기본이지만, 이미 작동하고 있는 키의 권한을 축소하는 것은 아무도 하지 않습니다. "잘 돌아가는데 왜 건드려?" — 이 사고방식이 3년간 AdministratorAccess 권한을 유지시킵니다.

로테이션 공포(Rotation Fear)가 세 번째이자 가장 치명적인 위험입니다. 키가 오래 유지될수록 의존하는 시스템이 늘어나고, 의존 시스템이 많을수록 로테이션의 영향 범위가 커지고, 영향 범위가 클수록 "건드리면 죽는다"는 공포가 커집니다. 이 공포가 로테이션을 더 미루게 하고, 미루는 동안 의존 시스템은 더 늘어납니다. 양의 피드백 루프입니다. 시간이 갈수록 로테이션이 더 어려워지는 구조.

이 세 가지가 합쳐지면 Aged Key는 일종의 "골든 키(skeleton key)"가 됩니다. 넓은 권한, 여러 곳에 복사, 교체 불가능. 공격자 입장에서 이보다 매력적인 타겟은 없습니다.

Kill Chain — Aged Key가 침해로 이어지는 5단계

Aged Key의 킬 체인은 Public Key(4분 만에 봇이 발견)나 Ghost Key(인포스틸러로 다크웹 유출)와 다릅니다. Aged Key는 급격한 사건이 아니라 느린 누적입니다. 3년에 걸쳐 천천히 위험이 쌓이고, 어느 순간 외부 트리거 하나로 모든 것이 무너집니다.

1단계: 크리덴셜 노화(Credential Aging)

키가 생성된 후 로테이션 없이 시간이 흐릅니다. 생성 시점에 부여된 과도한 권한이 그대로 유지됩니다. AWS IAM 키가 AdministratorAccess 수준의 정책과 연결된 채 1년, 2년, 3년이 지납니다. 이 단계에서는 아무런 사건도 일어나지 않습니다. 키는 정상적으로 작동하고, 인프라는 잘 돌아가고, 보안 팀의 대시보드에도 아무 경고가 뜨지 않습니다. 바로 그것이 문제입니다. "작동하고 있으니 안전하다"는 착각이 이 단계를 지배합니다.

2단계: 크리덴셜 확산(Credential Sprawl)

시간이 지나면서 키가 원래 위치를 벗어나 여러 시스템으로 복사됩니다. 새 팀원이 "AWS 접근이 필요하다"고 하면 기존 키를 슬랙으로 전달합니다. CI/CD 파이프라인을 하나 더 만들 때 기존 키를 복사해서 환경변수에 넣습니다. 장애 대응 문서에 "긴급 시 이 키를 사용하세요"라고 적습니다. 각각의 행위는 개별적으로 보면 이해할 수 있는 선택이지만, 누적되면 하나의 키가 조직 전체에 퍼져 있는 상황이 만들어집니다. 그리고 어디에 복사본이 있는지를 정확히 아는 사람은 아무도 없습니다.

3단계: 공급망 침해(Supply Chain Compromise)

Aged Key가 유출되는 경로는 Ghost Key의 인포스틸러와는 다릅니다. Aged Key는 여러 곳에 복사되어 있으므로, 그 중 어느 한 곳이라도 침해되면 키가 유출됩니다. 이 시나리오에서는 Terraform CI 플러그인이 공급망 공격에 노출되었습니다. 하지만 경로는 달라질 수 있습니다. Jenkins 서버가 해킹될 수도 있고, Slack 채널이 유출될 수도 있고, 팀원의 로컬 `.env`가 인포스틸러에 의해 수집될 수도 있습니다. 키가 존재하는 지점이 N개이면 공격 경로도 N개입니다.

4단계: 전체 범위 접근(Full-Scope Access)

유출된 키로 공격자가 인프라에 접근합니다. 여기서 Aged Key의 핵심 위험이 현실화됩니다. 3년간 축소되지 않은 권한. AdministratorAccess에 가까운 정책. 공격자는 권한 상승 같은 추가 작업 없이, 탈취한 키 하나만으로 프로덕션 인프라 전체에 접근할 수 있습니다. RDS 데이터베이스, S3 버킷, ECS 클러스터, Lambda 함수, CloudFront 배포 — 키 생성 당시 CTO가 인프라 전체를 세팅하기 위해 필요했던 모든 권한이 공격자의 손에 들어갑니다.

5단계: 연쇄 장애(Cascading Impact)

침해를 인지한 후 대응 단계에서 Aged Key만의 독특한 문제가 나타납니다. 일반적인 크리덴셜 침해라면 즉시 키를 폐기하면 됩니다. 하지만 Aged Key는 7개 지점에 의존 관계가 걸려 있습니다. 키를 폐기하면 Terraform state가 잠기고, Jenkins 배포가 멈추고, 두 팀의 개발 환경이 중단됩니다. 공격자에게 시간을 주느냐, 서비스를 멈추느냐 — 어느 쪽을 택해도 피해가 발생합니다. 이것이 3년간 로테이션을 미룬 대가입니다. 정상 상태에서의 로테이션은 계획적으로 할 수 있지만, 침해 상황에서의 로테이션은 혼란 속에서 즉시 실행해야 합니다. 그리고 혼란 속에서 7개 시스템의 의존 관계를 동시에 처리하는 것은 거의 불가능합니다.

왜 기존 보안 체계로는 잡히지 않는가

Aged Key의 구조적 위험이 이토록 명확한데, 왜 기존 보안 도구와 프로세스는 이걸 잡지 못할까요?

"작동하고 있으니 안전하다"는 착각

Aged Key가 방치되는 가장 근본적인 이유는 기술적 한계가 아니라 심리적 착각입니다. 키가 3년간 정상적으로 작동하면, 사람들은 그것이 "안정적"이라고 인식합니다. 매일 Terraform plan이 성공하고, Jenkins 배포가 돌아가고, 서비스가 정상이면 — 굳이 왜 바꿔야 합니까? 보안의 관점에서 보면 3년간 로테이션 없이 유지된 키는 시한폭탄이지만, 운영의 관점에서 보면 "가장 검증된 설정"입니다. 이 인식 차이가 Aged Key를 계속 방치하게 만듭니다.

IAM 정책 감사의 한계

분기별 또는 연간 IAM 정책 감사를 실시하는 조직이 있습니다. 하지만 이런 감사는 대부분 "누가 어떤 역할에 속해 있는가", "어떤 정책이 어떤 사용자에게 연결되어 있는가"에 초점을 맞춥니다. "이 키가 언제 생성되었고, 마지막 로테이션은 언제였으며, 몇 개의 시스템에 복사되어 있는가"를 확인하는 감사는 드뭅니다. IAM 도구 자체가 키의 수명(age)을 경고 지표로 사용하도록 설계되어 있지 않기 때문입니다. AWS IAM은 키의 생성일자를 표시하지만, 90일이 지나도, 365일이 지나도, 1000일이 지나도 알림을 보내지 않습니다. 직접 설정하지 않는 한.

Secrets Manager 도입의 착시

"우리는 AWS Secrets Manager(또는 Vault, GCP Secret Manager)를 쓰고 있으니 괜찮다"는 말을 자주 듣습니다. Secrets Manager는 크리덴셜의 중앙화된 저장과 자동 로테이션을 지원합니다. 문제는 Secrets Manager가 관리하는 키만 보호된다는 것입니다. 3년 전에 CTO가 만들어서 Jenkins에 하드코딩한 키, 슬랙 런북에 평문으로 적힌 키, `.env` 파일에 복사된 키 — 이것들은 Secrets Manager의 관리 대상에 포함되어 있지 않습니다. Secrets Manager 밖에서 돌아다니는 키는 Secrets Manager의 존재와 무관하게 Aged Key로 성장합니다.

기존 스캐닝 도구의 범위

시크릿 스캐닝 도구는 Git 리포지토리나 CI/CD 설정에서 하드코딩된 크리덴셜을 탐지합니다. 유용합니다. 하지만 대부분의 스캐닝 도구는 "이 크리덴셜이 하드코딩되어 있다"는 사실은 알려주지만, "이 크리덴셜이 1,095일 전에 생성되어 한 번도 로테이션 되지 않았고, 현재 7개 시스템에 복사본이 존재한다"는 맥락은 제공하지 않습니다. 하드코딩의 존재 자체보다 더 위험한 것은 그 하드코딩된 키의 수명과 확산 범위인데, 기존 도구는 이 차원을 다루지 않습니다.

인프라 관리자 교체의 맹점

스타트업에서 CTO나 초기 인프라 엔지니어가 퇴사하면, 그 사람이 만든 키의 전체 목록을 아는 사람이 사라집니다. 인수인계 문서에 "Terraform용 AWS 키"라고 적혀 있을 수 있지만, 그 키가 Jenkins에도 들어가 있고 다른 팀의 `.env`에도 복사되어 있다는 사실은 인수인계 문서에 없습니다. 새로 온 인프라 엔지니어는 "작동하는 설정을 건드리지 않는다"는 원칙에 따라 기존 키를 그대로 사용합니다. Aged Key가 세대를 건너뛰어 살아남는 메커니즘입니다.

실제 침해 사례와 업계 데이터

Aged Key는 이론적인 시나리오가 아닙니다. 장기 미로테이션 크리덴셜이 침해의 핵심 벡터로 작동한 사례는 반복적으로 기록되어 있습니다.

CodeCov 2021: 2개월간 방치된 크리덴셜

2021년 CodeCov 침해 사건은 Aged Key와 공급망 공격이 결합된 대표적 사례입니다. 공격자는 CodeCov의 Docker 이미지 빌드 프로세스에 침투해 Bash Uploader 스크립트를 변조했습니다. 이 스크립트는 CI 환경에서 실행되면서 환경변수에 저장된 크리덴셜 — AWS 키, GitHub 토큰, API 시크릿 등 — 을 외부 서버로 전송했습니다. 2개월 넘게 발각되지 않았고, 이 기간 동안 CodeCov를 사용하는 수천 개 조직의 CI 환경에서 크리덴셜이 유출되었습니다. 로테이션 주기가 짧았던 키는 이미 무효화되어 있었지만, 장기 미로테이션 키는 유출 시점에 여전히 유효했고, 이것이 실제 침해로 이어진 사례가 다수 보고되었습니다.

CircleCI 2023: CI/CD 환경의 크리덴셜 대량 유출

2023년 1월 CircleCI 침해 사건에서 공격자는 엔지니어의 노트북에 감염된 악성코드를 통해 SSO 세션 토큰을 탈취하고, CircleCI의 내부 시스템에 접근했습니다. 이를 통해 고객 환경에 저장된 시크릿에 접근할 수 있었습니다. CircleCI는 모든 고객에게 시크릿 로테이션을 긴급 권고해야 했습니다. 여기서 핵심 교훈은 CI/CD 파이프라인에 하드코딩된 장기 키가 단일 침해 지점을 통해 대량으로 유출될 수 있다는 것입니다. 로테이션 주기가 90일이었던 조직은 키가 이미 무효화되어 있었을 가능성이 높지만, "한 번 설정하고 잊어버린" 키를 사용하던 조직은 직접적인 피해를 입었습니다.

Travis CI 토큰 유출: 수만 개 프로젝트의 키 노출

Travis CI에서도 유사한 사건이 반복되었습니다. 보안 연구자들이 Travis CI의 API를 통해 수만 개 프로젝트의 환경변수 — 여기에는 GitHub 토큰, AWS 키, Docker Hub 크리덴셜 등이 포함 — 에 접근 가능한 취약점을 발견했습니다. 노출된 크리덴셜 중 상당수가 수년간 로테이션 되지 않은 장기 키였으며, 발견 시점에도 유효한 상태였습니다. 로테이션 정책이 있었던 조직의 키는 이미 만료되어 있었지만, 정책이 없던 조직의 키는 공격자가 즉시 악용할 수 있는 상태였습니다.

업계 데이터가 보여주는 규모

CSA 2026 State of NHI Security 보고서에 따르면, NHI 크리덴셜의 수명 관리에 대한 체계적 정책을 운용하는 조직은 소수입니다. 대부분의 조직이 "인프라가 잘 돌아가면 키도 괜찮다"는 가정 하에 크리덴셜을 방치하고 있습니다.

OWASP NHI Top 10은 부적절한 크리덴셜 로테이션을 핵심 리스크 항목에 포함시켰습니다. 이는 로테이션 실패가 개별 사고가 아니라 구조적이고 산업 전반에 걸친 문제라는 인식을 반영합니다.

AWS의 공식 보안 권장 사항에서도 IAM Access Key는 90일마다 로테이션할 것을 명시하고 있습니다. 하지만 이 권장을 실제로 준수하는 조직은 극소수입니다. 1,095일(3년) 된 키가 프로덕션을 지탱하고 있다는 것은, AWS의 권고 로테이션 주기를 12배 이상 초과한 것입니다.

GitGuardian의 2024 State of Secrets Sprawl 보고서는 또 다른 차원의 데이터를 제공합니다. 공개 GitHub 리포지토리에 노출된 시크릿의 90% 이상이 5일이 지나도 여전히 유효한 상태입니다. 공개 노출된 키도 이 정도인데, 비공개 환경에서 조용히 늙어가는 Aged Key의 유효 기간은 사실상 무제한입니다.

탐지 및 대응 가이드

Aged Key 대응의 핵심은 "한 번에 키를 교체하는 것"이 아니라 "단계적으로, 의존 관계를 파악하면서 교체하는 것"입니다. 3년간 7개 시스템에 퍼져 있는 키를 즉시 폐기하면 프로덕션이 멈추기 때문입니다. 계획적이고 체계적인 접근이 필요합니다.

1단계: 크리덴셜 수명 감사(Age Audit)

먼저 조직 내 모든 NHI 크리덴셜의 생성일자와 마지막 로테이션 일자를 확인합니다. AWS CLI로 `aws iam list-access-keys`를 실행하면 각 IAM 키의 `CreateDate`를 알 수 있습니다. 생성일 기준으로 90일 이상 된 키를 모두 리스트업합니다. 90일은 AWS 공식 권장 로테이션 주기입니다. 180일 이상은 즉시 조치 대상, 365일 이상은 긴급 조치 대상으로 분류합니다. 1,095일(3년) 이상이면 — 이 글의 시나리오처럼 — 이미 임계점을 넘긴 것으로 간주합니다.

2단계: 복사본 확산 매핑(Sprawl Mapping)

키가 어디에 존재하는지 전부 파악합니다. 이것이 가장 어렵고 가장 중요한 단계입니다. Terraform 설정, CI/CD 파이프라인, `.env` 파일, Slack 메시지, Confluence 문서, 장애 대응 런북, 로컬 개발 환경 — 키가 복사될 수 있는 모든 지점을 조사합니다. 하나라도 빠뜨리면 로테이션 후 해당 시스템에서 장애가 발생합니다. 그리고 빠뜨린 복사본은 여전히 이전 키 값을 사용하므로, 로테이션의 보안 효과도 없습니다.

3단계: 의존 관계 분석(Dependency Analysis)

각 복사본이 어떤 시스템의 어떤 기능에 영향을 미치는지 파악합니다. Terraform state backend의 키가 교체되면 모든 Terraform 명령이 실패합니다. Jenkins 파이프라인의 키가 교체되면 배포가 중단됩니다. 각 의존 관계의 영향 범위(blast radius)를 산정하고, 교체 순서를 결정합니다. blast radius가 작은 시스템부터 시작합니다.

4단계: 단계적 로테이션(Staged Rotation)

가장 영향이 적은 시스템부터 순서대로 키를 교체합니다. AWS IAM의 경우 새 키를 먼저 생성하고, 모든 시스템에 새 키를 적용한 뒤, 구 키가 더 이상 사용되지 않음을 확인한 후에 구 키를 비활성화합니다. 교체 순서의 예시는 다음과 같습니다.

먼저 로컬 `.env` 파일(개인 개발 환경, 영향 범위가 가장 좁음)을 교체합니다. 다음으로 CI/CD 파이프라인 환경변수를 새 키로 교체하고 파이프라인이 정상 실행되는지 확인합니다. 그다음 Terraform state backend의 인증을 교체합니다. 마지막으로 Slack 런북 등 문서에 적힌 평문 키를 삭제하고, 이후에는 키를 문서에 직접 적지 않는 정책을 수립합니다.

5단계: 자동 로테이션 정책 수립(Automated Rotation Policy)

수동 로테이션은 결국 다시 "나중에"로 밀립니다. 로테이션을 자동화해야 합니다. AWS Secrets Manager나 HashiCorp Vault의 자동 로테이션 기능을 활용해 90일마다(또는 더 짧은 주기로) 키가 자동으로 교체되도록 설정합니다. 키를 직접 하드코딩하는 대신, Secrets Manager에서 런타임에 키를 가져오는 패턴으로 아키텍처를 전환합니다. 이렇게 하면 로테이션 시 각 시스템의 설정을 개별적으로 업데이트할 필요가 없습니다.

Aged Key 발견 시: 이미 유출되었을 가능성을 전제

감사 과정에서 365일 이상 된 Aged Key가 발견되면, "아직 유출되지 않았을 것"이라는 가정은 위험합니다. 3년간 여러 곳에 복사된 키는, 그중 한 곳이라도 침해되었을 가능성이 높습니다. 대응 순서는 다음과 같습니다.

  1. 즉시 새 키 생성 — 구 키를 즉시 비활성화하지 않고, 먼저 새 키를 생성합니다
  2. 모든 의존 시스템에 새 키 적용 — sprawl mapping에서 파악한 모든 지점을 업데이트합니다
  3. 구 키 비활성화 — 모든 시스템이 새 키로 정상 작동하는 것을 확인한 후 구 키를 비활성화합니다
  4. 감사 로그 분석 — CloudTrail 로그에서 구 키의 사용 이력을 분석합니다. 비정상적인 리전, 시간대, API 호출 패턴이 있는지 확인합니다
  5. 구 키 영구 삭제 — 확인이 끝나면 구 키를 영구 삭제합니다

시크릿 탐지와 관리에 대한 더 체계적인 접근은 Secret Detection 완벽 가이드Git Secret Scanning 완벽 가이드에서 상세히 다루고 있습니다.

Cremit Argus는 이걸 어떻게 탐지하는가

Aged Key의 핵심 문제는 세 가지입니다. 키가 얼마나 오래되었는지 모르고, 키가 어디에 복사되어 있는지 모르고, 키를 교체하면 무엇이 깨지는지 모릅니다. Argus는 이 세 가지 무지를 해소하도록 설계되었습니다.

크리덴셜 수명(Age) 모니터링. Argus는 조직 내 모든 NHI 크리덴셜의 생성일자와 마지막 로테이션 일자를 지속적으로 추적합니다. 90일 경과 시 경고, 180일 경과 시 위험, 365일 경과 시 긴급 — 수명 기반의 단계별 알림을 자동으로 제공합니다. "이 키는 1,095일 전에 생성되어 한 번도 로테이션 되지 않았습니다"라는 사실이 대시보드에 명확하게 표시됩니다. "작동하니까 안전하다"는 착각을 데이터로 깨뜨립니다.

복사본 확산(Sprawl) 탐지. Argus는 하나의 키가 조직 내 어디에 존재하는지를 크로스 플랫폼으로 스캔합니다. GitHub 리포지토리, CI/CD 파이프라인 설정, Slack 메시지, Confluence 문서, 클라우드 인프라 설정 — 키가 복사될 수 있는 모든 표면을 탐지 대상으로 포함합니다. "이 AWS 키가 Jenkins 3개 파이프라인, GitHub Actions 1개 워크플로우, Slack 메시지 2건, Confluence 페이지 1건에 존재합니다"라는 sprawl map을 자동으로 생성합니다. 로테이션 전에 "어디를 업데이트해야 하는지"를 미리 파악할 수 있습니다.

의존 관계 기반 로테이션 지원. Aged Key의 로테이션이 어려운 이유는 "뭐가 깨질지 모르기 때문"입니다. Argus의 sprawl map은 단순히 "여기에 키가 있다"를 넘어 "이 키가 어떤 시스템의 어떤 기능에 영향을 미치는가"를 보여줍니다. 이를 바탕으로 blast radius가 작은 시스템부터 단계적으로 로테이션하는 계획을 수립할 수 있습니다. "건드리면 죽는다"는 공포를 "이 순서로 바꾸면 안전하다"는 확신으로 전환하는 것이 Argus의 역할입니다.

cremit.io에서 Argus의 크리덴셜 수명 관리와 확산 탐지를 확인해보세요.

NHI Kill Chain 시리즈 안내

이 글은 NHI Kill Chain 시리즈의 세 번째 글입니다. 조직에 잠재하는 위험한 NHI 크리덴셜 유형을 하나씩 분석합니다.

각 유형은 독립적인 위험을 가지면서도 서로 연결되어 있습니다. 공개 저장소에 노출된 키(Public Key)가 로테이션 없이 방치되면 Aged Key가 되고, 퇴사한 개발자의 키(Ghost Key)가 비활성화되지 않으면 시간이 지나면서 Aged Key와 같은 위험을 갖게 됩니다. 하나의 크리덴셜 관리 실패가 다른 유형의 위험으로 전이되는 구조를 이해하는 것이 이 시리즈의 목표입니다.

  1. Ghost Key — 퇴사한 개발자의 AWS 키는 아직 출근 중이다 (읽기)
  2. Shadow Key — Secrets Manager 옆에서 조용히 하드코딩되고 있었다 (읽기)
  3. Aged Key — 3년간 프로덕션을 지탱한 열쇠, 그 결말 (현재 글)
  4. Over-shared Key — Slack Bot Token 하나를 10명이 나눠 쓰면 생기는 일 (coming soon)
  5. Zombie Key — 코드에서 지웠다고 죽은 게 아니다 (coming soon)
  6. Drifted Key — CI/CD 봇이 Jira에 DB 비밀번호를 자동 첨부했다 (coming soon)
  7. Public Key — .env 하나가 GitHub에 올라간 지 4분 만에 일어난 일 (읽기)
  8. Unattributed Key — 이 키의 주인이 누구인지 아무도 모른다 (coming soon)

이전 글: [NHI Kill Chain: Ghost Key — 퇴사한 개발자의 AWS 키는 아직 출근 중이다](/ko/blog/nhi-kill-chain-ghost-key)

다음 글: NHI Kill Chain: Over-shared Key — Slack Bot Token 하나를 10명이 나눠 쓰면 생기는 일

Cremit is an NHI security company. Learn more at cremit.io

NHI 보안API 키클라우드 보안DevSecOpsCI/CD 보안Secret Detection공급망 공격

이 글이 유익하셨나요?

네트워크에 공유해보세요

Share: