마켓플레이스 publish 범위 (#2710)
MCP 도구 마켓플레이스에서 무엇을 게시할 수 있고 누구에게 보이는지를 통제하는 설정의 운영 가이드입니다.
이 기능 이전에는 publish 게이트가 카탈로그 단위라 iceberg·gendpg 전체가
허용이었습니다. 내부 PG 메타데이터(gendpg.public.data_grants)까지 게시 가능했고,
tenant/public 이 코드상 동의어라 publish 한 번이 곧 전 워크스페이스 공개였습니다.
ADR-0032 참조.
무엇이 언제 적용되는가
| 통제 | 설정 | 기본 동작 |
|---|---|---|
| publish 대상 스키마 | GEND_MCP_PUBLISHABLE_SCHEMAS | iceberg.silver 만 허용 |
| public(전 워크스페이스) publish 허용 | GEND_MARKETPLACE_PUBLIC_PUBLISH_ENABLED | true (온프렘 기준) |
| ws-fenced 도구 | 없음 | 항상 거부 (#2289 I5) |
| raw_sql 도구 | 없음 | 항상 거부 (실제 SQL 이 사설 테이블을 읽을 수 있음) |
| 등록된 DataMart 출력 | 없음 | 항상 거부 (스키마와 무관) |
설정
GEND_MCP_PUBLISHABLE_SCHEMAS
catalog.schema CSV. 공백·대소문자 무관, 빈 토큰은 무시합니다.
- 기본값
iceberg.silver— ★ 이 근거는 스키마의 일부에만 성립합니다 (#3196). intel silver asset (intel_ohlcv_minute·intel_trades) 은workspace_id를 sentinel 0 으로 넣어 전사 공유가 코드로 확인되지만, 같은 스키마의lng_operating_event·demo_customers는workspace_id컬럼 자체가 없습니다 — "전사 공유임이 확인된" 것이 아니라 태깅이 없는 것이고, 둘은 다른 상태입니다. 사설 데이터 탐지기(ws_fenced_col) 는 컬럼이 없는 테이블을 구조적으로 판정할 수 없으므로, 그런 테이블은 부재를 안전으로 오독한 채 통과합니다. 현재 점유 데이터가 합성이라 실노출은 없습니다. → allowlist 에 스키마를 추가하기 전에 그 스키마의 모든 테이블을 확인하세요. - ★★ ws-stamped 탐지기는 bronze 전용입니다 —
_WS_STAMPED_FQN_RE가^iceberg\.bronze\.intel_라서,iceberg.silver.intel_*는workspace_id컬럼을 가지고 있어도 ws-stamped 로 인식되지 않아ws_fenced_col이 요구되지 않습니다. 지금 무해한 이유는 그 행들이 전부 sentinel 0(전사 공유)이기 때문이며, 코드가 아니라 데이터 상태가 안전을 지탱하고 있습니다. #3194 가 silver 를 소유 ws 기반으로 바꾸면 그 전제가 깨지므로, 그 변경은 이 정규식 확장을 반드시 동반해야 합니다. - 빈 값이면 전량 거부입니다(fail-closed). 조용히 전량 허용으로 뒤집히지 않습니다.
- 3-세그먼트 FQN 이 아니면 거부합니다 — 스키마를 확정할 수 없으면 워크스페이스 사설 여부를 판정할 수 없기 때문입니다.
GEND_MCP_ALLOWED_CATALOGS 와 혼동하지 마세요그것은 도구 실행 allowlist 입니다. 좁히면 publish 는 그대로인 채
돌고 있는 Trino 도구가 죽습니다(build_trino_sql 이 ValueError).
publish 범위를 조정할 때는 반드시 GEND_MCP_PUBLISHABLE_SCHEMAS 를 쓰세요.
GEND_MARKETPLACE_PUBLIC_PUBLISH_ENABLED
| 배포 형태 | 권장 | 이유 |
|---|---|---|
| 온프렘 (단일 고객사 사내) | true | 부서 간 위임이 정상 시나리오 |
| SaaS (고객사 동거) | false | 크로스 테넌트 publish 자체를 422 로 차단 |
false 여도 tenant publish 는 허용됩니다.
노출 범위 — tenant vs public
GenD 는 Workspace 가 곧 테넌트인 flat 모델이므로:
| 값 | 노출 |
|---|---|
tenant (기본) | 소스 워크스페이스 내부 — 다른 워크스페이스에 보이지 않음 |
public | 전 워크스페이스가 검색·구독 가능 |
판정은 단일 상수 EXPORTED_VISIBILITIES 에서만 파생되어 네 곳(마켓플레이스 목록,
구독 조회, MCP 디스패처 2곳)에 동일 적용됩니다.
public → tenant 강등 시 기존 구독은 회수되고 구독자 guest grant 도 삭제됩니다.
기본값이 tenant 입니다. 다른 워크스페이스에 공개하려면 public 을 선택하세요.
메트릭
| 메트릭 | 라벨 | 의미 |
|---|---|---|
gend_mcp_marketplace_publish_total | visibility, result | publish 시도 결과 |
result ∈ published / rejected_target(스키마 allowlist) / rejected_raw_sql /
rejected_public_disabled / rejected_datamart.
모든 라벨 조합이 기동 시 0 으로 사전 생성됩니다 — 시계열 부재와 "0건"을 구분하기 위해서입니다.
allowlist 확대 절차
- 관측 —
gend_mcp_marketplace_publish_total{result="rejected_target"}를 확인합니다. 0 이면 현재 allowlist 가 실사용을 막고 있지 않다는 뜻입니다. - 대상 스키마가 워크스페이스 사설이 아님을 확인합니다. 판단 기준:
- 해당 스키마의 테이블에
workspace_id컬럼이 있고 값이 워크스페이스별로 다르면 사설입니다. - DataMart 출력 스키마는 등록 조회로 이미 차단되지만, 확대 전 직접 확인하세요.
- 해당 스키마의 테이블에
- 확대
kubectl --context aks-genos-prod -n gend set env deploy/gend-api \GEND_MCP_PUBLISHABLE_SCHEMAS="iceberg.silver,iceberg.<추가>"kubectl --context aks-genos-prod -n gend rollout status deploy/gend-api
- 재확인 —
rejected_target이 멈추는지 봅니다.
롤백은 같은 명령으로 이전 값을 되돌리면 됩니다. DB 변경이 없어 즉시 복구됩니다.
kubectl set env 는 Deployment pod template 을 바꿉니다이후 ConfigMap apply 로 되돌아가지 않습니다 — 값의 정본이 둘이 되므로,
영구 설정이라면 infra/helm/gend-api/configmap.yaml 에 반영하세요.
커버리지와 한계
커버: MCP 도구 마켓플레이스의 publish·목록·구독·디스패치 경로.
이 모델을 타지 않는 공유 채널 (고객 문서에 "모든 공유는 명시 동의"라고 쓰면 안 되는 이유):
iceberg.silverintel 자산 —workspace_idsentinel 0(전사 공유 fact)입니다. 이 표현의 UUID 통일은 #3194.iceberg.silver비-intel 테이블 —workspace_id컬럼이 없어 어떤 워크스페이스 펜스도 적용되지 않습니다 (#3196).
:::note 닫힌 채널 (이력)
종전 이 목록에 있던 "intel Fact 테이블 — workspace_id IS NULL 이 전사 공유" 항목은
ADR-0035 D-1 로 닫혔습니다(#3190 — PG intel
테이블 workspace_id NOT NULL + prod ALTER 적용). NULL 행이 존재할 수 없으므로 "NULL =
전 워크스페이스 가시" 경로가 사라졌습니다. 이 문서를 예전에 읽고 그 문구를 기억하는
운영자를 위해 삭제가 아니라 이력으로 남깁니다.
:::
- 온톨로지 L1~L3 — DB CHECK 제약이
workspace_idNULL 을 강제합니다. - 카탈로그 트리 — 워크스페이스 필터가 없어 전면 공유입니다.
- ArangoDB 그래프(glossary/lineage/documents) — 워크스페이스 필터 0건입니다.
미커버:
- 유향 2단 동의(제공자가 수신 워크스페이스 지정) — 후속.
- 구독 해지 엔드포인트 — 현재 구독자가 스스로 끊을 경로가 없습니다.
- 플랫폼 admin 의 워크스페이스 스코프 전면 우회 — D2(break-glass) 영역.
- CSV 적재가 만든 Iceberg 테이블의 워크스페이스 귀속 표시 — 물리 행에 표시가 없어 스키마 allowlist 로만 방어됩니다.