본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 22. 03:12

Policy as Code를 위한 Claude Code 보안 강화: Cerbos 기술이 내 설정을 어떻게 변화시켰나

요약

Claude Code를 에이전트로 활용할 때 발생할 수 있는 보안 위험을 관리하기 위해 Cerbos를 활용한 Policy as Code 설정 방법을 다룹니다. AI 에이전트가 권한 정책을 임의로 수정하거나 위험한 쉘 명령을 실행하지 않도록 세밀한 인가 정책을 통합하는 청사진을 제공합니다.

핵심 포인트

  • Claude Code의 에이전트 특성에 따른 보안 위험성 분석
  • Cerbos를 활용한 validate-in-a-loop 방식의 보안 강화
  • Policy as Code를 통한 AI 코딩 에이전트의 권한 제어
  • 세밀한 인가 정책(Fine-grained Authorization)의 중요성

저는 Claude Code를 아주 많이 사용합니다. 처음에는 조심스럽게 시작했습니다. 하지만 이제는 더 이상 조심스럽지 않습니다. 바로 그 점에 대해 이야기하고 싶습니다. Claude Code는 리팩터링 (refactors), 테스트 (tests), 빠른 스파이크 (quick spikes) 등 코드를 작업하는 저의 기본 방식이 되었습니다. 하지만 이에 더 많이 의존할수록, Claude Code의 보안과 이것이 저의 Policy as Code (정책 코드화) 설정에 어떻게 부합하는지에 대해 생각하기 시작했습니다. 이것은 "단순한 챗봇"이 아닙니다. 제 저장소 (repo)를 읽고, 파일을 수정하며, 쉘 명령 (shell commands)을 실행할 수 있는 에이전트 (agent)입니다. 잘못된 설정에서는 제가 주니어 엔지니어에게 감독 없이 허용할 수 있는 것보다 훨씬 더 많은 일을 할 수 있습니다. 이로 인해 저는 Claude Code의 권한 사용 방식과 세밀한 제어 (granular controls)를 강화하게 되었습니다. 이 여정에서 가장 흥미로웠던 부분은, 정책 번들 (policy bundle)이 깨끗해질 때까지 실제 cerbos compile 명령을 루프 내에서 실행하는 Cerbos 인가 정책 (authorization policy) 기술을 통합한 것이었습니다. 이 포스트는 다음 패턴에 관한 것입니다:

  • Claude Code 자체의 권한 모델과 권한이 실제로 어떻게 작동하는지
  • 왜 Policy as Code와 인가 정책 (authorization policies)이 AI 코딩 에이전트에게 맡기기에 특히 위험한 요소인지
  • Cerbos를 활용한 validate-in-a-loop 방식이 어떻게 더 안전한 작업 방식을 제공하는지
  • 이러한 도메인 특화 기술에 대한 반복 예산 (iteration budgets)과 실패 모드 (failure modes)를 어떻게 생각하는지

만약 여러분이 Claude Code 보안, 세밀한 권한 (granular permissions), 인가 정책 (authorization policies), 또는 Policy as Code에 관심이 있다면, 이 글이 복사하거나 개선할 수 있는 청사진을 제공할 것입니다.

Claude Code 보안에 대해 걱정했던 점

Claude Code는 기본적으로 괜찮은 보안 모델을 제공합니다. 쉘 명령을 실행하거나, 대규모 수정을 적용하거나, 기타 민감한 작업을 수행하기 전에 명시적인 승인을 요청합니다. 매우 보수적인 방식(항상 질문)부터 격리된 환경을 위한 더 자동화된 설정까지 다양한 권한 모드로 실행할 수 있습니다. 또한 프로젝트 경계 (project boundaries), 권한 규칙 (permission rules), 샌드박싱 (sandboxing)을 통해 유효 범위를 제한함으로써 사용자의 머신에서 광범위한 자유를 갖지 않도록 할 수 있습니다. 이는 이미 단순히 "채팅창에 코드를 붙여넣는" 경험보다는 훨씬 낫습니다.

하지만 실제로 사용하면서 한 가지 패턴을 발견했습니다. 제가 익숙해질수록, 시간을 아끼기 위해 매우 안전한 설정에서 점차 더 자동화된 설정으로 미끄러지듯 옮겨가게 되었습니다. 일부 워크플로우에서는 괜찮을 수 있지만, 보안(Security), 액세스 제어(Access Control), 인프라(Infrastructure)와 관련된 작업에서는 저를 두렵게 만들었습니다. 저는 다음과 같은 상황에 처하고 싶지 않았습니다:

  • Claude Code가 컴파일은 되지만 나의 액세스 모델(Access Model)을 약화시키는 방식으로 권한 정책(Authorization Policies)을 조용히 수정하는 상황.
  • 잘못 설정된 셸 권한(Shell Permission)으로 인해 내가 의도하지 않은 명령어를 실행하는 상황.
  • "빠른 테스트에서 코드가 충돌하지 않았다"는 것 외에는 강력한 검증 루프(Validation Loop)가 없는 상황.

이것이 바로 Claude Code 중심의 워크플로우에서 세밀한 권한 정책(Fine-grained Authorization Policies)에 대한 더 나은 방안을 찾게 된 계기였습니다.

왜 Policy as Code와 권한 정책을 잘못 설정하는 것이 위험한가

제가 신경 쓰는 대부분의 시스템은 복잡한 권한 로직(Authorization Logic)을 가지고 있습니다:

  • 다양한 역할 (관리자(Admin), 운영자(Operator), 지원(Support), 최종 사용자(End User))
  • 테넌트 격리(Tenant Isolation)
  • 금융, 보안, 감사(Audit) 등을 위한 특수 사례

저는 이를 위해 Policy as Code 접근 방식을 선호합니다. 특히 Cerbos를 사용하면 git에 저장되고 실제 컴파일러(Compiler)에 의해 검증되는 YAML 정책을 작성할 수 있습니다.

장점:

  • 정책을 검토(Reviewable)할 수 있습니다.
  • CI를 통해 변경 사항을 제어(Gate)할 수 있습니다.
  • 엣지 케이스(Edge Cases)에 대한 테스트를 작성할 수 있습니다.

단점:

  • 구문(Syntax)이 상세하여 실수하기 쉽습니다.
  • 단 한 번의 들여쓰기(Indentation) 실수로 의미론(Semantics)이 변할 수 있습니다.
  • 잘못된 기본 규칙(Default Rule) 하나가 실수로 테넌트 간의 액세스를 허용할 수 있습니다.

이 작업을 위해 AI 코딩 에이전트(AI Coding Agent)를 사용하는 것을 고민하기 시작했을 때, 권한 정책은 일반적인 코드보다 더 엄격한 가드레일(Guardrails)이 필요하다는 것이 명백해졌습니다. Claude Code가 약간 잘못된 React 컴포넌트를 생성하면 버그가 발생할 뿐이지만, 약간 잘못된 Cerbos 정책을 생성하면 데이터 노출(Data Exposure)이 발생합니다.

따라서 질문은 다음과 같았습니다: Claude Code의 보안과 세밀한 권한(Granular Permissions)을 최우선으로 유지하면서도, 권한 정책을 작성하는 데 Claude Code의 도움을 여전히 받을 수 있을까?

빠진 조각: 루프 내에서 검증하는 Cerbos 정책 스킬

이 문제를 해결해 준 것은 Cerbos 정책을 중심으로 구축된 작은 Claude Code 스킬이었습니다. 대략적으로 설명하자면, 이 스킬은 다음과 같이 작동합니다: 일반적인 영어 입력 → Cerbos 정책 번들 (policy bundle) 출력 → Docker에서 cerbos compile 실행 → 오류 수정 → 번들이 깨끗해질 때까지 반복. 사용자 관점에서는 다음과 같습니다: 제가 원하는 내용을 설명합니다. 예: "HR만 급여 필드를 볼 수 있습니다. 매니저는 자신의 직속 부하 직원에 대한 성과 검토 내용을 볼 수 있습니다." 그러면 스킬이 YAML 형식의 Cerbos 정책 번들을 생성하거나 편집합니다. 그 후 Docker 내부에서 해당 번들을 대상으로 cerbos compile을 실행합니다. 오류가 발생하면 실제 컴파일러 출력을 읽고, 무언가를 수정한 뒤 다시 시도합니다. 번들이 깨끗하게 컴파일될 때만 최종 결과를 확인할 수 있습니다. 설치 방법은 간단합니다: npx skills add cerbos/skills --skill cerbos-policy. 설치 후에는 정책이 위치한 프로젝트 내의 Claude Code에서 Cerbos 정책 스킬을 호출할 수 있습니다. 제가 이 방식에서 좋았던 점은 신뢰할 수 있는 단일 원천 (source of truth)이 모델이 아니라, 운영 환경을 모방한 환경에서 실행되는 실제 Cerbos 컴파일러라는 점입니다. 스킬은 단지 그 주변을 감싸는 스마트한 루프일 뿐입니다.

'루프 내 검증 (validate-in-a-loop)' 패턴 내부

'루프 내 검증 (validate-in-a-loop)' 패턴은 Cerbos 스킬을 단순히 인상적인 수준을 넘어 실용적으로 느껴지게 만드는 핵심 요소입니다. 전체 워크플로우는 이 Cerbos 포스트에서 다루고 있지만, 중요한 아이디어는 간단합니다: 모델은 신뢰할 수 있는 원천이 아닙니다. 컴파일러가 신뢰할 수 있는 원천입니다. 스킬은 무언가를 생성하기 전에 일반적인 언어로 명확히 하기 위한 질문을 던집니다. "매니저는 보고서를 볼 수 있다"와 같은 모호한 요구사항은 어떤 매니저인지, 어떤 보고서인지, 소유권, 기밀성, 그리고 예외 케이스(edge cases)에 대한 더 정밀한 논의로 전환됩니다. 프롬프트의 모호함이 정책의 모호함으로 이어질 수 있기 때문에 이는 매우 중요합니다. 사양(spec)이 명확해지면, 스킬은 정책 번들을 작성하고 Docker에서 cerbos compile을 통해 이를 검증합니다. 만약 무언가 실패하면, 구문(syntax), 스키마(schemas), 컴파일 오류, 그리고 테스트 순으로 한 번에 하나씩 문제를 해결해 나갑니다.

또한 반복적인 실패가 발생하면 중단하며, 중요한 점은 검증(validation)을 통과시키기 위해 테스트를 삭제하지 않는다는 것입니다. 이것이 진정한 가치입니다. 즉, 실제 검증을 중심으로 한 규율 있는 루프(disciplined loop)입니다. 제가 '검증 루프 내 기술(Validation-in-a-loop)'을 중심으로 Claude Code를 제어하는 방법은 하나의 계층입니다. Claude Code의 권한 강화(permission hardening)가 또 다른 계층입니다. 어느 쪽도 단독으로는 충분하지 않습니다. 컴파일러는 정책이 구문적으로 유효한지는 알려줄 수 있습니다. 하지만 Claude Code가 애초에 정책 파일에 접근해서는 안 되었다는 사실은 알려줄 수 없습니다. 그래서 저는 두 가지를 모두 실행합니다. 구체적으로, 제 설정은 다음과 같습니다:

제한된 파일 시스템 범위 (Narrowed filesystem scope)
이 설정에서 저는 Claude Code에 제 머신에 대한 광범위한 접근 권한을 주는 대신, Cerbos 정책과 관련 서비스가 포함된 저장소(repo)에만 집중하도록 유지합니다.

화이트리스트 기반 명령 (Whitelisted commands)
이 기술이 실제로 필요로 하는 유일한 셸(shell) 명령은 Docker로 래핑된 cerbos compile (그리고 선택적으로 cerbos test)뿐입니다. 저는 왜 필요한지 정확히 이해하지 못하는 임의의 bash 명령은 승인하지 않습니다.

정책 작업을 위한 보수적인 권한 모드 (Conservative permission mode for policy work)
단순한 리팩터링(refactor)의 경우 Claude Code가 더 빠르고 자동화된 모드로 실행되도록 허용할 수도 있습니다. 하지만 권한 정책(authorization policies)을 건드리는 모든 작업에 대해서는, 수정 사항과 명령이 승인을 위해 명확하게 노출되는 더 안전한 모드를 의도적으로 사용합니다.

의미론적 검토를 위한 인간의 검토 (Human review for semantics)
Cerbos 컴파일러는 번들(bundle)이 유효한지, 테스트를 통과하는지는 알려줄 수 있습니다. 하지만 비즈니스 규칙(business rule) 자체가 타당한지는 알려줄 수 없습니다. 저는 여전히 정책 변경 사항이 프로덕션(production) 근처에 가기 전에 일반적인 코드 리뷰(code review)와 CI를 거치도록 합니다. 이런 방식으로 Claude Code의 보안과 세밀한 권한(granular permissions)이 방어의 한 계층을 형성하고, Cerbos 컴파일러와 테스트가 또 다른 계층을 형성합니다.

반복 예산: 루프는 어디까지 진행되어야 하는가? (Iteration budgets: how far should the loop go?)
제가 여전히 탐구하고 있는 하나의 열린 질문은 '검증 루프 내 기술(validate-in-a-loop skills)'에 대해 반복 예산(iteration budgets)을 얼마나 공격적으로 설정해야 하는가입니다. 현재 제가 적절하다고 느끼는 기본값은 다음과 같습니다:

  • 동일한 유형의 오류를 수정하기 위해 최대 3회 시도 후 중단.
  • 지시당 컴파일 사이클(compile cycles)에 대한 적절한 전역 제한 (몇 번의 구문 + 스키마 + 테스트 통과에는 충분하지만, 수십 번에 달하지는 않는 수준).

Cerbos 컴파일과 테스트가 통과되면 해당 루프 내에서 추가적인 추측성 "개선 (improvements)" 없이 즉시 조기 종료 (Early exit)합니다. 실제로 대부분의 수정 사항은 1~3회 반복 내에 수렴합니다. 루프가 한계에 도달한다면, 이는 프롬프트가 모호했거나 기존 정책에 인간이 해결해야 할 더 깊은 구조적 문제가 있음을 의미하는 경우가 거의 대부분입니다. 저는 Claude Code 및 다른 에이전트 도구 (agentic tools)를 사용하는 다른 사람들이 이 문제를 어떻게 다루고 있는지 매우 궁금합니다. 만약 루프 내에서 정적 분석기 (static analyzer), 테스트 스위트 (test suite), 또는 커스텀 검증기 (custom validator)를 사용하고 있다면, 에이전트에게 몇 번의 시도를 허용하시나요? 보안 민감 영역 (인증 (auth), 인프라 (infra), 데이터 마이그레이션 (data migrations))을 순수하게 기능적인 코드와 다르게 취급하시나요? 모든 복잡성을 숨기는 대신 신뢰를 구축할 수 있는 방식으로 이러한 루프를 인간에게 보여주는 좋은 패턴을 찾으셨나요?

이 패턴을 직접 시도해 보기
Claude Code 보안을 실험 중이며 권한 부여 정책 (authorization policies)을 처리하는 더 견고한 방법을 원하신다면, 저에게 효과적이었던 패턴은 다음과 같습니다:

  1. 좁고 도메인 특화된 기술 (domain-specific skill) 정의하기
    저의 경우: 제 정책 레이아웃을 이해하고 Docker에서 cerbos compile을 실행하는 방법을 아는 Cerbos 정책 기술 (Cerbos policy skill)을 정의했습니다.

  2. 실제 도구를 심판으로 만들기
    모델이 무엇이 "충분히 좋은지" 결정하게 두지 마세요. 도메인 컴파일러 (domain compiler)나 검증기 (validator) (Cerbos, 린터 (linter), 테스트 러너 (test runner), 스키마 검사기 (schema checker))가 성공의 중재자가 되도록 하세요.

  3. 루프 내 검증 컨트롤러 (validate-in-a-loop controller)로 감싸기
    작은 반복 예산 (iteration budget)을 설정하여 반복당 한 번의 변경만 수행하고, 컴파일러 출력값과 차이점 (diffs)을 사용자에게 다시 전달합니다.

  4. Claude Code 자체 보안 모델 위에 계층화하기
    보안이나 인프라와 관련된 부분을 다룰 때는 파일 시스템 범위 (filesystem scope)를 제한하고, 명령어를 화이트리스트 (whitelist)에 등록하며, 보수적인 권한 모드를 선택하세요.

제가 사용 중인 정확한 Cerbos 설정을 시도해 보고 싶다면, Claude Code 측 설치 명령어는 다음과 같습니다:
npx skills add cerbos/skills --skill cerbos-policy

그런 다음 Cerbos 정책이 있는 리포지토리 (repo)를 지정하고, 작고 추론하기 쉬운 것부터 시작해 보세요.

검증 루프 (validation loop)를 관찰하고, 거기서 발생하는 컴파일러 오류 (compiler errors)를 읽으며, 안전하다고 느껴지는 수준에 따라 반복 예산 (iteration budget)을 조정하세요. 커뮤니티에 던지는 열린 질문이 하나 있습니다. 제가 이 내용을 공유하는 이유는 많은 사람이 비슷한 아이디어로 모이고 있다고 생각하기 때문입니다. 즉, 생성 및 편집에는 Claude Code (또는 다른 에이전트)를 사용하되, 도메인 특화 도구 (domain-specific tools)가 정확성을 강제하게 하고, 해당 도구들이 만족할 때까지 에이전트가 반복하도록 만드는 것입니다. 만약 여러분도 이와 유사한 방식—특히 보안 (security), 권한 부여 (authorization), 세분화된 권한 (granular permissions), 또는 코드로서의 인프라 (infrastructure as code, IaC)—를 운영하고 있다면, 다음 내용이 궁금합니다:

  • 여러분의 검증 루프 (validate-in-a-loop)는 어떤 모습인가요?
  • 반복 예산 (iteration budgets)을 얼마나 엄격하게 설정하시나요?
  • 루프의 부재로 인해 낭패를 보았던 공포스러운 사례가 있나요?

우리는 강력한 코딩 에이전트 (coding agents)를 기본적으로 안전하게 만드는 방법을 찾아가는 초기 단계에 있습니다. 저에게 있어, Claude Code의 보안 설정과 Cerbos 기반의 검증 루프 (validation loops)를 결합한 것은 올바른 방향을 향한 큰 진전이었습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0