보안 Hardening 체크리스트
로컬 노트북, CI 배치, 내부 분석 서비스별 DuckDB 보안·리소스·확장 정책을 표준화합니다.
핵심 요약
- DuckDB 보안은 SQL grant가 아니라 파일·네트워크·extension·secret·리소스를 다루는 실행 환경 통제 문제입니다.
- 로컬 노트북, CI/배치, 내부 분석 서비스 세 환경별로 SQL 입력·파일·네트워크·extension·secret·리소스 정책을 다르게 둡니다.
- extension은 parent process와 같은 권한으로 실행되므로 community/unsigned extension 허용은 코드 실행 허용 수준으로 검토합니다.
- secret은 prefix 단위 SCOPE로 좁히고 shared 장비에서는 persistent secret을 금지하며, SQL log에 literal을 남기지 않습니다.
- untrusted SQL은 그대로 실행하지 않고 allowlist template + parameter 바인딩으로 받아 리소스 제한된 sandbox에서 실행합니다.
DuckDB 보안은 SQL 권한 grant보다 실행 환경 통제에 가깝습니다. DuckDB SQL은 파일, 네트워크, extension, secret, CPU, 메모리까지 건드리므로 환경마다 hardening baseline을 따로 둡니다.
환경별 정책
| 항목 | 로컬 노트북 | CI/배치 | 내부 분석 서비스 |
|---|---|---|---|
| SQL 입력 | 신뢰한 작성자 | repo에 커밋된 SQL | allowlist query/template |
| 파일 접근 | project/scratch | job workspace | container volume 제한 |
| 네트워크 | 개발자 권한 | egress 제한 | egress deny 기본 |
| extension | core 위주 | pin + checksum/버전 기록 | core allowlist |
| secret | session secret 선호 | cloud role/CI secret | scope 좁은 service credential |
| 리소스 | 권장값 | hard limit | hard limit + timeout |
| 출력 | /tmp/scratch | staging 후 publish | per-request sandbox |
기본 hardening SQL
SET memory_limit = '6GB';
SET threads = 2;
SET preserve_insertion_order = false;
SET temp_directory = '/mnt/scratch/duckdb.tmp';
SET max_temp_directory_size = '100GB';
SET allow_community_extensions = false;allow_community_extensions는 엄격한 환경에서 community extension을 막는 기준입니다. unsigned extension은 production과 shared notebook에서 허용하지 않습니다.
Extension policy
| 등급 | 예 | 정책 |
|---|---|---|
| built-in/core | json, parquet, httpfs | 허용, 버전 기록 |
| secondary/core | fts, 일부 domain extension | 사용 목적 명시 |
| community | community repository | 보안 리뷰 후 허용 |
| unsigned/custom | 자체 빌드 extension | 격리 환경 전용 |
공식 문서는 extension이 DuckDB parent process와 같은 권한으로 실행된다고 설명합니다. 그래서 extension을 허용하는 일은 코드 실행을 허용하는 것과 같은 수준으로 검토합니다.
Secret policy
CREATE SECRET scoped_lake (
TYPE s3,
PROVIDER credential_chain,
REGION 'ap-northeast-2',
SCOPE 's3://company-lake/curated/'
);| 체크 | 기준 |
|---|---|
| scope | bucket 전체가 아니라 prefix 단위 |
| persistence | shared 장비에서는 persistent secret 금지 |
| rotation | cloud IAM rotation 정책과 연결 |
| logging | secret literal을 SQL log에 남기지 않음 |
| teardown | job 종료 후 scratch와 token cache 정리 |
Untrusted SQL 방어
사용자 입력 SQL은 그대로 실행하지 않습니다. 필요하면 table, column, filter value를 allowlist 기반 parameter로 받고 실행은 container/VM sandbox 안으로 제한합니다.
CI 체크리스트
| 체크 | 실패 시 |
|---|---|
duckdb_extensions() 결과가 allowlist와 일치 | build fail |
duckdb_settings()가 baseline과 일치 | build fail |
| output path가 staging prefix | publish 중단 |
| input manifest가 기록됨 | 재현성 경고 |
EXPLAIN ANALYZE smoke query 성공 | deploy 중단 |
사고 대응
| 사고 | 첫 조치 |
|---|---|
| secret 노출 | credential revoke, persistent secret 삭제 |
| temp disk 고갈 | job kill, scratch cleanup, quota 조정 |
| extension 오용 | extension cache 삭제, allowlist 축소 |
| 파일 유출 의심 | OS/cloud audit log 확인, egress log 확인 |
| SQL DoS | timeout/limit 상향이 아니라 template 축소 |