본문으로 건너뛰기

least-privilege

최소 권한 드리프트: 사고가 터지기 전에 과도한 권한을 가진 AI 에이전트 잡아내기

작성자 Olivares AI 5 분 소요

최소 권한은 보안에서 가장 오래되고 가장 신뢰할 수 있는 개념 중 하나입니다. 어떤 신원에 필요한 만큼의 액세스만, 그 이상은 일절 부여하지 않으면 침해가 발생하더라도 폭발 반경(blast radius)이 작게 유지됩니다. 사람 계정과 수명이 긴 서비스 계정에 대해서는 이 모델이 비교적 잘 작동합니다. 역할은 검토되고, 권한은 범위가 한정되며, 액세스 인증(access certification)은 분기 단위로 실행됩니다.

AI 에이전트는 이 모델을 조용히 무너뜨립니다. 에이전트에게는 자격 증명, 도구, MCP 서버 연결이 주어지며, 그 순간부터 에이전트의 동작은 동적입니다. 어떤 리소스를 읽을지, 어떤 것을 쓸지, 다음에 어떤 도구를 호출할지를 런타임에 스스로 결정합니다. 첫날에 적어 둔 권한은 천장을 기술할 뿐, 에이전트가 실제로 하는 일을 기술하지 않습니다. 그리고 에이전트는 생산적이기 때문에 그 천장은 관대해지는 경향이 있습니다. 광범위한 데이터베이스 역할, “혹시 모르니” 부여한 쓰기 액세스, 대여섯 개 워크플로에 공유되는 서비스 계정 같은 것들입니다. 그 결과, 허용된 액세스와 실제로 사용되는 액세스가 매일 소리 없이 벌어지는 환경이 만들어집니다.

독립적인 업계 조사는 이 사각지대의 규모를 잘 보여 줍니다. 약 82%의 조직이 자신도 모르게 실행 중인 AI 에이전트가 있다고 보고한 반면, 이를 실시간 인벤토리로 관리하는 조직은 약 21%에 불과합니다(CSA/Token Security, n=418). 볼 수 없는 환경에는 최소 권한을 적용할 수 없습니다.

최소 권한 드리프트의 정의

이 현상을 정확히 명명하겠습니다. 최소 권한 드리프트란 에이전트에게 허용된 액세스와 에이전트가 사용하는 것으로 관찰된 액세스 사이에서 점점 커지는 격차입니다. 여기에는 두 가지 실패 방향이 있는데, 그중 명백한 것은 하나뿐입니다.

명백한 방향은 *과소 사용(under-use)*입니다. 어떤 에이전트가 한 번도 쓴 적 없는 테이블에 대한 쓰기 액세스를 보유하고 있는 경우입니다. 이것은 죽은 권한(dead privilege)이며, 아무런 이득 없이 떠안고 있는 위험입니다. 위험한 방향은 그것이 함의하는 역신호입니다. 관찰된 집합에 허용된 집합이 의도적으로 부여한 적 없는 무언가가 포함되어 있다면, 누구도 검토하지 않은 동작이 일어나고 있는 것입니다. 읽기만 하던 버킷에 갑자기 쓰기를 시작하는 익스포트 작업, 정책이 하나의 스키마로 범위를 한정했는데도 다른 스키마로 뻗어 나가는 에이전트가 그 예입니다. 이런 일은 별난 사례가 아니라, 거친 권한으로 서로 엮인 에이전트들의 일상적인 양상입니다.

이것이 어려운 이유, 그리고 사람이 아닌 에이전트에 특유한 이유는 그 동작이 설정된 것이 아니라 생성된 것이기 때문입니다. 너무 많은 액세스를 가진 사람은 대개 그것을 행사하지 않습니다. 하지만 너무 많은 액세스를 가진 에이전트는 눈앞의 작업을 완료하는 데 도움이 되는 것이라면, 누구도 예상하지 못한 경로를 포함해 무엇이든 행사합니다. 정적인 정책 검토는 실행할 때마다 바뀌는 동작을 따라잡을 수 없습니다.

드리프트를 검토 가능한 신호로 바꾸기

드리프트는 보이지 않는 동안에만 위험합니다. 할 일은 그것을 사람이 검토할 수 있는 신호로 만드는 것이며, 이를 위해서는 두 가지가 함께 작동해야 합니다. 에이전트가 실제로 무엇에 접근하는지에 대한 지속적인 관찰, 그리고 무엇에 접근하도록 허용되었는지에 대한 안정적인 기록입니다.

관찰은 반드시 read-first여야 합니다. 로그, OpenTelemetry 트레이스, eBPF 커널 신호에서 관찰하는 수집기는 에이전트의 데이터 경로 바깥에 위치합니다. 프록시가 아니며, 호출을 게이팅하지 않고, 장애가 나더라도 안전한 의미에서 fail open 합니다. 즉 에이전트는 계속 동작하고, 잃는 것은 가용성이 아니라 가시성입니다. 이 비대칭성은 중요합니다. 운영 환경을 다운시킬 수 있는 보안 통제는 팀이 조용히 비활성화해 버리는 통제입니다. 특히 eBPF 계층은 에이전트가 우회할 수 없는, 커널 수준의 그라운드 트루스(ground truth) 역할을 합니다. 그렇기 때문에 MCP 도구 어노테이션(readOnlyHint, destructiveHint)과 같은 프로토콜 수준의 힌트는 신뢰되는 것이 아니라 이 신호와 대조 검증됩니다. MCP 명세 자체가 그 어노테이션을 신뢰할 수 없는 것으로 규정하고 있으며, 그 대조 검증을 실질적으로 가능하게 하는 것이 바로 커널 신호입니다.

이 관찰이 만들어 내는 것은 액세스 맵입니다. 각 에이전트별로 어떤 리소스에 접근했고 그것이 읽기(R)였는지 읽기/쓰기(RW)였는지를 담습니다. 이 맵은 페이로드, 시크릿, PII가 아니라 액세스 관계를 저장합니다. 흥미로운 부분은 diff입니다.

AgentResourcePermittedObservedDrift
data-export-jobprod-postgresRRnone
data-export-jobs3://billing-exportsRRWunreviewed write
report-builderanalytics-dbR(unused)dead privilege

중요한 행은 가운데 행입니다. 정책은 익스포트 버킷에 대해 읽기를 부여했는데, 수집기는 쓰기를 관찰했습니다. 이 한 줄이 바로 최소 권한 드리프트가 드러내고자 하는 핵심 위험입니다. 누구도 검토하지 않은 권한이 행사되었고, 그것이 공유 서비스 계정이 아니라 특정 에이전트에 귀속됩니다. 에이전트별 신원이야말로 그 귀속과 감사를 애초에 가능하게 만드는 요소이기 때문입니다.

단지 로깅하지 말고, 액세스 시점에 적용하기

탐지는 드리프트가 발생했다는 사실을 알려 줍니다. 루프를 닫으려면 검토되지 않은 쓰기를 로깅된 경로가 아니라 거부된 경로로 만들어야 합니다. 바로 여기서 액세스 시점에 평가되는 policy-as-code가 등장합니다. 드리프트를 표시했던 그 동일한 diff가 그것을 방지하는 규칙이 됩니다.

운영 데이터베이스에 대해 익스포트 작업을 읽기 전용으로 고정하고 쓰기를 전면 거부하되, 위반이 조용히 통과되지 않고 차단 및 알림되도록 하는 방식을 살펴보십시오.

agent "data-export-job" {
  # Read-only on the operational database. No writes, ever.
  access "prod-postgres" {
    mode  = "read"
    deny  = ["write", "delete", "ddl"]
  }

  # The export target the job is *supposed* to use.
  access "s3://billing-exports" {
    mode = "read"
  }

  on_violation {
    action = "block"        # deny the call at access time
    alert  = "security-oncall"
    audit  = "append"       # write to the tamper-evident ledger
  }
}

전후를 구체적으로 따라가 보겠습니다.

이전. 광범위한 역할을 보유한 익스포트 작업이 s3://billing-exports에 쓰기를 발행합니다. 이를 막는 것은 아무것도 없습니다. 작업은 성공하고, 정상 트래픽에 섞여 들며, 며칠 뒤에야 (그나마 발견된다면) 액세스 맵의 이상치로 나타납니다. 허용된 권한과 관찰된 권한 사이의 격차가 벌어졌지만, 남은 흔적이라곤 누구도 읽지 않은 로그 한 줄뿐입니다.

이후. 동일한 쓰기가 도착합니다. 정책이 액세스 시점에 평가되어, read로 범위가 한정된 리소스에 대한 write를 확인하고, 작업이 실제로 반영되기 전에 거부를 반환합니다. 위반은 호출을 차단하고, 온콜(on-call) 로테이션에 알림을 발생시키며, 추가 전용(append-only)이자 해시 체인으로 연결된 감사 원장(audit ledger)에 항목을 추가합니다. 검토되지 않은 쓰기는 결코 검토되지 않은 변경이 되지 않습니다. 드리프트는 그 순간에 다시 최소 권한 경로로 변환됩니다.

이 과정을 정직하게 유지하는 두 가지 속성이 있습니다. 첫째, 액세스 맵에 대한 모든 권한 있는 열람 자체가 감사됩니다. 누가 무엇을 보았는지 기록됩니다. 맵은 민감하며, 자신의 운영자를 설명하지 못하는 보안 도구는 신뢰할 수 없기 때문입니다. 둘째, 신뢰도는 명확하게 표시됩니다. 커널 수준의 증거로 에이전트에 귀속된 동작은 근사적으로 추론된 동작과 다르게 표시됩니다. 조작된 확실성을 근거로 행동하도록 요구받는 일은 결코 없습니다.

핵심 요점

최소 권한이 AI 에이전트에 대해 실패한 것이 아니라, 검토 주기가 실패한 것입니다. 권한은 거칠고, 동작은 동적이며, 분기별 인증은 실행할 때마다 바뀌는 액세스 표면을 추적할 수 없습니다. 해법은 임계 경로에 더 무거운 프록시를 두는 것이 아닙니다. 허용된 권한 대 관찰된 권한의 diff를 만들어 내는 지속적인 read-first 관찰, 그리고 교정된 경계를 액세스 시점에 적용하는 policy-as-code입니다. 그래야 과도한 권한을 가진 에이전트가 사고가 되기 한참 전에 검토 가능한 신호로 포착됩니다.

수집기, 액세스 맵, 액세스 시점 적용이 에이전트의 데이터 경로에 위치하지 않으면서 어떻게 맞물려 작동하는지 보고 싶다면 아키텍처 페이지에서 그 설계를 설명하며, 제품 페이지에서는 허용된 권한 대 관찰된 권한 뷰가 실제 환경에서 어떻게 보이는지 확인할 수 있습니다.

자주 묻는 질문

AI 에이전트의 최소 권한 드리프트란 무엇입니까?

에이전트가 수행하도록 허용된 작업과 실제로 수행하는 것으로 관찰된 작업 사이에서 벌어지는 격차를 말합니다. 거친 권한 부여와 동적 동작 때문에, 에이전트는 누구도 알아차리기 한참 전부터 아무도 승인하지 않은 리소스에 접근하기 시작할 수 있습니다. 드리프트는 그 격차가 소리 없이 누적되는 현상이며, 허용된 집합과 관찰된 집합을 지속적으로 비교해야만 검토가 가능합니다.

운영 환경을 망가뜨리지 않으면서 과도한 권한을 가진 에이전트를 어떻게 잡아냅니까?

가로채지 말고 관찰하십시오. read-first 수집기는 에이전트의 데이터 경로에 위치하는 대신 로그, OpenTelemetry, eBPF 커널 신호에서 읽어 들이므로, 수집기 장애가 에이전트를 절대 차단하지 않습니다. 이 관찰 결과는 허용된 권한 대 관찰된 권한의 diff로 이어집니다. 그다음 적용(enforcement)은 액세스 시점에 평가되는 policy-as-code에 위치하며, 검토되지 않은 쓰기는 거부된 경로와 알림으로 바뀝니다.

에이전트가 무엇에 접근할 수 있는지 확인하세요

Olivares AI는 당신의 AI 환경을 위한 개방형 자체 호스팅 플랫폼입니다. 자체 인프라에 배포하고 보안 및 플랫폼 팀이 필요로 하는 액세스 맵을 확보하세요.