Sentivex Incidents Ticket

sit.in-bridge.com

SOC 인시던트·HITL 대응 SoR 겸 PM 플랫폼. SEE 가 넘긴 사건을 사람 승인 게이트로 처리한다.

155 endpoints · 33 그룹

개요

SIT 은 Sentivex 제품군의 SOC 인시던트·HITL 대응 SoR(system of record) + PM 앱입니다. 구성은 4프로세스 — Next.js 16 웹앱(SoR/API) + LangGraph 트리아지 워커(별도 기동) + HITL Executor·재분석 스캐너 배치 + SXE WebSocket 구독기.

대상 개발자용도
SXE/XDR 연동 개발자보안 분석 결과(인시던트)를 SIT 으로 인입(push)하고 도착·라우팅 확인
패밀리 BFF 개발자서버간 세션교환으로 자기 세션 사용자를 pm 토큰으로 바꿔 인시던트·티켓을 per-user 소비
SOC 운영·자동화 개발자HITL 결정·SOAR 실행로그·워커 큐를 읽어 관제 파이프라인 연결
SIT 자체 기능 개발자PM/이슈/스프린트/페이지 API 위에 UI·통합 구축

인증

사람 = 쿠키 세션(자체 로그인 또는 패밀리 SSO), 서버 = 계약별 Bearer. SIT 에는 사용자 API 키 발급이 없습니다.

경로누구용
자체 JWT 로그인사람 — 이메일+비밀번호 → httpOnly 쿠키(8시간)
OIDC SSO사람 — 패밀리 IdP(inbridge-auth) 경유, 동일 쿠키 발급
BFF 세션교환패밀리 프런트 서버 — 사용자 신원을 pm 토큰으로 교환
외부 시스템 BearerSXE/XDR — 인입 전용 4라우트

인증 계약 · 스코프 환산

인증 경로계약
자체 JWTPOST /api/auth/login {email,password} → httpOnly token 쿠키 8시간(jwt.ts:47, #130 에서 1h→8h). 로그아웃=블랙리스트
OIDC SSOGET /api/auth/oidc/start → IdP → /api/auth/callback. code→token→userinfo 후 이메일 find/create, 동일 token 쿠키
BFF 교환POST /api/auth/exchange (Bearer BFF_EXCHANGE_SECRET) — email+roles → pm 토큰(roles→pm:* 환산 적재)
외부 BearerAuthorization: Bearer SXE_INGEST_SECRET — /api/external/* 4라우트 전용
perspective(광역 역할)pm:* 스코프
super · tenantpm:read · pm:write · pm:respond · pm:admin
analyst · responderpm:read · pm:write · pm:respond
pmpm:read · pm:write · pm:admin
hunterpm:read · pm:write
ciso · sales · generalpm:read
(미상/guest 폴백)pm:read — 빈 배열 금지(fail-closed)

userinfo 소비 계약(#198): subscription_status=suspended → 로그인 차단(/login?e=suspended); active·trial·grace·클레임 부재=통과. plan 은 메뉴 min_plan enforcement(#197)가 소비 예정. 메뉴/플랜 하드코딩 없음 — auth 카탈로그 API 소비(17메뉴: base 7 / standard 8 / pro 2). 워커 M2M 은 triage:* 스코프(auth client_credentials, #201 운영 매트릭스 통과).

퀵스타트

사람 — 쿠키 세션
# 1) 로그인 → 쿠키 저장 (계정은 ACCOUNTS-MATRIX.md)
curl -c /tmp/sit.jar -X POST https://sit.in-bridge.com/api/auth/login \
  -H 'content-type: application/json' \
  -d '{"email":"<email>","password":"<password>"}'

# 2) 첫 호출 — 내 세션 · 인시던트 5건
curl -b /tmp/sit.jar https://sit.in-bridge.com/api/auth/me
curl -b /tmp/sit.jar 'https://sit.in-bridge.com/api/incidents?projectId=<id>&limit=5'
서버간 — BFF 세션교환 후 pm API 소비 (sentivex-web 실전 패턴)
const ex = await fetch("https://sit.in-bridge.com/api/auth/exchange", {
  method: "POST",
  headers: { "content-type": "application/json",
             authorization: `Bearer ${process.env.BFF_EXCHANGE_SECRET}` },
  body: JSON.stringify({ email, roles }),           // roles → pm:* 환산
});
const { token } = await ex.json();                  // pm 세션 JWT
const incidents = await fetch(
  "https://sit.in-bridge.com/api/incidents?projectId=…&limit=5",
  { headers: { cookie: `token=${token}` } }).then(r => r.json());
외부 시스템(SXE) — 인입 도착 확인(읽기 전용 Bearer)
curl -H "Authorization: Bearer $SXE_INGEST_SECRET" \
  'https://sit.in-bridge.com/api/external/sxe/ingest-status?analysisId=123'

도메인 · 포트 · env

구분
운영 도메인sit.in-bridge.com — .35 pm2 indexpm-web (구 별칭 pm.in-bridge.com 폐기, 2026-07-12 정본화)
로컬 개발stag-sit.in-bridge.com = 127.0.0.1:42000 (pnpm dev, local-nginx TLS)
워커:4200 (FastAPI) — .35 전용 기동. 로컬 기동 금지: 공유 큐 이중처리
필수 envDATABASE_URL · JWT_SECRET(≥16자)
기능 게이트 envSXE_INGEST_SECRET(external 4라우트) · BFF_EXCHANGE_SECRET(세션교환) · LITELLM_API_KEY(AI) · OIDC_CLIENT_ID/SECRET(SSO) — 미설정 = 해당 기능 503/비활성
모드 스위치INDEXPM_OPEN_MODE(무인증 읽기 데모 — dev 기본 ON·production 기본 OFF) · ENABLE_DEV_LOGIN · WORKER_AUTO_ENQUEUE · REMEDIATION_LIVE

에러 · rate limit

에러 응답 포맷: { "error": "<메시지>", "code": "<코드>", "details"? } — auth 의 {success,…} 포맷과 다름(제품별 상이).

codeHTTP의미
BAD_REQUEST / VALIDATION_ERROR / INVALID_JSON400명시 throw / zod 실패(details.issues) / JSON 파싱 실패
UNAUTHORIZED401미인증(토큰 없음·무효·만료 8h)
FORBIDDEN403멤버십·스코프 상한 미달 (IdP 연동 시 APP_SEAT_LIMIT_EXCEEDED 매핑)
NOT_FOUND / CONFLICT / UNPROCESSABLE_ENTITY404/409/422리소스 없음 / 중복 / 의미상 불가
SERVICE_UNAVAILABLE503의존 서비스 다운 — 워커 미기동·시크릿 미설정 게이트 포함
INTERNAL_ERROR500미처리 예외

Rate limit(Redis 슬라이딩 윈도우, Redis 다운 시 fail-open): 로그인 5회/15분(IP) · 회원가입 10회/1시간(IP) · 비밀번호 변경 5회/15분(사용자). 그 외 API 전역 rate limit 없음(2026-07-07 기준).

주의사항

#주의사항
1개발자 표면·스펙 전부 로그인 게이트 — 무인증 크롤/fetch 불가. 스펙은 레포 파일을 읽을 것
2JWT 만료 8시간(1h→8h #130) — "7일" 은 구문서 값(정정됨)
3bare ocsf(vendor 없음) 라우팅 미매칭은 의도(project-routing.ts:39) — 버그 아님
4워커 로컬 기동 금지 — DB/Redis 가 .35 공유라 이중처리. 워커·구독기·스캐너는 .35 전용
5Cloudflare 가 python-urllib 기본 UA 를 403 차단 — .35발 서버간 호출은 커스텀 UA 필수(#201)
6헤더류(CSP 등)는 .35 nginx 까지 봐야 운영 반영 — vhost proxy_hide_header 전례(#64)
7public/ 정적 파일은 proxy dot-우회를 타므로 내부 정보 파일은 GATED_STATIC_PATHS 등재 필수
8verdict 미결 어휘 = inconclusive(DB 저장 어휘 — unknown 은 존재 불가)
9drizzle-kit push 금지(LangGraph checkpoint 테이블 drop) — 컬럼 추가는 멱등 raw SQL
10점수·등급·confidence 사용자 노출 금지(제품군 공통) — 문서 예제에도 금지