코드스페이스 보안 — 고객사 요구사항 대응 가이드
이 문서는 누구를 위한 것인가
GenD 코드스페이스는 브라우저에서 바로 쓰는 개인 개발환경(JupyterLab + VS Code)입니다. 개발환경에는 터미널이 있고, 사용자는 거기서 임의의 명령을 실행할 수 있습니다. 이는 개발환경의 존재 이유이자, 동시에 보안 검토에서 가장 먼저 지적받는 지점입니다.
"그 터미널에서 우리 데이터베이스에 직접 붙거나, 클라우드 계정을 탈취하거나, 클러스터를 망가뜨릴 수 있는 것 아닙니까?"
본 문서는 이 질문에 항목별로, 근거와 함께, 고객이 직접 확인할 수 있는 방법까지 답합니다.
- 대상 독자: 고객사 정보보호 담당자 · 보안 심사(ISMS-P 등) 대응 담당자 · 도입 검토 실무자
- 구성: 각 절마다 ① 어떤 요구사항인가 → ② 실제로 이런 사고가 있었다 → ③ GenD 는 이렇게 막는다 → ④ 직접 확인하는 방법
- 원칙: 구현되지 않은 것은 12. 미충족·조건부 항목에 솔직히 공개합니다. 보안 문서에서 과장은 그 자체가 위험입니다.
아래 방어 항목은 운영 클러스터(AKS prod)에서 임시 계정으로 코드스페이스를 띄우고 실제 터미널에서 공격을 시도해 확인한 결과입니다(2026-07-24 실측). 설정 파일에 그렇게 적혀 있다는 수준이 아니라, 실제로 막히는 것을 확인한 내용입니다.
0. 한눈에 보기 — 코드스페이스에서 가능한 것과 불가능한 것
| 사용자가 터미널에서 시도하는 것 | 결과 | 무엇이 막는가 |
|---|---|---|
| 자격 없는 사용자가 코드스페이스 생성 | ❌ 차단 | codespace-users 그룹 자격 (이중 시행) |
파이썬/노트북 실행, 라이브러리 설치(pip install) | ✅ 가능 (정상 업무) | — |
| 인가된 데이터 조회 (GenD API 경유) | ✅ 가능 (권한 범위 내) | 데이터 권한(DataGrant) + 행·열 정책 + Trino 접근제어 |
sudo 로 관리자 권한 획득 | ❌ 차단 | 비루트 실행 + 권한상승 금지 |
kubectl 로 클러스터 조작 | ❌ 차단 | 클러스터 자격증명 미주입 |
| 클라우드(Azure) 관리자 자격증명 탈취 | ❌ 차단 | 메타데이터 서버 차단 |
| DB(PostgreSQL)·쿼리엔진(Trino)·금고(Vault)에 직접 접속 | ❌ 차단 | 내부망 egress 차단 |
| 다른 사용자의 작업 파일 열람 | ❌ 차단 | 사용자별 컨테이너·볼륨 분리 |
| 다른 워크스페이스(팀)의 데이터 조회 | ❌ 차단 | 워크스페이스 격리 + 권한 시행 |
| 컨테이너 자원을 무한정 사용해 클러스터 마비 | ❌ 차단 | 프로필별 상한 + 네임스페이스 쿼터 |
핵심 원칙: 코드스페이스에서 무슨 일이 일어나도 피해 범위(blast radius)는 그 사용자의 컨테이너 안입니다. 데이터에 접근하려면 반드시 검문소(GenD API의 권한 검사) 를 거쳐야 하며, 검문소를 우회하는 뒷문(내부망 직결)은 네트워크 수준에서 닫혀 있습니다.
1. 최소권한 원칙 — 컨테이너 내 권한 상승 차단
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.6 접근통제 — 최소권한 부여 |
| CIS Kubernetes Benchmark | 5.2.5 권한상승 금지, 5.2.6 root 컨테이너 금지 |
| ISO/IEC 27001 | A.8.2 특권 접근권한 관리 |
컨테이너 내부에서 관리자(root)가 되면 컨테이너 탈출(escape) 공격의 출발점이 되고, 노드의 다른 컨테이너까지 위협할 수 있습니다.
실제로 이런 사고가 있었습니다
컨테이너 런타임 취약점(예: runC CVE-2019-5736)은 컨테이너 안에서 root 권한을 가진
프로세스가 호스트의 런타임 바이너리를 덮어쓰는 방식으로 동작했습니다. 즉 "컨테이너 안에서
root 인가"가 호스트 장악 가능 여부를 가르는 분기점이었습니다.
GenD 는 이렇게 막습니다
- 코드스페이스 프로세스는 일반 사용자
jovyan(uid 1000) 으로 실행됩니다. root 가 아닙니다. allowPrivilegeEscalation: false— 리눅스의 no new privileges 플래그가 설정되어sudo·setuid 바이너리로 권한을 올리는 경로 자체가 봉인됩니다.- 리눅스 capability 는 전부 제거(
drop: [ALL])되어 네트워크 조작·마운트 등 특권 작업이 불가능합니다. - 이 값들은 설치 도구의 기본값에 의존하지 않고 GenD 설정 파일에 명시되어 있으며, 누군가 이를 끄면 CI가 코드 병합을 차단합니다(회귀 방지).
직접 확인하세요
코드스페이스 터미널에서:
id
# 기대: uid=1000(jovyan) gid=100(users) — root(uid=0) 아님
sudo -n true
# 기대: sudo: The "no new privileges" flag is set, which prevents sudo from running as root.
2. 인프라 컨트롤플레인 접근 차단 — 클러스터 조작 방지
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.9 시스템 및 서비스 운영관리 — 관리자 접근 통제 |
| CIS Kubernetes Benchmark | 5.1.5/5.1.6 ServiceAccount 토큰 자동 마운트 금지 |
| SOC 2 | CC6.1 논리적 접근 통제 |
쿠버네티스 파드에는 기본적으로 클러스터를 조작할 수 있는 자격증명(ServiceAccount 토큰) 이 자동으로 들어갑니다. 이 토큰에 권한이 붙어 있으면, 컨테이너 하나가 뚫리는 순간 클러스터 전체가 위험해집니다.
실제로 이런 사고가 있었습니다
테슬라(2018) — 인증 없이 노출된 쿠버네티스 대시보드를 통해 공격자가 클러스터에 접근했고, 거기서 얻은 클라우드 자격증명으로 계정을 침해해 암호화폐 채굴에 사용했습니다. 컨테이너/클러스터 자격증명 하나가 전체 인프라로 가는 통로가 된 사례입니다.
GenD 는 이렇게 막습니다
- 코드스페이스 파드에는 ServiceAccount 토큰이 아예 마운트되지 않습니다. 권한이 없는 토큰이 들어가는 것도 아니라, 토큰 파일 자체가 존재하지 않습니다.
- 따라서
kubectl을 설치하더라도 인증할 자격증명이 없어 쿠버네티스 API 호출이 원천적으로 불가능합니다. - 추가로, 네임스페이스의 기본 ServiceAccount 에는 어떤 권한(RoleBinding)도 부여되어 있지 않습니다 — 토큰을 어떻게든 구해도 권한이 없습니다(이중 방어).
직접 확인하세요
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# 기대: No such file or directory (토큰 자체가 없음)
3. 클라우드 자격증명 탈취 방지 — 메타데이터 서버 차단
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.10 시스템 보안관리 — 클라우드 자원 접근 통제 |
| ISO/IEC 27001 | A.5.15 접근통제, A.8.3 정보 접근 제한 |
| CIS Cloud Benchmark | 인스턴스 메타데이터 접근 제한 |
클라우드 가상머신에는 169.254.169.254 라는 내부 전용 주소가 있고, 여기에 접속하면
그 노드에 부여된 클라우드 계정 자격증명을 받아올 수 있습니다. 애플리케이션이 이 주소로
요청을 보내도록 유도하는 공격(SSRF)이 클라우드 침해의 대표 경로입니다.
실제로 이런 사고가 있었습니다
캐피털 원(2019) — 공격자가 서버 측 요청 위조(SSRF) 취약점을 이용해 EC2 인스턴스
메타데이터 서버(169.254.169.254)에서 IAM 자격증명을 획득했고, 그 권한으로 S3 버킷의
약 1억 건의 고객 정보를 유출했습니다. 클라우드 보안 역사상 가장 많이 인용되는
메타데이터 탈취 사고입니다.
개발환경 터미널은 SSRF 취약점조차 필요 없습니다 — curl 169.254.169.254 한 줄이면 되므로,
차단이 없다면 캐피털 원 사고보다 쉬운 경로가 됩니다.
GenD 는 이렇게 막습니다
- 코드스페이스 파드가 뜰 때 전용 초기화 컨테이너(
block-cloud-metadata) 가 실행되어169.254.169.254로 향하는 트래픽을 방화벽 규칙(iptables)으로 차단합니다. - 네트워크 정책에서도 해당 주소를 egress 허용 대상에서 제외합니다(이중 방어).
직접 확인하세요
curl --max-time 5 -H "Metadata:true" \
"http://169.254.169.254/metadata/instance?api-version=2021-02-01"
# 기대: 타임아웃 또는 연결 실패 (자격증명 응답 없음)
4. 내부 시스템 직접 접근 차단 — 망 분리 / 인가된 경로 강제
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| 전자금융감독규정 | 제15조 해킹 등 방지대책 — 망 분리 |
| ISMS-P | 2.6.1 네트워크 접근, 2.6.7 인터넷 접속 통제 |
| CIS Kubernetes Benchmark | 5.3.2 NetworkPolicy 적용 |
개발환경이 운영 데이터베이스에 직접 붙을 수 있으면, 애플리케이션 계층의 모든 통제 (권한 검사·마스킹·감사 로그)가 무의미해집니다. 데이터 유출 사고의 다수가 이 경로입니다.
실제로 이런 사고가 있었습니다
국내 카드사 대량 개인정보 유출 사고들의 공통 구조는 "개발·분석 목적으로 운영 데이터에 직접 접근할 수 있었다" 는 점이었습니다. 권한 있는 내부자나 외주 인력이 정상 도구로 대량 조회·반출했고, 애플리케이션의 권한 통제는 우회됐습니다. 이 때문에 금융권에서는 망 분리와 "직접 접속 금지, 통제된 경로만 허용" 이 강제 요구사항이 되었습니다.
GenD 는 이렇게 막습니다
코드스페이스에서 사설 IP 대역 전체(10/8, 172.16/12, 192.168/16)로 나가는 통신이 차단됩니다. 결과적으로:
- PostgreSQL(
postgresql:5432) — ❌ 직접 접속 불가 - Trino 쿼리엔진(
trino:8080) — ❌ 직접 접속 불가 - Vault 비밀금고(
vault:8200) — ❌ 직접 접속 불가 - 벡터DB(
weaviate:8080), 내부 API — ❌ 직접 접속 불가
데이터에 접근하는 유일한 경로는 공개 진입점(Ingress)을 통한 GenD API 입니다. 이 경로에는 데이터 권한 시행(DataGrant) · 행 필터/컬럼 마스킹 · 워크스페이스 격리 · 감사 로그가 걸려 있습니다(5절 참조).
즉, 검문소를 통과하는 길만 열려 있고 뒷문은 네트워크 수준에서 닫혀 있습니다.
네트워크 정책은 클러스터에 정책 시행 엔진(enforcer) 이 있어야 실효합니다. GenD 운영 클러스터(AKS)는 Calico 로 시행됩니다. 자체 클러스터에 GenD 를 설치하는 경우, CNI 가 NetworkPolicy 를 강제하는지 반드시 확인하십시오(예: kind 의 기본 kindnet 은 시행하지 않아 정책이 무효화됩니다).
직접 확인하세요
python3 -c "
import socket
for host, port in [('trino',8080), ('postgresql',5432), ('vault',8200)]:
s = socket.socket(); s.settimeout(4)
try:
s.connect((host, port)); print(f'{host}:{port} 연결됨 (문제)')
except Exception as e:
print(f'{host}:{port} 차단됨 ({type(e).__name__})')
finally:
s.close()
"
# 기대: 전부 '차단됨 (timeout)'
5. 데이터 접근 통제 — 인가된 경로만 허용
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.6.3 응용프로그램 접근, 3.2 개인정보 접근권한 |
| 개인정보보호법 | 제29조 안전조치 — 접근권한 최소화 |
| SOC 2 | CC6.3 데이터 접근 권한 관리 |
"누가 어떤 데이터를 볼 수 있는가"가 사용자 재량이 아니라 시스템이 강제해야 합니다.
실제로 이런 사고가 있었습니다
내부자 유출 사고의 전형은 "권한은 있었지만 필요 범위를 넘어선 조회" 입니다. 분석 목적으로 부여된 계정으로 담당 업무와 무관한 고객 데이터를 대량 조회·반출하는 형태로, 개별 쿼리는 정상으로 보이기 때문에 권한 범위 자체를 좁히지 않으면 탐지가 어렵습니다.
GenD 는 이렇게 막습니다
코드스페이스에서 데이터를 조회하는 정상 경로(GenD API·SDK·gend CLI)에는 다음이
서버 측에서 적용됩니다 — 클라이언트 설정으로 끌 수 없습니다:
- DataGrant 권한 시행: 사용자에게 명시적으로 부여된 데이터에만 접근 허용. 권한이 없으면 403 으로 거부되고 위반 시도는 지표(metric)로 집계됩니다
- 워크스페이스 격리: 소속 팀(워크스페이스) 밖의 데이터는 조회 결과에서 제외됩니다. 소속을 해석할 수 없는 사용자는 차단(fail-closed) 이 기본 동작입니다
- ABAC(행 필터·컬럼 마스킹) 및 PII 마스킹: 정책에 따라 민감 컬럼이 마스킹된 상태로 반환
SQL 종류별 통제 주체(정확한 구분):
| SQL 출처 | 통제 |
|---|---|
| AI 가 생성한 SQL(자연어→SQL 등) | SqlGuard — 조회(SELECT) 외 차단, 시스템 카탈로그 접근 차단, 워크스페이스 교차 조인 차단 |
| 사용자가 직접 작성한 SQL | GenD API 를 경유하는 한 위의 DataGrant·행/열 정책·워크스페이스 격리가 적용됩니다. 애플리케이션 계층의 SqlGuard 는 적용되지 않습니다 |
위 통제는 GenD API·SDK·CLI 를 경유할 때 서버 측에서 적용됩니다. 쿼리 엔진(Trino)에 JDBC 등으로 직접 접속하는 경로에는 엔진 계층 파일 ACL 이 활성화(v1.1+)되어 있어, DataGrant 에서 파생된 카탈로그·스키마·테이블 단위 접근제어가 적용됩니다 — 권한이 없는 테이블은 직접 접속으로도 조회할 수 없으며, 권한 변경은 주기 동기화로 수 분 내 엔진에 반영됩니다(Trino JWT 가이드 참조).
다만 행 필터·컬럼 마스킹·PII 마스킹은 이 경로에 적용되지 않습니다 — 파일 기반 정책이 행/열 마스킹을 지원하지 않기 때문입니다. 따라서:
- 행/열 수준 정책 시행이 필요한 민감 데이터 조회는 반드시 GenD API 경로를 사용해야 합니다
- 직접 접속 기능이 필요 없다면 비활성화하는 것을 권장합니다(고객 환경별 구성 가능)
- 행/열 수준 엔진 시행은 로드맵 항목입니다 — 별도 설계가 필요합니다
이 갭은 자체 보안 검증(2026-07-27)에서 확인되어 공개했으며, 이 중 테이블 단위 접근제어는 활성화 완료되었습니다(2026-08-05).
현재 운영 환경의 권한 시행은 화이트리스트 모드로, 학습 데이터셋 테이블
전체(테이블 접두어 ds_ 로 식별 — 어느 워크스페이스 스키마에 있든)에 적용되어
있으며, 관측 데이터를 축적하며 범위를 확대하는 단계적 전환 중입니다
(12절 참조).
데이터셋이 워크스페이스별 스키마(iceberg.ws_<슬러그>)로 옮겨간 뒤에도(ADR-0044)
시행 범위가 따라가도록, 스키마 이름이 아니라 테이블 접두어로 판정합니다 — 스키마
목록으로 관리하면 워크스페이스가 늘 때마다 갱신해야 하고 빠뜨리면 그 워크스페이스의
데이터셋이 조용히 범위 밖으로 나갑니다.
관리자도 예외가 아닙니다
보안 심사에서 자주 확인하는 지점입니다 — "관리자는 마스킹을 우회하는가?"
GenD 는 관리 권한과 원본 열람 권한을 분리합니다:
| 권한 | 의미 | 마스킹 |
|---|---|---|
| 관리자(admin) | 플랫폼 운영 — 사용자·정책·인프라 관리 | 적용됨 (예외 없음) |
| 원본 열람(unmask) | 마스킹·행 필터 면제 — 별도로 명시 부여 | 면제 |
- 관리자라는 이유만으로 원본 데이터를 볼 수 없습니다. 원본이 필요한 업무(장애 조사·데이터 품질 확인 등)는 별도 권한을 신청·부여받아야 합니다.
- 원본 열람 권한 사용은 전부 기록됩니다 — 누가·언제·어떤 조회로 면제를 사용했는지가 감사 로그와 지표에 남습니다. 부여받았다는 사실만으로 조용히 열람할 수는 없습니다.
- 기본값은 아무도 원본 열람 권한을 갖지 않는 상태이며, 필요 인원에게만 최소 부여합니다.
데이터 권한(DataGrant) 시행은 관리자 예외를 유지합니다 — 플랫폼 운영자가 권한 미보유 테이블 조회로 잠기면 장애 대응이 불가능하기 때문입니다. 다만 그 조회 역시 위반으로 기록되어 감사 지표에 남습니다(차단하지 않을 뿐 기록은 남깁니다).
직접 확인하세요
권한이 없는 테이블을 조회해 보십시오.
gend query "SELECT * FROM iceberg.ws_<타인_워크스페이스>.ds_<타인_소유> LIMIT 1"
# 기대: 403 — 권한 없음 (테이블 목록에 뜨더라도 조회는 거부)
6. 사용자 간 격리 — 다른 사람의 작업물 보호
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.6.2 정보시스템 접근, 2.7 암호화 적용 |
| ISO/IEC 27001 | A.8.3 정보 접근 제한 |
멀티테넌트 환경에서 사용자 A 가 사용자 B 의 코드·데이터·자격증명에 접근할 수 없어야 합니다.
실제로 이런 사고가 있었습니다
공용 분석 서버(모두가 같은 서버에 로그인해 각자 폴더를 쓰는 방식)에서는 파일 권한 설정 실수 하나로 다른 사람의 노트북·자격증명 파일이 그대로 읽히는 일이 반복적으로 발생했습니다. 격리를 파일 권한에 의존한 구조의 한계입니다.
GenD 는 이렇게 막습니다
- 코드스페이스는 사용자마다 별도의 컨테이너로 실행됩니다. 공용 서버에 함께 로그인하는 구조가 아닙니다.
- 저장 공간도 사용자별 전용 볼륨(PVC) 이 각자의 컨테이너에만 연결됩니다. 다른 사용자의 볼륨은 애초에 마운트되지 않습니다.
- 코드스페이스 제어 API(시작·중지·상태 조회)는 본인 또는 관리자만 호출할 수 있으며, 타인의 자원을 지정하면 403 으로 거부됩니다.
- 사용자 식별은 SSO 토큰에서 서버가 판정합니다 — 클라이언트가 사용자명을 바꿔 보내도 소용없습니다.
직접 확인하세요
ls /home/jovyan # 본인 파일만 존재
mount | grep jovyan # 본인 볼륨 1개만 연결됨
관리자는 파드 목록에서 사용자별로 파드와 볼륨이 1:1 분리되어 있음을 확인할 수 있습니다.
7. 인증 및 세션 — 신원 확인과 접속 통제
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.5 인증 및 권한관리 |
| 전자금융감독규정 | 제13조 전산실 등 접근통제 |
| SOC 2 | CC6.1 인증 |
GenD 는 이렇게 구현되어 있습니다
- 코드스페이스 접근은 Keycloak 기반 SSO(OpenID Connect) 로 인증됩니다. 코드스페이스 전용 별도 계정·비밀번호가 없으며, 전사 계정 정책이 그대로 적용됩니다.
- 사용 자격은 명시적 그룹(
codespace-users)으로 통제됩니다 — SSO 로 인증되더라도 이 그룹에 속하지 않으면 코드스페이스를 생성할 수 없습니다(403). 코드스페이스는 사용자당 컨테이너와 전용 볼륨을 점유하므로, 데이터 접근 역할과 분리된 별도 자격으로 다룹니다. 통제는 두 지점에서 이중으로 시행됩니다(직접 로그인 경로 + 플랫폼 API 경로). - 계정 보호: 로그인 실패 5회 시 일시 잠금(브루트포스 차단), 비밀번호는 12자 이상 + 대소문자·숫자 조합 + 사용자명 포함 금지 + 최근 3개 재사용 금지.
- 미인증 사용자는 코드스페이스 URL 에 직접 접근해도 로그인으로 리다이렉트됩니다.
- 세션은 유휴 30분 / 최대 10시간 후 만료됩니다.
- 코드스페이스 자체도 1시간 무활동 시 자동 종료되고 최대 수명은 8시간입니다. 방치된 개발환경이 상시 노출되는 것을 방지합니다(작업 파일은 볼륨에 보존).
- 다중 인증(MFA) — TOTP(OTP 앱) 및 WebAuthn(보안키) 기능이 준비되어 있으나 현재 전사 강제는 비활성 상태입니다. 고객사 요구 시 설정 변경만으로 즉시 전 사용자 강제가 가능합니다(12절).
8. 감사 추적 — 누가 무엇을 했는지 기록
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.9.4 로그 및 접속기록 관리 |
| 개인정보보호법 | 제29조 — 접속기록 보관 및 위·변조 방지 |
| 전자금융감독규정 | 제13조 — 접속기록 보존 |
실제로 이런 사고가 있었습니다
침해 사고 대응에서 가장 흔한 실패는 "무엇이 얼마나 유출됐는지 특정할 수 없음" 입니다. 접속기록이 없거나, 있어도 공격자가 지울 수 있으면 피해 범위 산정도 법적 대응도 불가능합니다. 개인정보보호법이 접속기록의 위·변조 방지까지 요구하는 이유가 여기에 있습니다.
GenD 는 이렇게 기록합니다
- 코드스페이스에서 GenD API 로 나가는 모든 요청이 구조화된 감사 로그로 기록됩니다 — 사용자 ID · 호출 엔드포인트 · HTTP 메서드 · 응답 코드 · 처리 시간.
- 감사 로그는 HMAC 해시 체인으로 서로 연결되어, 중간 기록을 삭제하거나 고치면 체인 검증에서 드러납니다. 검증은 정기 배치로 자동 수행됩니다(위·변조 방지 요건 대응).
- 데이터 조회는 별도의 접근 이력으로도 남아 "누가 어떤 테이블을 조회했는가"를 사후 추적할 수 있습니다.
- 권한 없는 접근 시도는 거부와 동시에 지표(metric)로 집계되어 이상 징후 탐지에 사용됩니다.
- 감사 로그는 검색 가능한 저장소로 수집되어 90일 보존되며, 보존 기간 내 인덱스는 읽기 전용(WORM) 으로 전환되어 사후 변경이 차단됩니다.
컨테이너 내부에서 실행한 셸 명령이 개별 감사 기록으로 남지는 않습니다. 감사 로그의 대상은 플랫폼 API 호출과 데이터 접근입니다.
보완 장치로 런타임 위협 탐지가 전 노드에서 가동 중이며 코드스페이스 파드도 감시 범위에 포함됩니다 — 커널 시스템콜 수준에서 동작하므로 권한 상승 시도·민감 파일 접근 등 이상행위 탐지가 가능합니다. 코드스페이스 특화 규칙 3종(예상 밖 프로세스 실행·정찰 도구 사용·자격증명 파일 접근)이 적용되어 있고, 탐지 이벤트는 감사 인덱스에 보존되어 조회할 수 있습니다.
다만 이는 전체 명령 감사(세션 레코딩)와는 다른 수준입니다 — 모든 셸 명령을 기록하는 것이 아니라 이상 패턴을 탐지하는 방식이며, 실시간 알림 라우팅은 아직 연동 전입니다 (12절 참조).
탐지 예시 — 실제 기록된 이벤트
아래는 운영 환경에서 실제로 기록된 탐지 이벤트입니다. 코드스페이스 터미널에서 네트워크 분석 도구를 실행했을 때 남은 기록으로, 누가·어느 코드스페이스에서·어떤 명령을 실행했는지가 함께 남습니다.
{
"rule": "Recon Tool in GenD Codespace",
"priority": "Warning",
"proc.name": "tcpdump",
"proc.cmdline": "tcpdump",
"k8s.pod.name": "jupyter-<사용자>",
"user.name": "jovyan",
"container.image.repository": ".../gend-singleuser-codeserver",
"time": "2026-07-25T15:18:59Z"
}
적용된 코드스페이스 탐지 규칙은 세 가지입니다:
| 규칙 | 심각도 | 탐지 대상 |
|---|---|---|
| 정찰·네트워크 도구 실행 | Warning | 포트 스캐너·패킷 캡처·컨테이너 제어 도구 |
| 자격증명 파일 접근 | Warning | 클라우드 자격증명·SSH 키·클러스터 설정 파일 |
| 예상 밖 프로세스 실행 | Notice | 개발 도구 허용 목록 밖의 프로세스 |
개발 도구(파이썬·git·패키지 설치·빌드 툴체인 등)는 허용 목록으로 제외되어 정상
작업이 경보를 만들지 않습니다. 이벤트는 감사 인덱스(gend-audit-falco-*)에 보존되어
기간·사용자·규칙별로 조회할 수 있습니다.
9. 크레덴셜 관리 및 공급망 보안
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.5.4 비밀번호 관리, 2.7 암호화 적용 |
| ISO/IEC 27001 | A.8.24 암호키 관리, A.5.21 공급망 보안 |
| SOC 2 | CC6.1 자격증명 관리 |
실제로 이런 사고가 있었습니다
- Codecov(2021) — CI 도구의 스크립트가 변조되어, 이를 사용하던 고객사들의 환경변수에 담긴 자격증명이 외부로 전송됐습니다. 개발환경에 장수명 자격증명이 상주할 때의 위험을 보여준 대표 사례입니다.
- 소스코드에 하드코딩된 API 키가 저장소로 흘러가 악용되는 사고는 매년 반복됩니다.
GenD 는 이렇게 관리합니다
- 코드스페이스에는 플랫폼 자격증명이 사전 주입되지 않습니다. 파드 환경변수에 GenD API 키나
DB 접속 정보가 들어가지 않으며, 사용자가
gend init을 실행할 때 비로소 git 토큰이 발급됩니다. - git 토큰은 발급 시 유효기간이 최대 60분으로 제한되고(상한은 서버가 강제), 권한 범위는 저장소 접근으로 한정되며, GenD 데이터베이스에는 해시만 저장됩니다(평문 미보관). 단, 발급된 토큰의 Git 서버 측 실제 만료·회수는 현재 자동화되어 있지 않습니다 (12절 참조).
- 발급된 토큰은 소유자만 읽을 수 있는 권한(0600)으로, 파일 생성 시점부터 저장됩니다 (권한이 느슨한 상태로 노출되는 순간이 없습니다).
- 플랫폼의 시크릿(DB 비밀번호·API 키)은 Vault·Kubernetes Secret 으로 관리되며 코드스페이스에 주입되지 않습니다. 애초에 코드스페이스는 Vault 에 네트워크로 접근할 수도 없습니다(4절).
- 코드스페이스 이미지에는 시크릿 탐지(detect-secrets) · 노트북 출력 제거(nbstripout) · pre-commit 도구가 사전 설치되어 있습니다. 다만 git hook 으로 자동 활성화되지는 않으며, 사용자가 직접 설정해야 합니다(경량 JupyterLab 프로필에는 도구 자체가 미설치).
- 이미지 취약점은 CI 에서 Trivy 로 스캔(CRITICAL·HIGH)됩니다. 코드스페이스 이미지는 현재 리포트 전용이며 병합을 차단하지 않습니다(플랫폼 API 이미지는 차단). 베이스 이미지는 버전 고정 + 다운로드 무결성(SHA-256) 검증 후 빌드되고, 알려진 취약점은 이미지 빌드 시 보정 패키지로 덮어씁니다.
10. 자원 남용 방지 — 가용성 보호
어떤 요구사항인가
| 표준·규제 | 해당 조항 |
|---|---|
| ISMS-P | 2.9.3 성능 및 장애관리 |
| ISO/IEC 27001 | A.8.6 용량 관리 |
한 사용자가 무한 루프나 대용량 학습 작업으로 클러스터 전체를 마비시키면 안 됩니다.
GenD 는 이렇게 막습니다
- 프로필별 CPU·메모리 상한: Basic 1 CPU/2G · Standard 2 CPU/4G · Large 4 CPU/8G. 상한을 초과하면 해당 컨테이너만 제한되며 다른 사용자에게 영향이 없습니다.
- 개인 저장공간은 10Gi 로 제한됩니다.
- 네임스페이스 전체에도 쿼터(CPU·메모리·볼륨 개수)가 설정되어 있어, 코드스페이스가 플랫폼 전체 자원을 잠식할 수 없습니다.
- 유휴 자동 종료(1시간)로 방치된 환경이 자원을 계속 점유하지 않습니다.
- 동시 실행 상한: 클러스터 전체 동시 코드스페이스 20개, 동시 기동 5개 — 스폰 폭주로 클러스터가 마비되는 것을 방지합니다.
11. 데이터 암호화
| 구간 | 적용 | 비고 |
|---|---|---|
| 전송 구간(사용자 ↔ 코드스페이스) | ✅ HTTPS/TLS (cert-manager 자동 갱신) | 공개 진입점에서 종단 |
| 저장 구간(개인 볼륨) | ✅ Azure Managed Disk 서버측 암호화 | 플랫폼 관리 키 — 고객 관리 키(CMK) 요구 시 별도 구성 필요 |
| 데이터베이스 연결 | ✅ 애플리케이션 연결은 TLS 인증서 검증(verify-full) | 부가 컴포넌트 1건이 전환 잔여 — 개선 진행 중 |
12. 미충족·조건부 항목 (정직한 공개)
보안 문서에서 가장 중요한 부분입니다. 현재 구현되지 않았거나 조건부인 항목을 공개합니다. 대부분은 고객 요구 시 설정·추가 구성으로 대응 가능합니다.
| # | 항목 | 현재 상태 | 고객 요구 시 대응 |
|---|---|---|---|
| 1 | MFA 강제 | 기능 준비됨(TOTP·WebAuthn), 전사 강제는 비활성. 단 브루트포스 차단·비밀번호 정책은 적용됨 | Keycloak 필수 액션 활성화 — 설정 변경 즉시 적용 |
| 2 | 공용 인터넷 접근 | 허용됨(pip install 등 개발 편의). 데이터 반출 경로가 될 수 있음 | 폐쇄망 요구 시: 사내 패키지 미러 + 인터넷 egress 차단 구성 필요(별도 설계) |
| 3 | 터미널 명령 로깅 | 명령 단위 감사는 여전히 미구현 — 컨테이너 내부 셸 명령이 개별 기록되지는 않음. 단 코드스페이스 전용 런타임 탐지 규칙 3종(예상 밖 프로세스·정찰 도구·자격증명 파일 접근)이 적용·가동 중이며, 탐지 이벤트는 감사 인덱스에 보존·검색 가능 | 전체 명령 감사·세션 레코딩이 요구되면 별도 도입 검토 |
| 4 | Pod Security Admission / 정책 엔진 | PSA 경고·감사 모드 적용(위반 시 기록, 차단은 아님). 정책 엔진(Kyverno·Gatekeeper)은 미도입 — 격리는 배포 설정 + CI 회귀 가드로 강제 | 차단 모드 승격은 선행 과제 필요: 실측 결과 네임스페이스 워크로드의 절반 이상이 인프라 필수 요구(서비스 메시 네트워크 권한, 로그 수집 호스트 경로)로 기준을 위반해, 그대로 차단하면 메시·로그 수집이 중단됨 |
| 5 | 저장 암호화 키 관리 | 플랫폼 관리 키(SSE) | 고객 관리 키(CMK) 요구 시 별도 구성 |
| 6b | 쿼리 엔진 직접 접속(JDBC 등)의 정책 시행 | 부분 적용 — 카탈로그·스키마·테이블 단위 파일 ACL 활성화(v1.1+, DataGrant 파생 규칙 주기 자동 동기화). 행 필터·컬럼 마스킹은 이 경로에 미적용. GenD API 경로에는 모든 통제가 적용됩니다(5절 경고 참조) | 직접 접속 비활성화(즉시 가능) / 행·열 수준 엔진 시행 도입(별도 설계 — 로드맵) |
| 6 | 데이터 권한 시행 범위 | 화이트리스트 모드 — 학습 데이터셋 테이블(접두어 ds_, 스키마 무관)에만 차단 적용. 그 외 테이블은 관측·기록만 | 전면 적용은 사전 권한 백필 후 전환(운영 절차·런북 보유) |
| 7 | 서비스 간 mTLS | 코드스페이스 파드는 서비스 메시 비가입 | 내부망 egress 자체가 차단되어 실질 위험은 낮음. 요구 시 메시 편입 검토 |
| 8 | git 토큰 서버측 만료·회수 | 발급 시 TTL 60분 상한 강제 + DB 해시 저장은 적용. 그러나 Git 서버 측 실제 만료 전달·자동 회수 배치는 미구현 | 회수 API 연동 + 만료 토큰 정리 배치 추가(로드맵) |
| 9 | 커밋 전 시크릿 검사 자동화 | 도구는 사전 설치, hook 자동 활성화 아님. Git 서버 push 시 서버측 스캔 없음 | 이미지에 hook 자동 설치 + 서버측 스캔 도입 가능 |
| 10 | 코드스페이스 이미지 CVE 게이트 | 코드스페이스 이미지 2종 모두 스캔(통합 이미지 + 경량 JupyterLab 이미지). 다만 차단 아님(리포트 전용) | 베이스라인 해소 후 차단 승격 예정 |
| 11 | 읽기전용 루트파일시스템 / seccomp | seccomp 기본 프로파일 적용 — 불필요한 시스템콜을 차단해 커널 공격면 축소. 읽기전용 루트파일시스템은 미적용(노트북 환경은 홈·커널 등록·확장 설치에 쓰기가 필요해 부작용 대비 실익이 낮다는 판단) | 읽기전용 요구 시 쓰기 경로 분리 설계 선행 |
| 12 | 런타임 위협 탐지 — 알림 라우팅 | 런타임 탐지는 전 노드 가동 중이고 코드스페이스 특화 규칙도 적용 완료(예상 밖 프로세스·정찰 도구·자격증명 접근). 탐지 이벤트는 감사 인덱스에 보존됩니다. 다만 실시간 알림 라우팅(메신저·온콜)은 미연동 — 현재는 조회 기반 | 알림 채널 연동은 후속(운영 절차와 함께 설계) |
13. 고객 보안 심사 체크리스트
심사·실사 시 아래 항목을 코드스페이스 터미널에서 직접 실행해 확인할 수 있습니다.
| # | 확인 항목 | 명령 | 기대 결과 |
|---|---|---|---|
| 1 | 비루트 실행 | id | uid=1000(jovyan) |
| 2 | 권한 상승 차단 | sudo -n true | no new privileges 오류 |
| 3 | 클러스터 자격증명 부재 | cat /var/run/secrets/kubernetes.io/serviceaccount/token | 파일 없음 |
| 4 | 클라우드 메타데이터 차단 | curl --max-time 5 http://169.254.169.254/ | 타임아웃 |
| 5 | 내부 DB 직접 접속 차단 | 4절의 python 스니펫 | 전부 타임아웃 |
| 6 | 인가 경로는 동작 | gend dataset list | 본인 권한 범위의 목록만 반환 |
| 7 | 자원 상한 | cat /sys/fs/cgroup/memory.max | 프로필 상한값 |
| 8 | 자동 종료 정책 | 1시간 방치 후 재접속 | 중지 상태, 파일 보존 |
| 9 | 진입 자격 통제 | 자격 그룹 미소속 계정으로 코드스페이스 시작 시도 | 403 — 그룹 소속 필요 안내 |
| 10 | 계정 잠금 | 로그인 5회 연속 실패 후 정상 비밀번호로 시도 | 일시 잠금(로그인 거부) |
14. 자체 클러스터 배포 시 필수 확인
GenD 를 고객사 자체 인프라에 설치하는 경우, 아래를 반드시 확인하십시오.
- NetworkPolicy 시행 엔진 — CNI 가 NetworkPolicy 를 강제해야 4절의 내부망 차단이 실효합니다(Calico·Cilium 등). 미지원 CNI 에서는 격리가 무효가 됩니다.
- 격리 설정 유지 — 코드스페이스 격리 값은 배포 설정에 명시되어 있고 CI 가 회귀를 차단합니다. 설정을 커스터마이즈할 때 해당 값을 끄지 마십시오.
- 인증 정책 — 고객사 계정 정책(MFA·비밀번호·잠금)을 Keycloak 에 반영하십시오.
- 폐쇄망 요건 — 인터넷 차단이 필요한 환경은 사내 패키지 미러 구성이 선행되어야 합니다.
관련 문서
- 코드스페이스 사용 가이드 — 사용자용 · 운영 절차
- CVE 스캔 / 보안 개선 프로세스