Sentivex CTI
scti.in-bridge.com위협 인텔리전스 조회·집계·상관·역추적 API. IOC 문자열을 받아 단일 verdict 로 응답한다.
72 endpoints · 10 그룹
개요
SCTI 는 임의의 IOC 문자열(해시/IP/도메인/URL/CVE/MITRE/APT/이메일)을 던지면 서버가 타입을 자동 식별해 로컬 TI DB/캐시로 분기 조회하고, 단일 verdict + 매칭 sources[] 로 통일 응답하는 TI 제품입니다. 핵심 데이터 = 원격 PostgreSQL(ioclog·threat_intelligence) + NSRL 72M 정상해시 + OpenSearch(EDR/OCSF). 외부 enrichment(VT/OTX/AbuseIPDB/URLScan/GreyNoise/ThreatFox)는 미탐 지표만 큐로 보강합니다.
| 대상 개발자 | 용도 |
|---|---|
| API 소비 개발자(외부/사내 스크립트) | Bearer 키로 /api/ti/* 조회 — SOAR·스크립트 IOC 판정 자동화 |
| 패밀리 프런트(sentivex-web) | BFF 가 SCTI API 를 소비해 TI 메뉴 화면을 렌더 |
| 운영자(SOC/Ops) | /ops 콘솔(수집 크론·워커 제어) · /osa-simulation(공격 시뮬레이션 실검증) |
API 그룹
스펙 SoT = public/openapi.json (v1.3.0, 55 paths / 72 operations, openapi:check 드리프트 게이트).
| 그룹 | 역할 | 인증 |
|---|---|---|
| TI 소비 API (/api/ti/*) | 통합 lookup · stats · benign/해시 검사 · graph · sightings · correlate · threat-hunter · collection · watchlist · daily-analysis · news · ransomware · 리소스 검색 | Bearer 키 |
| Public-read | 리소스 목록/행 · threat-map GeoIP 집계 · 정상/해시 관리 화면 백킹(읽기) | 무인증 |
| Pipeline | 12노드+HUB 상태 · SSE 스트림 · suspicious-rare | Bearer (스펙 표기는 stale — 라이브 401 실측) |
| Ops · OSA · Auth | 운영 콘솔 · 공격 시뮬레이션 · 세션 — 외부 개발자 대상 아님 | ops_session / Bearer |
인증 3계층 · OIDC
| 계층 | 계약 |
|---|---|
| 공개 TI API 게이트 | Authorization: Bearer <key> (key ∈ TI_API_KEYS 콤마 화이트리스트) — 키 OR ops_session 중 하나면 통과. Effective-scope(ti:read/write/hunt)는 OIDC 사용자만 검사, API 키·레거시 세션은 스코프 무관 통과(#81). 부족 → 403 |
| Ops 콘솔 게이트 | 비밀번호(OPS_ADMIN_PASSWORD) → HMAC 세션쿠키 ops_session (timingSafeEqual 검증) |
| 페이지 게이트(Edge) | PUBLIC_PATHS 외 모든 페이지는 ops_session 없으면 /login?next= 로 307. /api/* 는 matcher 제외(자체 401 JSON) |
OIDC SSO 계약: SCTI 는 IdP 의 OIDC 클라이언트지만 유저별 세션이 없는 단일 공용 ops_session 모델입니다. 콜백은 userinfo entitlements 에 ti-app 포함을 확인해야 접근 허용(보안 게이트), 발급 쿠키 2종 = ops_session(접근) + 서명 ti_id(name/role + effective scopes). 필요 스코프 키 = ti:read(조회) · ti:write(관심IOC/해시/일별분석 쓰기) · ti:hunt(threat-hunter/OSA). suspended → /login?e=suspended. 상단 네비는 IdP 카탈로그 API(GET {issuer}/api/v1/catalog/ti-app/menus) 소비 — 카탈로그 주도.
퀵스타트
키 발급: TI_API_KEYS(콤마 화이트리스트)에 등록된 값을 운영자에게서 받습니다(자가발급 UI 없음 — env 관리). 헤더는 Authorization: Bearer <키>.
curl -X POST https://scti.in-bridge.com/api/ti/lookup \
-H "Authorization: Bearer $TI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"indicators":["8.8.8.8","44d88612fea8a8f36de82e1278abb02f","example.com","CVE-2014-0160","Lazarus"]}'
# → { success, results:[{indicator, detected_type, verdict, sources:[...]}], stats, performance }const res = await fetch("https://scti.in-bridge.com/api/ti/lookup", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ indicators: ["8.8.8.8", "example.com"] }),
});
if (res.status === 401) throw new Error("TI_API_KEY 누락/불일치");
if (res.status === 429) throw new Error("rate limit — 잠시 후 재시도");
const { results } = await res.json();
// verdict ∈ benign | malicious | info | suspicious_rare | unknown | unsupportedcurl -H "Authorization: Bearer $TI_API_KEY" \
"https://scti.in-bridge.com/api/ti/sightings?value=1.193.163.2"도메인 · 포트 · env
| 구분 | 값 |
|---|---|
| 운영 도메인 | scti.in-bridge.com (Cloudflare → .35). 폐기: ti.in-bridge.com(#86) |
| 로컬 개발 | stag-scti.in-bridge.com = 127.0.0.1:6100 (pnpm dev, Turbopack) |
| 배포 | .35:/www/ti-app — standalone server.js(PM2 ti-app), 서버 자체 소스로 pnpm ops:rebuild |
| DB / Redis | PostgreSQL .35:8433/n8n (스키마 ioclog·threat_intelligence) · Redis .35:6379 |
| 인증/세션 env | TI_API_KEYS · OPS_ADMIN_PASSWORD · OPS_SESSION_SECRET · OIDC_ISSUER/CLIENT_ID/CLIENT_SECRET · NEXT_PUBLIC_OIDC_ENABLED |
| OpenSearch env(용도별 분리) | 일반 OPENSEARCH_* · EDR 라이브 OPENSEARCH_K8S_* · 상관(W3) TI_CORRELATION_OPENSEARCH_URL→DEFENDERX_* (미설정 시 ib-guard 폴백 → OCSF finding 0 주의사항) · AWS OCSF TI_AWS_* |
에러 · rate limit
| 코드 | 의미 | 발생 조건 |
|---|---|---|
| 401 | Unauthorized | Bearer 키 없음/불일치 & 세션 없음 — lookup·collection·correlate·pipeline/state 무인증 실측 401 |
| 403 | Forbidden | OIDC 사용자가 필요 스코프 미보유 — {error:'forbidden', scope} |
| 307/308 | Redirect | 게이트 페이지 무인증 접근 → /login?next= |
| 400 | Bad Request | 필수 파라미터 누락(seed·value·indicators 1~1000) |
| 410 | Gone | /api/hybrid-search 폐기 — 인증 통과 시에만 도달(무인증은 401 먼저) |
| 429 | Too Many Requests | rate limit 초과 — Retry-After·X-RateLimit-* 헤더 포함 |
| 502 | Bad Gateway | OSA 어댑터/ocsf-server/dispatch-server 도달 실패 |
Rate limit: 인메모리 슬라이딩 윈도, 기본 100 req/15분/클라이언트(식별 = Bearer 해시 또는 마지막 프록시 IP). 재시작 시 리셋·인스턴스 간 비공유.
주의사항
| # | 주의사항 |
|---|---|
| 1 | 스코프 게이트는 OIDC 유저만 — Bearer 키·레거시 세션은 ti:* 무관 통과(유효 키는 필수) |
| 2 | openapi.json 의 Pipeline/Retired 인증 서술 stale — 라이브 동작(401 우선)이 기준 |
| 3 | 페이지는 전부 게이트 — 스펙만 필요해도 로그인 후 열람 |
| 4 | standalone 배포 정합 — 래퍼가 매 기동 .next/static·public 재복사 + --env-file 주입 + HOSTNAME=0.0.0.0 (안 하면 정적 404) |
| 5 | W3 상관 OCSF finding 0 주의사항 — DEFENDERX_* 미설정 시 ib-guard 로 조용히 폴백. 쿼리 말고 env 교정 |
| 6 | OCSF -latest 동결(2026-06-18) — 쿼리는 -latest,<datastream> + ignore_unavailable 병기 |
| 7 | W2 enrichment 는 best-effort — VT 무료 4/min 등 쿼터로 stall 금지 |
| 8 | IdP 액세스 토큰 만료 짧음(1h 관행) — 브라우저 검증 중 세션 끊길 수 있음 |
| 9 | 워커/크론 로컬 실행 금지 — .35 공유 DB/Redis 큐 중복 처리 |
| 10 | openapi.json 은 손수 유지 — 라우트 변경 시 스펙+TI-Lookup-API.md 동반 갱신(pnpm openapi:check 게이트) |