VDB
EN

API

VDB REST API 사용 가이드.

API 개요

VDB는 OSV 호환 취약점 데이터베이스에 AI 시대 시그널(슬롭스쿼팅·MCP 서버·모델 아티팩트)을 더한 공개 API를 제공합니다. 모든 응답은 JSON이며 UTF-8로 인코딩됩니다.

Base URLhttps://vdb.ai.kr
버전/v1/
콘텐츠 타입application/json
OpenAPIopenapi.json

인증 정책

모든 엔드포인트는 인증 없이 호출 가능하지만 IP당 누적 10회까지입니다. 그 이후엔 무료 API 키를 받으세요(에이전트가 이메일로 요청 가능 — 아래 참고). 인증 호출은 IP가 아니라 계정 단위로 집계되므로, 공유 출구(AI 제공자·사무실 NAT·학교망) 뒤의 사용자끼리 서로 제한하지 않습니다. 검색엔진 크롤러는 제한 대상이 아닙니다.

영역인증예시
읽기·검색·조회noneGET /v1/vulns/{id} · GET /v1/search
AI 시그널 (read·bulk check)noneGET /v1/ai/slopsquatting
SBOM 스캔nonePOST /v1/sbom/scan
버그 리포트 (계정 연결)API 키POST /v1/bug-reports
관리자API 키 + is_admin/v1/admin/*

트래픽 한도 / 부정사용 방어

VDB는 정상 사용은 거의 신경 안 쓰고, 봇/스크래핑/burst 공격만 잡도록 한도를 잡았습니다. 정상 사용자가 한도에 닿는 일은 거의 없도록 설정했고, 그 이상으로 트래픽이 튀면 그건 거의 항상 자동화입니다.

1) 무인증 — IP당 누적 10회 (영구)

Authorization 없이 호출하면 IP당 누적 10회까지만. 월별 리셋 없음 — 일회성 trial입니다. 11회째부터 429이며, 그 본문이 에이전트에게 이메일로 무료 키를 받는 법(POST /v1/auth/request-key)을 안내합니다. Authorization: Bearer vdb_…를 보내면 그때부터 IP가 아니라 계정 단위로 집계됩니다.

2) 분 / 시간 / 일 윈도우 한도

호출은 분·시간·일 롤링 윈도우로 제한되며, 축은 신원에 따라 하나만 적용됩니다: 익명 트래픽은 IP당, 인증 트래픽은 계정당. 분 윈도우가 핵심 — 봇은 분당 수백 호출을 하기 때문에 시간/일 한도에 닿기도 전에 잡힙니다. 정상 사용자(AI 에이전트·CI burst·일반 개발)는 모두 한도 안에서 동작합니다. 페이지 열람과 검색엔진 크롤은 집계 대상이 아닙니다.

범위분당시간당일당env
IP당 (익명)
공유 출구(egress) 친화
601,0008,000VDB_RL_IP_PER_MIN
VDB_RL_IP_PER_HOUR
VDB_RL_IP_PER_DAY
계정당 (vdb_ 키 호출)
내 키, 내 한도
1203,00020,000VDB_RL_USER_PER_MIN
VDB_RL_USER_PER_HOUR
VDB_RL_USER_PER_DAY

참고: 정상 사용 시나리오 대비 한도 — AI 에이전트 코딩 세션은 평균 분당 5~10회, 시간당 30~100회입니다. IP 분당 한도는 300 — 많은 익명 사용자를 나르는 AI 제공자 공유 출구가 스크래퍼로 오인되지 않도록 잡았습니다. SBOM 1000개 패키지 풀스캔은 1회 호출입니다. 한 호스트가 1분 내내 5 RPS 이상을 유지하면 그때 걸리며, 인증된 헤비 사용자는 같은 IP의 이웃이 아니라 자기 계정 한도로만 제한됩니다.

3) 차단 정책

분 초과 → 10분 차단 (burst), 시간 초과 → 1시간 차단, 일 초과 → 24시간 차단. 응답: 429 + 본문에 reason·axis·expires_at(익명 429엔 request-key URL도 포함). 차단은 집계 대상 호출에만 적용됩니다 — 페이지 열람이나 크롤은 거부하지 않으며, IP 차단이 같은 네트워크의 인증 계정에 영향을 주지 않습니다.

4) 429가 에이전트에게 할 일을 알려줌

한도에 걸리면 429 본문이 머신이 바로 처리할 수 있는 형태입니다: reason·axis·signup_url, 그리고 익명 호출엔 request_key_url, 더해 호출자 언어로 된 사람용 message. AI 에이전트가 이를 읽고 사용자에게 이메일을 받아 /v1/auth/request-key로 POST하면 — 키가 메일로 발송되어 대시보드 방문 없이 계속 진행할 수 있습니다.

5) 관리자 수동 차단

관리자가 /admin/blocks 페이지에서 특정 IP/계정을 수동 차단 가능. reason manual로 기록.

첫 호출

인증 없이 누구나 시도할 수 있는 가장 간단한 호출:

curl https://vdb.ai.kr/v1/vulns/GHSA-29mw-wpgm-hmr9

패키지 단위 조회:

curl -X POST -H "Content-Type: application/json" \
  -d '{"package":{"purl":"pkg:npm/lodash"},"version":"4.17.20"}' \
  https://vdb.ai.kr/v1/query

API 키 발급

  1. **이메일로 (비밀번호 불필요):** `POST /v1/auth/request-key` 에 `{"email":"you@example.com"}`. 키는 응답이 아니라 해당 이메일로 전송됩니다 — 대신 호출하는 AI 에이전트는 키를 보지 못합니다. 레이트리밋 429가 에이전트에게 안내하는 경로입니다.
  2. **비밀번호로:** 회원가입 — 이메일·비밀번호. 첫 키가 한 번 표시되고 내 계정에서 키를 관리합니다.
  3. 이메일로 계정을 만들었다면, 그 메일의 링크에서 웹 로그인 비밀번호를 설정하세요(또는 새 링크 요청). 키는 그와 무관하게 계속 유효합니다.

Bearer 헤더

키는 Authorization 헤더에 담아 보냅니다:

Authorization: Bearer vdb_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

curl 예시:

curl -H "Authorization: Bearer vdb_xxxxx" \
  https://vdb.ai.kr/v1/auth/me

키 관리 / 폐기

/account 페이지에서:

  • 새 키 발급 (이름 메모 가능)
  • 발급된 키 목록 (prefix · 최근 사용 시각)
  • 개별 키 폐기 (즉시 무효)

API로도 가능:

# new key
POST /v1/auth/keys/new
{ "name": "ci" }

# list
GET  /v1/auth/keys

# revoke
POST /v1/auth/keys/revoke
{ "key_id": "<uuid>" }

인증 API (signup/login/verify)

웹 UI가 사용하는 인증 라이프사이클의 wire-level 엔드포인트. SDK·CLI에서 직접 호출할 때 형태를 확인할 수 있도록 노출. 가입은 이메일 인증이 필수입니다.

# Get a free key BY EMAIL — no password needed. The funnel the 429 points
# agents to. The key is emailed to the address; it is NEVER in the response.
# Generic 200 either way (anti-enumeration).
POST /v1/auth/request-key
{ "email": "you@example.com", "email_consent": true }

# Set a web-login password via the single-use link from that email.
POST /v1/auth/set-password
{ "token": "<from the email link>", "password": "..." }

# Sign up WITH a password — sends a verification email (mandatory).
POST /v1/auth/signup
{ "email": "you@example.com", "password": "...", "email_consent": true }

# Click the link in the email → web app calls this:
GET  /v1/auth/verify?token=<token>          # one-time; mints the first API key

# Resend the verification email (anti-enumeration: same 200 either way).
POST /v1/auth/resend-verification
{ "email": "you@example.com" }

# Log in → sets a web session cookie. Use Bearer + an API key for programmatic.
# A passwordless (email-funnel) account gets 403 password_not_set until it
# sets one via /v1/auth/set-password.
POST /v1/auth/login
{ "email": "you@example.com", "password": "..." }

# Which accounts share this IP? Read-only audit signal. Returns { ip_hash, binding }.
GET  /v1/auth/ip-binding

IP가 아니라 계정 단위 집계 — 인증 호출은 키(계정)로 집계되므로, AI 제공자·사무실 NAT 같은 공유 출구 뒤의 사용자끼리 서로 제한하지 않습니다. 키가 없으면 IP당 무료 체험 10회 후 /v1/auth/request-key로 이메일 키를 받으세요. (예전의 "IP 1:1 바인딩 + 7일 cooldown" 강제는 공유 출구와 충돌해 기본 비활성화되었습니다.)

취약점 조회

단일 조회

GET /v1/vulns/{id}

VDB ID·CVE-ID·GHSA-ID·EUVD-ID 모두 가능. 응답은 OSV 1.6 + vdb_signals 확장.

패키지로 매칭 (OSV 호환)

POST /v1/query
{
  "package": { "purl": "pkg:npm/lodash" },
  "version": "4.17.20"
}

최근 추가

GET /v1/recent?limit=12

SBOM / 의존성 파일 스캔

업로드한 SBOM·잠금파일·매니페스트를 자동 감지·파싱해서 VDB의 취약점 DB와 매칭합니다. 각 발견 항목에는 업그레이드 명령(Level 1)영향받는 함수 목록(Level 2)이 함께 포함됩니다.

요청

POST /v1/sbom/scan
Authorization: Bearer vdb_xxxxx     # optional — anonymous gets 3 lifetime scans/IP
Content-Type: multipart/form-data

file=@<filename>     # single file, max 20 MB

익명 호출자도 IP당 평생 3회 무료 시도 가능 (실제 락파일로 응답 셰이프 확인용). 소진 후엔 401 + signup_url이 응답에 들어옵니다 — /signup에서 무료 키 발급 시 즉시 무제한 사용 가능. check-packages의 10회/IP보다 빡빡한 이유: SBOM은 파일 파싱 + 대량 vuln JOIN으로 호출당 비용이 훨씬 높습니다.

자동 감지 포맷:

  • CycloneDX (JSON/XML), SPDX 2.3+ JSON
  • npm: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml
  • Python: requirements.txt, Pipfile.lock, pyproject.toml
  • Go: go.mod, go.sum
  • Rust: Cargo.lock · Ruby: Gemfile.lock · PHP: composer.lock
  • Dart / Flutter: pubspec.yaml, pubspec.lock
  • Excel (.xlsx) · CSV/TSV (헤더 자동 감지)

호출 예시

curl -H "Authorization: Bearer $VDB_API_KEY" \
     -F file=@package-lock.json \
     https://vdb.ai.kr/v1/sbom/scan

응답 (200 OK)

{
  "sbom_format":         "package-lock.json",
  "components_total":    127,
  "components_matched":   14,
  "components_covered":   23,
  "components_unknown":  104,
  "coverage_ratio":      0.181,
  "summary": {
    "critical": 1, "high": 5, "medium": 8,
    "low": 0, "none": 0,
    "kev": 2, "slop": 0
  },
  "vulnerabilities": [
    {
      "id":              "GHSA-29mw-wpgm-hmr9",
      "purl":            "pkg:npm/lodash",
      "version":         "4.17.20",
      "summary":         "Command injection in lodash",
      "severity_bucket": "high",
      "severity_score":  7.4,
      "fixed_in":        ["4.17.21"],
      "kev":             false,         // CISA Known-Exploited list membership
      "epss":            0.00073,       // FIRST.org 30-day exploit probability (0..1)
      "slop_risk":       null,

      // ── Level 1 — copy-pasteable upgrade hint ──────────────
      "remediation": {
        "type":      "upgrade",
        "ecosystem": "npm",
        "name":      "lodash",
        "fixed":     "4.17.21",
        "command":   "npm install lodash@4.17.21",
        "manifest":  "\"lodash\": \"^4.17.21\"",
        "rationale": "Upgrade lodash to 4.17.21 or newer via npm."
      },

      // ── Level 2 — function-level impact ───────────────────
      "affected_functions": [
        { "path": null, "symbol": "template" },
        { "path": null, "symbol": "templateSettings" }
      ]
    }
  ],

  // ── Anon trial counter (omitted entirely when authenticated) ──
  "trial": {
    "used":      1,           // count BEFORE this call: now 1/3 consumed
    "limit":     3,           // lifetime per source IP
    "remaining": 2,
    "reset_at":  null         // lifetime quota — never resets
  }
}

필드 설명

필드설명
sbom_format자동 감지된 입력 포맷 (예: cyclonedx-json, package-lock.json).
components_total / components_matched전체 구성요소 수 / 그 중 취약점 매칭된 패키지 수.
components_covered / components_unknown / coverage_ratioVDB가 인식하는 컴포넌트(취약점·MCP·모델·데이터셋 집합) 수 / 미인식 수 / 비율. 0.2 미만이면 "검증된 부분 집합만 반영" 임을 사용자에게 알리세요 — 안전 신호가 아닙니다.
summary발견된 취약점의 심각도 분포 + KEV/slop 카운트.
vulnerabilities[].severity_bucketcritical / high / medium / low / none. CVSS v3 + GHSA 폴백으로 계산.
vulnerabilities[].kev / .epssKEV(CISA Known Exploited Vulnerabilities — boolean) + EPSS(FIRST.org 30일 익스플로잇 확률, 0..1, 매일 갱신). kev=true면 CVSS 점수와 무관하게 즉시 패치 대상 — 게이트는 자동 거부 신호로 사용. EPSS≥0.5도 같은 처리. 둘 다 매일 새벽 KST 14:25 (UTC 05:25)에 ai_signals 테이블에 업서트되며, 응답에는 그 결과만 LEFT JOIN 으로 합쳐 보냅니다.
vulnerabilities[].fixed_inOSV affected[].ranges에서 추출한 모든 fixed 버전 (중복 제거).
vulnerabilities[].remediation생태계별 업그레이드 가이드. 객체이거나 null.
.type"upgrade"또는"no-fix-available". 후자는 OSV에 fixed 마커가 아예 없는 경우.
.fixed권장 최소 업그레이드 버전. fixed_in 중 가장 낮은 값을 사용.
.command셸에 그대로 붙여 실행할 수 있는 명령. 미지원 생태계는 null.
.manifestlockfile/manifest에 들어갈 한 줄 (PR 자동화에 유용).
.rationale한 줄 설명 (UI 인라인 표시용).
vulnerabilities[].affected_functionsOSV의 ecosystem_specific / database_specific에서 추출한 영향 함수 목록. 항목 형식: { path, symbol }. path는 Go vulndb처럼 import 경로를 기록하는 생태계에서만 채워집니다. 빈 배열이면 advisory가 함수 단위 정보를 제공하지 않은 것.
vulnerabilities[].slop_risk슬롭스쿼팅 위험 등급 (high/medium/low) 또는 null.

권장 사용 패턴

CI에서 PR 단위 스캔을 자동화하려면 응답의 summary.critical + summary.high가 0보다 클 때 머지를 차단하고, vulnerabilities[].remediation.command를 PR 본문에 그대로 인용하세요. affected_functions가 비어있지 않다면 grep을 돌려 실제 호출이 있는지 확인하는 단계를 한 번 더 끼우는 것이 정확도 향상에 효과적입니다.

에러

  • 400 — 빈 파일 / 파싱 실패 / 잘못된 multipart 페이로드.
  • 413 — 파일 > 20 MB.

AI 시그널 (4-pillar: 패키지·MCP·모델·데이터셋)

0) 자가 발견 매니페스트

AI 도구가 한 번 호출로 모든 엔드포인트·결정 정책·인젝션 가드를 학습할 수 있는 단일 JSON. 프롬프트는 이 URL만 알고 있어도 됩니다.

GET https://vdb.ai.kr/v1/ai/manifest

슬롭스쿼팅 후보 목록

GET /v1/ai/slopsquatting?ecosystem=npm&limit=50

패키지·모델·데이터셋 일괄 체크 (DB + 실시간 레지스트리)

POST /v1/ai/check-packages
{
  "packages": [
    "pkg:npm/%40babel/core@7.24.0",            // exact version (purl, %40 = @)
    "pkg:npm/express@^4.19.2",                 // semver range — server resolves
    "pkg:pypi/requests@>=2.0,<3.0",            // PEP 440 specifier — server resolves
    "pkg:pub/dio@5.4.0",                       // Dart / Flutter via pub.dev
    "pkg:huggingface/BAAI/bge-large-en-v1.5",  // AI model (Hugging Face)
    "pkg:data/squad",                          // training dataset
    "pkg:mcp/anthropic/filesystem"             // MCP server (trust + scopes)
  ],
  "probe_registry": true     // default. false → DB only (skip realtime probe).
}

입력 자동 정규화 — OSV 라벨(pkg:crates.io/..., pkg:rubygems/..., pkg:go/..., pkg:packagist/...)을 보내면 내부에서 purl-spec 표준 (cargo, gem, golang, composer)으로 변환해 매칭합니다. 응답의 input은 원본을, purl은 정규화된 형태를 표시.

각 항목에 대해 (1) 슬롭/모델/데이터셋 DB 매칭 + (2) npm·PyPI·crates·Go·Dart·Hugging Face 레지스트리 실시간 조회를 병렬 수행. 둘 중 하나라도 의심이면 matched=true.

지원 생태계: npm, PyPI, crates.io, Go modules, pub.dev (Dart/Flutter), Hugging Face (모델 + 데이터셋). 버전 슬롯에 정확 버전 또는 범위(^4.19.2, ~1.2, >=2.0,<3.0, 1.2.x, ||) 모두 받습니다. 범위는 npm / PyPI에서 자동 해결되어 resolved_version으로 응답에 표시됩니다. AI 모델·데이터셋 항목은 응답의 model · dataset 필드에 weights_format, license, PII 시그널이 추가로 채워집니다.

{
  "results": [
    {
      "input":              "pkg:npm/express@^4.19.2",
      "purl":               "pkg:npm/express@^4.19.2",
      "version":            "4.21.2",           // what we evaluated against
      "requested_version":  "^4.19.2",          // raw caller input
      "resolved_version":   "4.21.2",           // null if range unresolvable
      "matched":            false,
      "risk":               "low",
      "flags":              [],
      "registry":           { "exists": true, "age_days": 482, "risk_hint": "low" },
      "vulnerabilities":    []
    },
    {
      "input":              "pkg:npm/this-name-does-not-exist@1.0.0",
      "purl":               "pkg:npm/this-name-does-not-exist@1.0.0",
      "matched":            true,
      "risk":               "not_found",                                    // ← new
      "flags":              [],
      "registry": {
        "ecosystem": "npm",
        "name":      "this-name-does-not-exist",
        "exists":    false,
        "risk_hint": "not_found",
        "rationale": "Name does not exist on the npm registry — almost certainly an LLM hallucination. Attackers commonly squat hallucinated names; refuse without explicit user confirmation."
      }
    },
    {
      "input":   "pkg:npm/react-helper-v2@1.0.0",
      "risk":    "high",
      "registry": {
        "exists":    true,
        "age_days":  3,
        "risk_hint": "high",
        "rationale": "Registered only 3 day(s) ago — fresh-registered names that LLMs already recommend are a classic slopsquatting pattern."
      }
    },
    {
      "input":   "pkg:mcp/anthropic/filesystem",
      "purl":    "pkg:mcp/anthropic/filesystem",
      "risk":    "medium",                                  // ← scopes are orthogonal to risk
      "mcp": {
        "trust_tier":  "community",                         // official / partner / community / unverified
        "scopes":      ["fs:read", "fs:write", "exec"],
        "risk_score":  62,
        "risk_notes":  "Holds fs:write + exec — capable of arbitrary code execution on the host.",
        "scope_drift": {                                    // populated only if changed within 90 days
          "added":      ["exec"],
          "removed":    [],
          "changed_at": "2026-05-18T09:32:00Z",
          "previous":   ["fs:read", "fs:write"]
        }
      }
    },
    {
      // Log4Shell — illustrates the KEV + EPSS exploit-evidence signals.
      // vulnerabilities[] entries carry the same kev / epss fields as
      // sbom-scan findings. Array is pre-sorted KEV → EPSS → CVSS so
      // vulnerabilities[0] is always the right one to surface.
      "input":   "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1",
      "purl":    "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1",
      "version": "2.14.1",
      "matched": true,
      "risk":    "high",
      "vulnerabilities": [
        {
          "id":              "GHSA-jfh8-c2jp-5v3q",
          "summary":         "Remote code injection in Log4j (Log4Shell)",
          "severity_bucket": "critical",
          "severity_score":  10.0,
          "fixed_in":        ["2.15.0"],
          "kev":             true,         // CISA-confirmed exploited
          "epss":            0.944         // 94.4% exploit probability (FIRST)
        }
      ]
    }
  ],
  "trial": {
    "limit":     10,           // 10 lifetime calls per source IP (anon only)
    "remaining": 7,
    "reset_at":  null          // lifetime quota — never resets. Sign up to bypass.
  }
}

MCP scope_drift — 권한이 최근 90일 안에 바뀐 경우에만 채워집니다. added가 비어있지 않으면 maintainer-takeover 의심 신호이므로 risk 값과 별개로 사용자 명시 확인이 필요합니다. 채워지지 않으면 null이 아니라 필드 자체가 없습니다.

KEV / EPSS — 익스플로잇 근거 신호. 각 vulnerabilities[] 항목에 kev (boolean, CISA Known Exploited 등재 여부) + epss (0..1, FIRST 30일 익스플로잇 확률)가 붙습니다. kev=true이거나 epss ≥ 0.5면 CVSS bucket과 무관하게 즉시 거부 — "낮은 CVSS인데 실제로 악용 중"인 케이스를 자동으로 잡습니다. 배열은 서버에서 KEV → EPSS → CVSS 순으로 미리 정렬되어 있으므로 vulnerabilities[0]만 봐도 최우선 위협이 잡힙니다.

trial 블록은 익명 호출에만 포함됩니다. reset_at: null일일 한도가 아니라 평생 한도임을 의미하며 — 따로 GET /v1/ai/trial-status로 잔여 호출수만 확인할 수도 있습니다.

익명 재방문 알림 — since_last_visit — 같은 IP에서 지난 30일 안에 점검한 purl 중, 그 이후 새 advisory가 발행된 항목을 알려줍니다. 익명 호출에만 포함, 가입 / 추가 호출 / 별도 워치리스트 등록 모두 불필요. 빈 결과면 필드 자체가 응답에 포함되지 않습니다.
응답 모양: { lookback_days: 30, total_alerts: N, alerts: [{ purl, checked_at, new_vulnerability: { id, summary, modified, severity } }] }

risk 등급별 권장 처리

risk권장 동작
not_found거부. 레지스트리에서 존재 확인 실패 — LLM 환각일 가능성 매우 높음. 사용자에게 "이 이름은 만들어진 이름"이라고 알리고 의도한 실제 패키지를 묻기.
high거부. reason / advisory_url 인용. 더 안전한 대안 제시.
medium경고하고 사용자 명시 동의를 받은 뒤에만 진행.
unknownVDB가 검증을 못 한 상태 (not_found와 다름). 사용자에게 알리고 동의를 받기.
low정상 진행.

MCP 서버 레지스트리

GET /v1/ai/mcp-servers
GET /v1/ai/mcp-servers/{id}     # id = "owner/name" OR "mcp:owner/name" OR "pkg:mcp/owner/name"

권장 — MCP 서버는 /v1/ai/check-packages: 같은 게이트 로직 + scope_drift + 미인증 trial 카운트가 한 응답에 들어옵니다. 직접 GET은 브라우징/디버깅용. 미지의 서버도 404가 아니라 trust_tier: "unverified" + metadata.source: "not_in_registry"로 200 반환되므로 에이전트가 일관되게 처리 가능합니다.

응답 객체는 check-packages 응답의 mcp 필드와 동일한 모양 — trust_tier, scopes, risk_score, 그리고 (해당되면) scope_drift가 포함됩니다.

같은 기능을 MCP 네이티브로도 노출합니다 — Claude Desktop / Cursor 등에서는 vdb/mcp:dev 컨테이너를 stdio MCP 서버로 추가하면 vdb_check_packages, vdb_lookup, vdb_search 등 도구로 바로 호출 가능. 설치 방법은 매니페스트의 mcp_server 필드 참고.

AI 모델 레지스트리 (Hugging Face)

GET /v1/ai/models                       # list / filter by provider, license
GET /v1/ai/models/{purl}                # purl = pkg:huggingface/owner/name

# example
curl https://vdb.ai.kr/v1/ai/models?provider=huggingface&limit=20
curl https://vdb.ai.kr/v1/ai/models/pkg:huggingface/BAAI/bge-large-en-v1.5

Hugging Face 등에서 수집한 모델 카드. weights_format(pickle/safetensors), license, sha256, 다운로드 수, risk_score, risk_notes를 노출. 모델을 다운로드하기 전에 호출하면 코드 실행 위험(pickle)·라이선스 위반·서명 미일치 등을 차단할 수 있습니다.

{
  "id":             "pkg:huggingface/BAAI/bge-large-en-v1.5",
  "display_name":   "BAAI/bge-large-en-v1.5",
  "provider":       "huggingface",
  "framework":      "pytorch",
  "license":        "mit",
  "weights_format": "safetensors",     // pickle | safetensors | gguf | …
  "sha256":         "…",
  "downloads":      1843201,
  "risk_score":     0.05,
  "risk_notes":     null,
  "metadata":       { /* raw HF model-card fields */ }
}

weights_format=="pickle" 인 모델은 로드 즉시 임의 코드를 실행할 수 있습니다 (torch.load gadget chain). safetensors 변종이 있으면 그쪽을 권합니다. licensenon-commercial/research-only/other/null이면 상업 사용 전 검토 필요.

학습 데이터셋 레지스트리

GET /v1/ai/datasets                     # list / filter by provider, license
GET /v1/ai/datasets/{purl}              # purl = pkg:data/name  or  pkg:data/owner/name

# example
curl https://vdb.ai.kr/v1/ai/datasets?provider=huggingface&limit=20
curl https://vdb.ai.kr/v1/ai/datasets/pkg:data/squad

Hugging Face·Kaggle 등에서 수집한 데이터셋 카드. file_formats, license, task, 다운로드 수, risk_score, risk_notes(PII 신호 포함)를 노출. 파인튜닝·재배포·상업적 사용 전 라이선스와 개인정보 위험을 확인하세요.

{
  "id":            "pkg:data/squad",
  "display_name":  "rajpurkar/squad",
  "provider":      "huggingface",
  "task":          "question-answering",
  "file_formats":  "parquet,json",
  "license":       "cc-by-sa-4.0",
  "downloads":     412330,
  "risk_score":    0.10,
  "risk_notes":    null,                 // e.g. "pii:flagged" when HF tags include PII signals
  "description":   "Stanford Question Answering Dataset"
}

버그 리포트 (인증 필요)

POST /v1/bug-reports
Authorization: Bearer vdb_xxxxx
Content-Type: application/json

{
  "title":       "Search result ordering looks off",
  "description": "Repro: ... / Expected: ... / Actual: ...",
  "category":    "ui"
}

카테고리: ui · data · api · suggestion · other

GET /v1/bug-reports/me     # list my reports

메타 / 변경 이력

정적 페이지를 긁지 않고도 빌드 정보·헤드라인 카운트·/changelog 항목·30일 수집 활동을 가져갈 수 있도록 공개된 가벼운 엔드포인트들. 모두 인증 불필요.

GET /v1/version                          # build + commit info
GET /v1/stats                            # headline counts (vulns, mcp, …)
GET /v1/changelog?limit=200              # curated + auto-milestone entries
GET /v1/activity/recent                  # 30-day sanitised collection activity (day × source)

관리자 (is_admin 필요)

모든 관리자 엔드포인트는 Authorization: Bearer + 해당 사용자의 is_admin=true 필요.

GET   /v1/admin/users
PATCH /v1/admin/users/{id}                # { "is_admin": true }
GET   /v1/admin/bug-reports[?status_filter=open]
PATCH /v1/admin/bug-reports/{id}          # status / triage_note
GET   /v1/admin/disclosures[?status_filter=received]
GET   /v1/admin/disclosures/{id}          # PoC included
PATCH /v1/admin/disclosures/{id}          # status / internal_notes / vuln_id
GET   /v1/admin/traffic?hours=24[&source=user|internal|anon]
GET   /v1/admin/collector-runs
GET   /v1/admin/collector-health          # 24h health + watermarks + DB counts
GET   /v1/admin/anon-insights             # funnel + cohort retention + conversion
POST  /v1/admin/changelog                 # { date, tag, title_ko, title_en, body_ko, body_en, visibility? }

Swagger UI

인터랙티브 — 브라우저에서 직접 호출·테스트 가능. 모든 엔드포인트가 그룹 태그(vulnerabilities, sbom, ai-signals, auth, bug-reports, disclosures, admin, meta)로 정리되어 있습니다.

Swagger UI 열기 →

ReDoc

ReDoc 열기 →

OpenAPI 3.1 JSON

curl https://vdb.ai.kr/openapi.json > vdb-openapi.json

에디터 확장 — VS Code · Cursor

API를 직접 호출하기 번거롭다면, 공식 **VDB** 확장이 이 POST /v1/ai/check-packages를 그대로 감싸 편집 중 인라인으로 결과를 보여줍니다. package.json·requirements.txt·Cargo.toml·go.mod·pubspec.yaml이나 MCP 설정을 열거나 저장하면 위험한 의존성에 에디터에서 바로 밑줄이 그어집니다 — 슬롭스쿼팅은 에러로, 알려진 CVE는 한 번에 안전 버전으로 올리는 퀵픽스로.

워크스페이스에서 CycloneDX SBOM을 생성해 한 번에 스캔하고, 각 MCP 서버가 실행하는 npm/PyPI 패키지까지 점검합니다. VS Code·Cursor·Windsurf·VSCodium(Open VSX)에서 동작하며, 소스 코드는 보내지 않고 패키지명·버전만 전송합니다.

Marketplace에서 설치

에러 응답

모든 에러는 다음 형태:

{ "detail": "<message>" }
상태의미
400요청 본문/파라미터 유효성 실패
401Bearer 토큰 누락 또는 무효
403관리자 권한 필요
404리소스 없음
409충돌 (이메일 중복 등)
413업로드 파일 너무 큼 (SBOM > 20MB)
429Rate limit 초과
500서버 에러 (보고해 주세요)