1인 회사에 보안팀이랑 감사팀을 만들었음 (AI 에이전트로)
집 서버 하나 굴리는데 보안팀에 감사팀까지 만드는건 좀 오버 같긴 한데... 이유가 있다.
이번주에 나온 것들이 이렇다.
- logrotate가 이관 후에 옛날 경로 보고 있어서 로그가 몇 달째 회전 안되고 있었음. 오류도 안냈다
- fail2ban
dbpurgeage가 1일이라 밴 이력이 매일 지워지고 있었다. 재범 카운트가 영원히 1회차 - 회사 소개 문서랑 블로그엔 SSH가 2222라고 적혀있는데 서버는 22에서 듣고 있다
전부 "설정 파일은 멀쩡한데 실제는 다른" 종류다. 내가 만들고 내가 확인하니까 계속 놓쳤다. 자기가 짠 코드 자기가 리뷰하는거랑 똑같음
조직도
Moon (사장)
├── Dal Founding Engineer
├── Suho 보안팀장
│ └── Nun 탐지분석가
└── Jeoul 감사팀장 ← 사장 직속
└── Jatdae 구성감사원
이름은 수호, 눈, 저울, 잣대. 기존에 문(Moon)이랑 달(Dal)이 있어서 맞췄음
역할은 이렇게 나눴다.
| | 하는 일 | 안하는 일 | |---|---|---| | Suho 보안팀장 | 차단 정책 설계, 공격면 관리, 대응 지휘 | 사장 승인 없는 포트 개방 | | Nun 탐지분석가 | 로그 분석, 주간 브리핑, 임계값 조정 제안 | 차단 직접 실행 | | Jeoul 감사팀장 | 통제가 실제로 도는지 독립 검증 | 서버 변경 (읽기 전용) | | Jatdae 구성감사원 | 문서랑 실제 대조 | 서버 변경 (읽기 전용) |
감사팀을 보안팀 밑에 안 둔 이유
이게 이 글의 핵심이다.
감사 대상이 감사자의 상급자면 감사가 성립을 안한다. 보안팀이 만든 통제가 실제로 도는지 확인하는게 감사팀 일인데, 보안팀장한테 보고하면 그건 그냥 자체 점검이지 감사가 아님
그래서 감사팀장은 사장 직속이고, 감사 결과는 보안팀 안 거치고 나한테 바로 온다. 보안팀이 먼저 보고 조용히 고칠 기회를 주면 그것도 감사가 아니라 사전 통보고.
사람 수보다 직무분리
4명으로 잡았다. 대응 담당을 따로 두고 싶었는데 보안팀장이 겸하게 했음
1인 회사에서 에이전트 수 늘리는건 별 의미가 없다. 중요한건 "만드는 사람"과 "확인하는 사람"이 갈라져 있는거지 몇 명이냐가 아니다.
canCreateAgents는 전부 false로 박아뒀다. 에이전트가 에이전트를 늘리기 시작하면 곤란하다. 조직 확대는 사람이 결정할 일
지침에 뭘 적었나
capabilities는 한줄 소개고, 실제 업무 규칙은 AGENTS.md로 따로 넣는다. 여기 뭘 적느냐가 전부인것 같다.
넣은 것들
- 이 서버의 실제 상태. 열린 포트, fail2ban 설정값, 내부 대역. 추측으로 일하지 말라고
- 하지 말 것. 사장 승인 없는 공격면 확대, 자가 차단, 그리고 귀속 추정
- 모르는건 모른다고 하기
- 감사팀은 읽기 전용
세 번째가 생각보다 중요했다. 예를 들어 공유기가 외부 몇 번 포트를 22로 넘기는지는 서버에서 알 수가 없다. NAT는 공유기에서 일어나고 서버 로그엔 항상 22로 찍히니까. 이런건 "미확인"으로 남기고 나한테 물어보라고 적어뒀다. 추정을 사실처럼 적는게 감사에선 제일 큰 잘못이다.
귀속 추정 금지도 적었다. 로그에 중국 IP 몇 개 찍혔다고 "중국 해커"라고 쓰면 안된다. 관측된 IP는 대부분 감염된 피해 기기지 공격 주체가 아니다.
만드는 법
Paperclip CLI로 했다. UI로도 되는데 CLI가 재현이 된다.
CLI는 별도 인증이 필요하다.
docker exec paperclip pnpm paperclipai auth login --no-browser --instance-admin
# 승인 URL 나오면 브라우저에서 승인
board_api_keys 테이블에 직접 INSERT하면 클릭 없이도 되는데 안했다. 인증 DB 우회해서 키 발급하는건 딱 감사팀이 잡아야 할 행위다. 내가 그걸 하면 좀...
에이전트 생성은 이런 식
docker exec paperclip pnpm paperclipai agent create -C $CO --json --payload-json '{
"name": "Suho",
"role": "security",
"title": "보안팀장 / Security Lead",
"icon": "shield",
"reportsTo": "'$CEO'",
"adapterType": "claude_local",
"adapterConfig": {"model": "claude-sonnet-5", "instructionsBundleMode": "managed",
"instructionsEntryFile": "AGENTS.md", "dangerouslySkipPermissions": true},
"permissions": {"canCreateAgents": false, "canCreateSkills": false}
}'
reportsTo만 바꾸면 조직도가 된다. 감사팀장만 CEO를 가리키게 하면 끝.
지침 넣는건
docker cp Suho.md paperclip:/tmp/Suho.md
docker exec paperclip pnpm paperclipai agent instructions-file:put <agentId> \
--path AGENTS.md --content-file /tmp/Suho.md
걸린 것들
role이 enum인데 감사용이 없다. ceo cto cmo cfo security engineer designer pm qa devops researcher general 이게 전부라서 감사팀은 qa로 넣었음
org chart 명령이 있을줄 알았는데 없다. 조직도는 그냥 DB에서 agents.reports_to 보면 된다.
openapi 출력이 JSON 파싱 안되길래 뭔가 했더니 앞에 pnpm 배너가 붙어있었다. sed -n '/^{/,$p'로 잘라내면 된다.
paperclipai doctor가 config 없다고 실패하는건 무시해도 된다. CLI 로컬 모드용 점검이라 도커 배포랑 상관없음
첫 과제
4명 다 아직 idle이다. 기동해서 첫 보고서를 받아봐야 하는데 그건 다음에.
감사팀 첫 과제는 이미 정해져 있다. 회사 소개 문서랑 서버 실제 상태 불일치 찾기. SSH 포트 얘기부터 메일 발신 경로까지 이미 몇 개 나와있다. 문서를 고칠지 서버를 고칠지는 봐야 알겠고
마치며
만든 사람이 검증하면 안 잡히는게 있다. 그거 하나 때문에 팀을 둘로 나눴다.