k-skill/docs/security-and-secrets.md
설코딩 -SeolCoding 4ba9876a57
feat: 국가데이터처 KOSIS 통계 조회(kosis-stats) 스킬 추가 (#216)
* feat: 국가데이터처 KOSIS 통계 조회(kosis-stats) 스킬 추가

KOSIS Open API 4개 endpoint(statisticsSearch / statisticsData getMeta /
statisticsParameterData / statisticsBigData) read-only 호출을 단일 Python
helper로 묶었다. 인증키는 KSKILL_KOSIS_API_KEY 환경변수(또는 기본
secrets.env)로 사용자별 발급한다 — proxy 미사용.

- kosis-stats/SKILL.md, scripts/run_kosis_stats.py: stdlib only,
  search/meta/data/bigdata 서브커맨드, --json/--text/--dry-run
- kosis-stats/references/kosis-openapi-guide.md: 인증키 발급, 호출 한도
  (분당 1000건/40k cells), 에러 코드, HTTPS 전용 정책 정리
- kosis-stats/tests/: stdlib unittest 36개, mock 기반 (네트워크 X) +
  KSKILL_KOSIS_API_KEY 가 있을 때만 도는 라이브 smoke 1개
- docs/features/kosis-stats.md, README, install/setup/security-and-secrets/
  sources, examples/secrets.env.example, package.json lint/test 등록

* fix(kosis-stats): 사용자 시나리오 e2e 검증 기반 UX 보강

4개 sonnet 서브에이전트 병렬 시나리오(단일수치/시계열/지역비교/실패회복)
검증에서 발견된 P1/P2 UX 부족함 보강. 4개 회복 시나리오 친절도 평균 2.75
→ 4.5 (S4c 코드 20 막힘 P1 해결).

- ERROR_CODE_HINTS: 코드 20/21/30/31 모두 next-step 명령 예시 포함
  (코드 20은 ITM 메타 우선 안내 — 실제 표 다수에서 OBJ 비어 있음)
- render_search_text: Next 액션 흐름 안내 추가
- render_meta_text: 빈 결과 시 다른 --meta-type 시도 안내
- render_data_text: 빈 결과 시 필터/meta 재확인 안내,
  새 [summary] 라인(rows/period/unit, UNIT_NM 누락 명시)
- SKILL.md Workflow: 코드 20 회복 절차, 행정구역 코드(시도 2자리/시군구
  5자리) 관례 명시
- SKILL.md Failure modes: 코드 20 추가, meta 30 분기, UNIT_NM 누락 처리,
  코드 20/31 회복 시나리오 예시
- docs/features/kosis-stats.md "흔한 문제 해결"에 코드 20 회복 절차 추가
- tests: 8개 회귀 테스트 추가 (hint 키워드/render 메시지/[summary] 라인)

* fix(kosis-stats): drop xls bigdata format and detect json error envelope in non-json formats

Reviewer follow-up on PR #216:

- Removes `xls` from bigdata --format choices. KOSIS returns xls as a
  binary Excel payload, but the helper streams text-only output, which
  would corrupt the file. json/sdmx/csv (text) remain supported.
- Detects KOSIS `{err, errMsg}` envelopes even when --format is csv/sdmx,
  so non-json bigdata responses surface auth/limit errors instead of
  printing a misleading error envelope as raw success output.
- Updates SKILL.md, references/kosis-openapi-guide.md, and
  docs/features/kosis-stats.md so the advertised contract matches the
  helper's actual capabilities.
- Adds 3 unit tests: xls rejection, json error envelope detection in csv
  mode, and clean csv passthrough when no error envelope is present.

---------

Co-authored-by: Jeffrey (Dongkyu) Kim <vkehfdl1@gmail.com>
2026-05-08 23:06:19 +09:00

5.9 KiB

Security And Secrets

k-skill필요한 환경변수 이름만 선언하고, 그 값을 어떻게 공급하느냐는 에이전트의 자유에 맡긴다.

Credential resolution order

모든 credential-bearing 스킬은 아래 우선순위를 따른다.

  1. 이미 환경변수에 있으면 그대로 사용한다.
  2. 에이전트가 자체 secret vault(1Password CLI, Bitwarden CLI, macOS Keychain 등)를 사용 중이면 거기서 꺼내 환경변수로 주입해도 된다.
  3. ~/.config/k-skill/secrets.env (기본 fallback) — plain dotenv 파일, 퍼미션 0600.
  4. 아무것도 없으면 유저에게 물어서 2 또는 3에 저장한다.

기본 경로에 저장하는 것은 fallback일 뿐, 강제가 아니다.

Default secrets file

  • 경로: ~/.config/k-skill/secrets.env
  • 형식: plain dotenv (KEY=value, 한 줄에 하나)
  • 퍼미션: 0600 (owner-only read/write)
KSKILL_SRT_ID=replace-me
KSKILL_SRT_PASSWORD=replace-me
KSKILL_KTX_ID=replace-me
KSKILL_KTX_PASSWORD=replace-me
KSKILL_FORESTTRIP_ID=replace-me
KSKILL_FORESTTRIP_PASSWORD=replace-me
KSKILL_KOSIS_API_KEY=replace-me
LAW_OC=replace-me
KIPRIS_PLUS_API_KEY=replace-me
AIR_KOREA_OPEN_API_KEY=replace-me
KSKILL_PROXY_BASE_URL=

서울 지하철 도착정보와 한국 날씨 조회는 KSKILL_PROXY_BASE_URL 이 없거나 비어 있으면 기본 hosted proxy(k-skill-proxy.nomadamas.org)를 쓰므로 사용자 쪽 키가 불필요하다. 미세먼지, 한강 수위, 주유소 가격, 한국 주식 정보 조회, 의약품 안전 체크, 식품 안전 체크도 기본 hosted proxy를 쓴다. 생활쓰레기 배출정보는 k-skill-proxy/v1/household-waste/info 라우트를 거쳐 serviceKey만 proxy 서버에서 주입하므로 사용자 쪽 키가 불필요하다.

Missing secret handling policy

인증이 필요한 스킬에서 필요한 값이 없으면 우회하지 않는다.

  • 어떤 값이 비어 있는지 정확한 환경변수 이름으로 사용자에게 알려준다
  • credential resolution order에 따라 확보한다
  • 대체 사이트, 대체 API, 하드코딩 같은 우회 경로를 찾지 않는다
  • 시크릿이 없다는 이유로 다른 서비스나 비공식 우회 수단을 자동 채택하지 않는다

Forbidden patterns

  • 실제 비밀값이 들어있는 파일을 git에 두기
  • 스킬 문서 안에 예시용 실비밀번호를 쓰기
  • 시크릿이 없다는 이유로 다른 서비스나 비공식 우회 수단을 자동 채택하기

Threat model

  • ~/.config/k-skill/secrets.env는 plain dotenv 파일이다
  • 파일 퍼미션 0600으로 같은 머신의 다른 유저로부터 보호한다
  • .gitignore로 git 노출을 방지한다
  • 에이전트는 이 파일을 읽고 쓸 수 있다 — 이것은 의도된 동작이다
  • OpenClaw/에이전트 환경에서 유저는 에이전트에게 credential을 위임하는 것을 전제로 사용한다

Standard variable names

  • KSKILL_SRT_ID
  • KSKILL_SRT_PASSWORD
  • KSKILL_KTX_ID
  • KSKILL_KTX_PASSWORD
  • KSKILL_FORESTTRIP_ID
  • KSKILL_FORESTTRIP_PASSWORD
  • KSKILL_KOSIS_API_KEY
  • LAW_OC
  • KIPRIS_PLUS_API_KEY
  • AIR_KOREA_OPEN_API_KEY
  • KRX_API_KEY
  • KSKILL_PROXY_BASE_URL

LAW_OCkorean-law-mcp 가 법제처 Open API 를 호출할 때 쓰는 표준 변수명이다. 이 값은 로컬 CLI/로컬 MCP server 경로에서만 사용자 쪽에 필요하고, upstream remote MCP endpoint 예시는 사용자 LAW_OC 없이 url만 등록한다. DATA_GO_KR_API_KEY 는 프록시 운영자 문맥에서만 서버에 넣는다. 부동산 실거래가 조회는 기본 hosted proxy(k-skill-proxy.nomadamas.org)를 경유하므로 사용자 쪽 키가 불필요하다. 생활쓰레기 배출정보 조회는 k-skill-proxy/v1/household-waste/info 라우트를 거쳐 serviceKey(DATA_GO_KR_API_KEY)를 proxy 서버에서 주입하므로 사용자 쪽 키가 불필요하다. 의약품 안전 체크도 k-skill-proxy/v1/mfds/drug-safety/lookup 라우트를 거쳐 DATA_GO_KR_API_KEY 를 proxy 서버에서만 주입하므로 사용자 쪽 키가 불필요하다. 식품 안전 체크는 k-skill-proxy/v1/mfds/food-safety/search 라우트를 거쳐 DATA_GO_KR_API_KEY 및 선택적 FOODSAFETYKOREA_API_KEY 를 proxy 서버에서만 주입하므로 사용자 쪽 키가 불필요하다. 한국 주식 정보 조회도 기본 hosted proxy를 경유하므로 사용자 쪽 KRX_API_KEY 가 불필요하다. KRX_API_KEY 는 self-host proxy 운영자 문맥에서만 서버에 넣는다. 근처 가장 싼 주유소 찾기는 기본 hosted proxy를 경유하므로 사용자 쪽 OPINET_API_KEY 가 불필요하다. OPINET_API_KEY 는 프록시 운영자 문맥에서만 서버에 넣는다. KIPRIS_PLUS_API_KEY 는 한국 특허 정보 검색 helper가 KIPRIS Plus Open API에 보낼 ServiceKey 값을 담는 표준 변수명이다. 공공데이터포털에서 복사한 percent-encoded key도 helper가 한 번 정규화한 뒤 요청한다. public 공유용 Cloudflare Tunnel/Auth0/operator secret은 사용자 기본 secrets 파일에 넣지 않는다. 프록시 운영자 문맥에서는 upstream 환경변수 SEOUL_OPEN_API_KEY, KMA_OPEN_API_KEY, AIR_KOREA_OPEN_API_KEY, HRFCO_OPEN_API_KEY, OPINET_API_KEY, DATA_GO_KR_API_KEY, FOODSAFETYKOREA_API_KEY, KRX_API_KEY 를 사용할 수 있다. 다만 일반 사용자/client 쪽 기본 secrets 파일에는 넣지 않는다. KSKILL_PROXY_BASE_URL 은 별도 self-host proxy를 쓸 때만 넣는다. 서울 지하철, 한국 날씨, 미세먼지, 한강 수위, 주유소 가격, 한국 주식 정보 조회, 의약품 안전 체크, 식품 안전 체크는 이 값이 없거나 비어 있으면 기본 hosted proxy(k-skill-proxy.nomadamas.org)를 사용한다.

이 레포의 credential-bearing skill은 전부 이 정책을 전제로 작성한다. 자세한 공통 설치 절차는 공통 설정 가이드를 본다.