이 글에서는 KeyShield 프로젝트에서
브라우저 기반 DLP(Data Loss Prevention)를 왜 Zero Trust 구조(PEP / PDP / PIP)로 설계했는지,
그리고 그 과정에서 어떤 보안 개념과 설계 판단이 필요했는지를 정리합니다.
이 프로젝트는 단순히 “붙여넣기를 막는 확장 프로그램”을 만드는 것이 아니라, 정책·컨텍스트·자동화까지 포함한 보안 시스템을 직접 설계하고 구현해보는 공부용 프로젝트이기 때문에, 개념적인 배경 설명을 함께 남겨두는 것이 중요하다고 판단했습니다.
브라우저에서 DLP를 시작하게 된 배경
전통적인 DLP(Data Loss Prevention)는 보통 서버나 네트워크 경계에서 동작합니다.
파일 업로드를 검사하거나, 네트워크 트래픽을 감시하고, 로그를 통해 유출을 사후 탐지하는 방식입니다.
하지만 실제 개발 환경을 돌아보면, 민감 정보(API Key, JWT, OAuth Token 등)가 유출되는 지점은 생각보다 훨씬 앞단에 있습니다.
- GitHub Issue나 PR 코멘트에 실수로 붙여넣기
- Notion, Confluence 문서에 키를 그대로 기록
- Slack, Discord 같은 메신저
- ChatGPT나 각종 AI 도구 입력창
- 웹 콘솔이나 폼 입력
이 공통점은 모두 브라우저 안에서 발생한다는 점입니다.
한 번이라도 서버 로그에 남거나 외부 서비스에 전송된 Secret은 사실상 회수가 불가능합니다.
그래서 KeyShield는 “사후 탐지”가 아니라,사용자가 입력하는 바로 그 순간에 차단하는 것을 목표로 삼았습니다.
즉, 브라우저를 보안의 출발점(Policy Enforcement Point) 으로 두게 된 이유입니다.
단순한 브라우저 확장으로 끝내지 않은 이유
처음에는 단순한 구조도 가능해 보였습니다.
- 브라우저 확장에서 정규식으로 Secret 탐지
- 탐지되면 붙여넣기 차단
- 사용자에게 경고 표시
하지만 이 방식은 금방 한계에 부딪혔는데, 가장 큰 문제는 정책이 코드에 고정된다는 점입니다.
어떤 키를 막을지, 어떤 도메인에서는 허용할지, 반복 행동을 어떻게 다룰지 같은 판단이 전부 확장 코드에 박히게 됩니다.
또 다른 문제는 상태와 맥락(Context)을 다루기 어렵다는 점입니다.
한 번 실수한 사용자와 짧은 시간 안에 여러 번 Secret을 붙여넣으려는 사용자를 같은 기준으로 처리하는 것은 바람직하지 않습니다.
이 지점에서 KeyShield는 방향을 명확히 정리했습니다.
“차단은 브라우저에서 하되,
판단은 중앙에서,
맥락은 별도로 관리하자.”
Zero Trust 개념을 KeyShield에 적용하기
Zero Trust의 핵심 문장은 잘 알려져 있습니다.
Never Trust, Always Verify
이를 KeyShield의 브라우저 DLP 맥락으로 풀어보면 다음과 같습니다.
- 브라우저 입력은 기본적으로 신뢰하지 않는다
- 모든 입력 이벤트는 정책 평가를 거친다
- 과거 행동과 현재 상황에 따라 판단 결과가 달라질 수 있다
- 신뢰는 고정되지 않으며, 언제든 회수되거나 완화된다
이 개념을 구조로 옮기면 PEP / PDP / PIP 분리라는 형태가 자연스럽게 도출됩니다.
전체 아키텍처 개요
KeyShield는 다음 세 컴포넌트로 구성됩니다.
- PEP (Policy Enforcement Point): 브라우저 확장
- PDP (Policy Decision Point): 정책 결정 서버
- PIP (Policy Information Point): 컨텍스트 처리 컴포넌트
이 셋은 역할이 명확히 다릅니다.
PEP: 브라우저는 ‘집행’만 담당한다
PEP는 Chrome Extension 형태로 구현되어 있습니다.
사용자의 입력 이벤트(paste, input, drag & drop 등)를 가장 먼저 만나는 지점입니다.
PEP의 책임은 의외로 단순합니다.
- 입력 이벤트를 감지한다
- Secret 후보를 탐지한다
- 정책 결정을 서버에 요청한다
- 서버의 응답에 따라 차단/경고/마스킹을 수행한다
중요한 점은,
PEP는 절대 정책을 “결정”하지 않는다는 원칙입니다.
또한 보안상 매우 중요한 제약이 있습니다.
- Secret 원문은 서버로 전송하지 않는다
- 로그나 스토리지에 저장하지 않는다
PEP는 말 그대로
정책을 집행하는 손과 발에 해당합니다.
PDP: 모든 판단의 단일 진실 소스
PDP는 Spring Boot 기반 서버로,
KeyShield에서 정책 판단의 중심이 됩니다.
여기서 이루어지는 일은 다음과 같습니다.
- 입력 이벤트에 대한 정책 평가
- 사용자/조직 단위 정책 관리
- 정책 우선순위 및 충돌 해결
- 모든 결정에 대한 감사 로그(Audit) 기록
이 구조를 선택한 이유는 분명합니다.
정책은 코드가 아니라 데이터로 관리되어야 하기 때문입니다.
정책이 서버에 모여 있어야
- 정책 변경이 즉시 반영되고
- 확장 업데이트 없이도 기준을 바꿀 수 있으며
- “왜 이 행동이 차단되었는지”를 설명할 수 있습니다.
실제 보안 시스템에서 매우 중요한 요소입니다.
PIP: ‘한 번의 실수’와 ‘반복 행동’을 구분하기 위해
마지막 구성 요소는 PIP입니다.
PIP는 Python 기반의 컨텍스트 핸들러로, 이벤트를 누적해서 사용자 리스크 상태를 계산합니다.
여기서 다루는 개념은 다음과 같습니다.
- 이벤트 기반 리스크 점수 누적
- 시간에 따른 감쇠(decay)
- 상태 전이 (Normal → Elevated → Restricted)
- 특정 상태 진입 시 정책 자동 강화
- 일정 시간 후 자동 완화(rollback)
이 로직을 PDP 안에 넣지 않은 이유는, 컨텍스트 처리는 성격이 다르기 때문입니다.
즉각적인 응답이 필요한 정책 판단과 달리, 컨텍스트는 시간과 누적을 다루는 문제입니다.
이 분리를 통해 나중에 CTI, AI 기반 분석으로 확장할 수 있는 여지도 확보했습니다.
정책 결정과 집행을 분리했을 때 얻은 것
- 정책 변경이 확장 업데이트로 이어지지 않는다
- 반복 행동에 따라 자동으로 정책이 강화된다
- 모든 차단/허용 결정이 감사 가능하다
- 서버 장애 시에도 확장은 최소 기능으로 동작할 수 있다
마무리하며
브라우저 DLP를 Zero Trust 구조로 설계한 이유는 단순합니다. 브라우저라는 제한된 환경 안에서도 정책, 컨텍스트, 자동화라는 보안의 핵심 개념을 끝까지 밀어붙여 보고 싶었기 때문입니다. 이 프로젝트는 공부용이지만, 동시에 실제 서비스로 확장 가능한 구조를 목표로 하고 있습니다.