Skip to content

CH 28 · 보안과 컴플라이언스

전체 글자 수약 3,490자예상 소요 시간약 20분선행 학습CH 04난이도이해 위주

이 장의 목표

명령을 실행하고 파일을 쓸 수 있는 Agent를 내 컴퓨터에서 돌리면 이런 걱정이 떠오릅니다. 함부로 내 파일을 지우진 않을까? 몰래 내 키를 외부로 보내진 않을까? 내 시스템 설정을 바꾸진 않을까?

이런 걱정은 타당합니다. 보안 경계가 없는 Agent는 시한폭탄과 같습니다. dsh의 답은 세 겹의 보호입니다. 파일 샌드박스, 작업 승인, 키는 쓰기 전용. 앞서 CH 04에서 권한 모델을 다룰 때 일부 언급했는데, 이 장에서는 각 층의 원리를 명확히 합니다. Agent를 어떻게 제약하는지, 어떤 경계가 우회 불가능한 하드 경계인지, 무엇이 직접 판단해야 할 영역인지. 이것만 이해해도 무엇을 안심하고 맡길 수 있고 무엇을 스스로 챙겨야 하는지 알 수 있습니다.

먼저 정리하기: dsh의 보안 사고방식

dsh 보안 설계의 핵심은 여덟 글자입니다. 기본은 제한, 필요 시에만 허용.

"일단 권한을 다 주고 신중하게 쓰길 기대한다"가 아니라 정반대입니다. 기본적으로는 명시적으로 허용한 범위만 건드릴 수 있고, 경계를 넘으려면 반드시 동의를 받아야 합니다. "관리자 비밀번호 쥐어주고 알아서 하라"는 발상과는 완전히 다릅니다.

세 겹의 보호, 바깥에서 안으로:

무엇을 관리하나어떻게 관리하나
1층: 파일 샌드박스어떤 파일을 건드릴 수 있는가3단계 권한, OS 커널 수준 격리
2층: 작업 승인민감한 작업을 실행할 수 있는가팝업으로 묻고, 거부하면 실행 안 함
3층: 키는 쓰기 전용API Key를 어떻게 보관하나쓰기 전용, UI에 표시 안 함, 로컬 저장, 업로드 안 함

아래에서 한 층씩 살펴봅니다.

1층: 파일 샌드박스

CH 04에서 3단계 권한을 다뤘는데, 여기서는 그 뒤에 있는 원리를 다룹니다.

샌드박스는 "경로가 작업 영역 밖이면 에러" 같은 if 분기를 도는 JavaScript 코드가 아닙니다. 그런 방식은 모델이 우회할 수 있습니다(상대 경로로 점프한다거나, 심볼릭 링크를 쓴다거나). dsh의 샌드박스는 OS 커널 수준입니다. Windows에서는 잡 오브젝트로 프로세스가 접근할 수 있는 자원을 제한하고, Linux/macOS에서는 namespace와 seccomp로 시스템 콜을 필터링합니다. 모델이 어떤 수를 써도 커널을 통과 못 하면 통과 못 합니다.

3단계 권한, 엄격한 것에서 느슨한 순:

모드무엇을 쓸 수 있나어떤 시나리오에 적합한가
read-only아무것도 못 씀읽기 전용 분석, 코드 리뷰, 순수 Q&A. 보기만 하고 변경은 불가
workspace-write (기본)현재 작업 영역 디렉터리 + 시스템 임시 디렉터리만일상 업무. 프로젝트 파일은 바꿀 수 있지만 시스템과 다른 프로젝트는 건드릴 수 없음
danger-full-access제한 없음디스크 전체 작업이 명확히 필요할 때만. 시스템 유지보수, 소프트웨어 설치 등. 위험은 본인이 부담

쉽게 놓치는 부분: 샌드박스는 파일 시스템 부작용만 관리하며 네트워크나 프로세스 격리는 관여하지 않습니다. 즉 workspace-write 모드에서도 Agent는 작업 영역 밖 파일을 쓸 수는 없지만, 네트워크 요청을 보내거나, 작업 영역 밖 파일을 (읽기 전용으로) 읽을 수는 있습니다. 따라서 workspace-write를 켰다고 절대 안전하다고 생각하면 안 됩니다. 작업 영역 안의 민감한 파일 내용이 API 요청을 통해 외부로 나갈 수도 있습니다(정상 모델은 그렇게 안 하지만 이론적 경계는 있습니다).

전환 방법은 CH 04에서 다뤘습니다. 현재 세션에서 임시로 바꾸려면 /permission을 쓰고, 기본값을 바꾸려면 설정 → 일반 → 권한(새로 만드는 세션부터 적용).

2층: 작업 승인

샌드박스가 "어떤 파일을 건드릴 수 있는가"를 잡아주듯, 승인은 "민감한 작업을 실행할 수 있는가"를 잡아줍니다.

Agent가 현재 권한 범위를 벗어나는 일을 하려 할 때, 예를 들어 workspace-write 모드에서 작업 영역 밖 파일을 쓰려 한다거나, 시스템을 바꿀 수도 있는 명령을 실행하려 할 때 곧바로 실행하지 않고 먼저 승인 요청을 올립니다. 인터페이스에 다이얼로그가 떠서 다음을 알려줍니다.

  • 실행하려는 작업(구체적인 명령이나 파일 경로)
  • 왜 그렇게 하려는가(모델이 제시한 이유)

그리고 세 가지 선택지가 주어집니다. 한 번 허용, 거부, 취소.

이미지 자리: 여기에 "Agent가 작업 영역 밖 파일 쓰기를 요청하고 승인 다이얼로그가 뜬" 스크린샷 — 작업 내용, 모델의 이유, 허용/거부 버튼이 보이는 — 을 넣습니다.

몇 가지 핵심 디테일:

  1. 한 번 허용은 정말 한 번 — "앞으로도 허용"이 아닙니다. 다음에 같은 작업이 와도 다시 묻습니다.
  2. 거부는 거부 — 모델이 거부를 받으면 다른 우회 방법을 찾거나 못한다고 알려주며, 슬쩍 우회하지 않습니다.
  3. 승인은 플러그인 레벨 확장 포인트 — CH 11에서 도구 호출 파이프라인을 다뤘는데, 승인은 그 단계 중 하나입니다. 자체 플러그인을 써서 승인 정책을 커스터마이즈할 수 있습니다. 예컨대 "특정 명령은 자동 허용, 특정 명령은 자동 거부".

승인과 샌드박스는 서로 보완합니다. 샌드박스는 하드 경계(커널 수준, 우회 불가), 승인은 소프트 경계(정책 수준, 통과시킬 수 있음). 일상에서 workspace-write + 승인 팝업을 쓰는 것이 "기본 안전, 필요할 때 수동 허용"의 균형입니다.

3층: 키는 쓰기 전용

API Key는 가장 민감한 자산입니다. 유출되면 다른 사람이 내 쿼터를 쓰거나, 심지어 내 신분으로 API를 호출합니다. dsh가 키를 다루는 방식은 쓰기 전용(write-only) 입니다.

쓰기 전용이란 무엇인가? 설정 → 모델에서 API Key를 입력하고 저장하면, 인터페이스 위 그 Key 문자열이 "사라지고" 마스킹된 디스크립터(예: deepseek://sk-...x8f2)만 남습니다. 인터페이스에서 다시 평문 Key 전체를 읽어올 방법은 없습니다.

이건 버그가 아니라 의도된 설계입니다.

  • 평문 Key는 로컬 $DSH_HOME/.credentials.yaml에만 떨어집니다(Windows: C:\Users\<사용자 이름>\.dsh\.credentials.yaml)
  • 인터페이스와 settings.yaml에는 참조(apiKeyEnv 같은 필드)만 저장되며 평문은 저장되지 않음
  • 브라우저 메모리, 네트워크 로그, 프런트엔드 상태 어디에도 Key 전체가 다시 노출되지 않음

이미지 자리: 여기에 "설정 → 모델 페이지에서 DeepSeek 카드가 저장 후 마스킹된 디스크립터만 보여주는" 스크린샷 — 키 필드가 deepseek://sk-...xxxx 형식으로 바뀐 것 — 을 넣습니다.

키 우선순위(높은 순):

  1. 프로세스 환경 변수(export DEEPSEEK_API_KEY=sk-xxx)
  2. $DSH_HOME/.credentials.yaml 파일
  3. 프로젝트 디렉터리의 .env 파일

환경 변수가 우선순위가 가장 높아 임시 사용에 적합하고, 파일 방식이 가장 흔히 쓰이며 장기 설정에 적합합니다.

보안 알림: .credentials.yaml 파일 권한은 0600(본인만 읽기/쓰기 가능)이지만, 전체 ~/.dsh 디렉터리를 클라우드에 백업하거나 다른 사람과 공유하면 키도 함께 따라갑니다. 백업할 때는 마스킹 처리를 잊지 마세요.

데이터 프라이버시

키 외에도 dsh가 생성하는 모든 데이터는 로컬에 있습니다.

데이터저장 위치업로드 여부
세션 기록~/.dsh/sessions/안 함
트라젝토리(Trajectory)세션 기록에 내장안 함
플러그인 설정~/.dsh/profiles/안 함
API Key~/.dsh/.credentials.yaml안 함
작업 영역 파일사용자가 선택한 작업 영역 디렉터리안 함

dsh에는 클라우드 동기화도, 계정 체계도, 텔레메트리 리포팅도 없습니다. 모델과의 대화 내용은 사용자가 요청을 보낼 때 모델 제공사(DeepSeek 등)에게만 전달되며, dsh 자체는 클라우드에 사본을 보관하지 않습니다.

이것이 의미하는 것:

  • 장점: 데이터가 완전히 내 손에 있고, 프라이버시를 직접 통제할 수 있음
  • 단점: 컴퓨터를 바꾸면 ~/.dsh 디렉터리를 수동으로 옮겨야 하며 원클릭 동기화는 없음

보안 모범 사례

위에서 설명한 메커니즘을 일상 사용에 적용하려면 다음을 기억하세요.

  1. 일상에서는 workspace-write를 쓰고 full access를 상시 켜두지 말 것 — full access에서는 샌드박스가 사실상 사라지며 Agent가 하드 디스크 전체를 건드릴 수 있습니다. 시스템 수준의 작업이 명확히 필요할 때만 임시로 켜고, 끝나면 다시 돌려놓으세요.
  2. ~/.dsh 디렉터리를 그대로 GitHub에 푸시하지 말 것 — 안에 .credentials.yaml 평문 키가 들어 있습니다. 설정을 백업해야 한다면 settings.yaml(키 미포함)만 따로 내보내고, 키는 별도로 관리하세요.
  3. Docker 팀 배포는 다중 사용자 격리가 없음에 주의 — CH 27에서 다뤘듯이, 현재 버전에서는 모두 같은 Basic Auth로 로그인해 같은 세션과 설정을 공유합니다. 팀이 함께 쓸 땐 민감 정보를 그 안에 넣지 말고, 각자 독립 인스턴스를 배포하세요.
  4. 작업 영역은 깔끔한 디렉터리를 고를 것C:\Users 전체나 홈 디렉터리를 작업 영역으로 지정하지 마세요. 전용 프로젝트 디렉터리를 지정해야 Agent가 만질 수 있는 범위가 그쪽으로 한정됩니다.

이 장에서 배운 것

아래 항목을 스스로 완수할 수 있으면 합격입니다.

  • [ ] dsh 보안 설계의 핵심 사고방식을 안다: 기본은 제한, 필요 시에만 허용
  • [ ] 세 겹의 보호가 무엇인지 안다: 파일 샌드박스, 작업 승인, 키는 쓰기 전용
  • [ ] 샌드박스가 OS 커널 수준이며 JS의 if 분기가 아니라는 점, 모델이 우회할 수 없다는 점을 안다
  • [ ] 세 단계 권한(read-only / workspace-write / danger-full-access)의 차이와 적용 시나리오를 분명히 설명할 수 있다
  • [ ] 승인이 "한 번 허용"이지 영구 허용이 아님을 안다
  • [ ] API Key가 쓰기 전용이라는 점, 저장 후 인터페이스에 다시 표시되지 않으며 평문은 로컬 .credentials.yaml에만 있음을 안다
  • [ ] dsh의 모든 데이터가 로컬에 있으며 클라우드 동기화가 없음을 안다
  • [ ] 일상 보안 모범 사례를 최소 3가지 이상 말할 수 있다

Open Source · MIT · Community Driven