이 글은 KeyShield 프로젝트의 첫 번째 개발 기록입니다.
프로젝트 전체 설계와 목표에 대한 설명은 이미 메인 글에서 다루었고,
이번 글부터는 실제 개발 과정에서 무엇을 고민했고, 무엇을 구현했는지를 시간 순서대로 정리합니다.
이번 개발일지의 범위는 Day 1부터 Day 3까지,
즉 Chrome Extension 기반 PEP(Policy Enforcement Point)의 최소 기능을 완성한 시점까지입니다.
개발을 시작하기 전에 정한 전제
KeyShield는 단순히 “동작하는 코드”를 만드는 프로젝트가 아니라,
Zero Trust 구조를 실제 서비스 형태로 구현하는 것이 목적입니다.
그래서 개발 초반부터 다음 원칙을 분명히 했습니다.
- Secret 유출은 사후 탐지보다 사전 차단이 훨씬 중요하다
- 정책 판단과 정책 집행은 반드시 분리되어야 한다
- Secret 원문은 서버, 로그, DB 어디에도 남기지 않는다
- 개인 프로젝트라도 “실제 운영 가능한 구조”를 목표로 한다
이 전제들이 Day 1~3의 모든 선택에 영향을 주었습니다.
Day 1 — 프로젝트 구조와 방향을 먼저 고정한 이유
Day 1에는 코드보다 구조와 규칙을 먼저 확정하는 데 시간을 썼습니다.
이 단계가 중요한 이유는, 이후 기능이 늘어나도 프로젝트의 방향이 흔들리지 않게 하기 위함입니다.
Monorepo 구조를 선택한 이유
KeyShield는 다음 세 구성 요소로 명확히 나뉩니다.
- 브라우저에서 직접 입력을 차단하는 Chrome Extension (PEP)
- 정책을 판단하고 감사 로그를 남기는 Spring Boot 서버 (PDP)
- 사용자 행동을 누적 분석해 정책을 자동 강화하는 Python Context Handler (PIP)
이 세 요소는 역할이 완전히 다르기 때문에,
처음부터 하나의 Monorepo 안에서 논리적으로 분리된 구조로 가져가는 것이 맞다고 판단했습니다.
keyshield/
├─ apps/
│ ├─ extension/
│ ├─ pdp/
│ └─ pip/
├─ infra/
└─ docs/
개발 규칙을 Day 1에 정한 이유
개인 프로젝트지만 다음 규칙을 명확히 했습니다.
- 모든 기능은 feature/* 브랜치에서 개발
- PR 기반으로 병합
- Squash merge 사용
- Conventional Commits 형식 유지
규칙을 통해 나중에 이 프로젝트를 설명할 때 변경 이유와 흐름을 명확히 보여주는게 좋을 듯 해 미리 설정하고 갔습니다.
(학습용 프로젝트이기 때문에)

확실히 해두는게 깔끔? 하고 예쁜 거 같습니다
보안 프로젝트로서 가장 먼저 고정한 원칙
KeyShield는 Secret 유출을 막는 프로젝트입니다.
그래서 레포지토리 자체에서부터 다음 원칙을 강하게 적용했습니다.
- .env, 키 파일, 인증 정보는 커밋 불가
- .env.example 기반 운영
- README와 문서에 “원문 Secret 서버 전송 금지” 명시
이 원칙은 이후 모든 구현의 기준점으로 두려고 합니다.
Day 2 — 왜 Chrome Extension부터 시작했는가
Day 2부터는 본격적으로 PEP 구현에 들어갔습니다.
서버보다 브라우저를 먼저 선택한 이유
Secret 유출 사고를 분석해보면, 대부분은 다음과 같은 흐름에서 발생합니다.
- GitHub Issue, PR 코멘트
- Notion, Slack, Jira
- ChatGPT 같은 AI 입력창
- 웹 콘솔의 입력 폼
공통점은 모두 브라우저 안에서 발생한다는 점입니다.
서버에서 로그를 분석하는 방식은 이미 “유출 이후”입니다.
KeyShield는 그 이전 단계, 즉 붙여넣기 순간에 막는 것을 목표로 했습니다.
그래서 PEP는 Chrome Extension으로 시작하는 것이 가장 합리적이었습니다.
Chrome MV3 기본 스켈레톤 구성
Day 2의 목표는 단순했습니다.
“모든 웹 페이지에서 내가 paste 이벤트를 감지할 수 있는가”
이를 위해 MV3 기반 확장 스켈레톤을 구성했고,
content script가 정상적으로 동작하는지부터 확인했습니다.
이 단계에서는 정책이나 서버 없이 브라우저 입력 이벤트에 개입할 수 있는지만 검증했습니다.
(개발모드로 확장자 도입하여 확인할 수 있다!)
paste 이벤트 감지의 의미
paste 이벤트를 감지할 수 있다는 것은 단순한 기술 구현 이상의 의미가 있습니다.
- 사용자가 의식하지 못한 실수를 포착할 수 있고
- 입력이 실제로 반영되기 전에 개입할 수 있으며
- Zero Trust 관점에서 가장 앞단의 Enforcement Point가 됩니다
Day 2에서 paste 이벤트가 안정적으로 감지되는 것을 확인하면서,
이 프로젝트의 기술적 가능성은 충분하다고 판단할 수 있었습니다.

Day 3 — Secret 탐지와 “실제 차단”까지
Day 3은 KeyShield에서 가장 중요한 전환점인데 단순 감지가 아니라, 실제로 붙여넣기를 막는 기능이 추가됐기 때문입니다.
정규식 기반 Secret 탐지부터 시작한 이유
초기에는 가장 명확한 패턴부터 탐지 대상으로 삼았습니다.
- AWS Access Key ID
- JWT 토큰
- GitHub Personal Access Token
이 단계의 목표는 완벽한 탐지가 아니라,
“확실한 것부터 놓치지 않는 것”이었습니다.
정규식의 한계와 entropy 개념 도입
정규식만 사용하면 오탐이 빠르게 늘어납니다.
비슷한 형태의 테스트 문자열, 임의의 Base64 값 등이 계속 걸리기 때문입니다.
그래서 문자열의 무작위성(entropy)를 함께 계산했습니다.
- 길이는 길지만 규칙성이 높은 문자열은 제외
- 실제 Secret에 가까운 문자열만 통과
이 과정에서 “보안 정확도”와 “사용자 경험” 사이의 trade-off를 실제로 체감하게 됩니다.
(물론 정확도가 그리 높지 않기 때문에, 나중에 알고리즘을 추가하려 합니다. 우선 뼈대만..)

실제 붙여넣기 차단
Secret으로 판단된 경우, paste 이벤트의 기본 동작을 차단했습니다.
이 단계에서 중요한 점은 다음이었습니다.
- 텍스트는 실제 입력되지 않아야 하고
- 사용자는 왜 차단됐는지 즉시 이해해야 하며
- 불필요한 UX는 피해야 함
Day 3 종료 시점의 상태
KeyShield 상태
- Chrome Extension이 모든 웹 페이지에서 동작
- paste 이벤트 감지 가능
- 대표적인 Secret 패턴 탐지
- entropy 기반 오탐 보완
- 실제 붙여넣기 차단
아직 서버(PDP)나 컨텍스트(PIP)는 연결되지 않았지만, PEP 단독으로도 “실수 방지” 는 막을 수 있다!
'Project > keyshield' 카테고리의 다른 글
| [Project : KeyShield] Chrome Extension 기반 Zero Trust 보안 시스템 (0) | 2025.12.06 |
|---|