API Key
API Key는 비대화형 클라이언트(CI 러너·Webhook·스크립트·GitHub Action)를 위한 자격증명입니다. 사용자의 JWT 세션을 소비하지 않고 머신 간 트래픽을 인증합니다.
팀 범위 Key를 발급하는 team_admin, 조직 범위 Key를 발급하는 super_admin.
/integrations UI 로 관리하기
대부분의 사용자는 통합 페이지에서 본인의 Key를 직접 발급·폐기합니다. /integrations UI는 다음을 제공합니다.
- 로그인한 사용자가 관리할 권한이 있는 모든 Key 나열.
- Create 시 1회 노출 모달과 클립보드 복사 버튼, 전체 Key가 단 한 번만 표시된다는 강한 경고.
- 행별 Revoke와 확인 다이얼로그 — 폐기는 ~5초 내에 전파.

생성 다이얼로그는 team_admin과 super_admin이 동일한 화면을 사용합니다. super-admin의 경우 scope 드롭다운에 org가 추가됩니다.

이 페이지는 서버 측 동작 — Key 형태, 해싱, scope 시멘틱, 감사 로그, 회전 전략을 다룹니다. CI에 Key를 연결하기만 하면 되는 사용자는 통합 사용자 가이드에서 멈춰도 됩니다.
Key 형태
tos_<8-char-prefix>_<32-char-secret>
예시: tos_a1b2c3d4_eaff8b91d36c5e0a2f1c4d7e8a9b0c2d.
tos_— 고정 prefix.<8-char-prefix>— 랜덤이며 공개. 조회와 표시 라벨에 사용. 감사 로그에 노출.<32-char-secret>— 랜덤이며 비공개. 서버에는 bcrypt 해시로만 저장. 전체 Key는 운영자에게 생성 시 단 한 번 표시되며 그 이후로는 절대 보이지 않음.
조회는 prefix 전반에서 상수 시간이며, secret 비교는 타이밍 공격을 막기 위해 bcrypt.checkpw를 사용합니다.
Scope 모델
각 Key는 권한 경계를 결정하는 단일 리소스 scope를 가집니다.
org— 조직 전체에서 행위하며, 발급자가 호출할 수 있던 어떤 endpoint 든 호출 가능.team— 특정 팀을 대신해 행위하며, 팀 간 호출은 403으로 실패.project— 특정 프로젝트에 묶이며, 해당 프로젝트 외의 호출은 403으로 실패.
각 scope 발급 권한:
| Scope | 발급 가능 주체 |
|---|---|
org | super-admin 만 |
team | super-admin, team-admin |
project | super-admin, team-admin, developer (소속 팀의 프로젝트 한정) |
Key는 요청 시점에 발급한 사용자의 역할을 상속합니다 — v0.10.0에는 별도의 "effective role"이나 "allowed actions" 목록이 없습니다. 권한 검사는 JWT로 인증된 요청과 동일한 RBAC 코드 경로를 따릅니다.
Key는 **선택적 만료(TTL)**를 지원합니다. 발급 시 expires_in_days(1–1825)를 지정하면 그만큼의 일수가 지난 뒤 인증이 거부됩니다 — 유출된 CI 키(파이프라인 로그, 포크 PR 러너)가 수동 폐기 없이 스스로 만료됩니다. 생략하면 만료 없는 Key(기존 기본값)가 됩니다. CI 키는 TTL을 설정하고 회전하는 것을 권장합니다. 세분화된 allowed_actions taxonomy(scan:trigger, scan:read, report:download, …)는 여전히 로드맵입니다.
curl -sS -X POST "https://trustedoss.example.com/v1/api-keys" \
-H "Authorization: Bearer ${JWT}" -H "Content-Type: application/json" \
-d '{"name": "ci-key", "scope": "project", "project_id": "<uuid>", "expires_in_days": 90}'
Key 발급
Team admin 으로
- /integrations(
team_admin이상 사용 가능한 최상위 사이드바 항목)을 엽니다. - API keys 탭으로 전환.
- New API key 클릭.
- 채우기:
- Label(예:
github-action-checkout-service) - Scope —
team(기본) 또는project - Project — scope가
project일 때 필수
- Label(예:
- Create.
전체 Key는 모달에서 단 한 번 표시됩니다. 복사해 CI 시크릿 저장소(GitHub secrets, GitLab CI variables, Jenkins credentials)에 보관하세요. 모달을 닫으면 UI에서는 prefix만 보이고 전체 Key는 복구 불가입니다.
Super-admin 으로
같은 /integrations 흐름이지만, 팀 경계를 넘는 Key는 scope를 org로 설정할 수 있습니다(드묾 — 대부분의 CI 통합은 team 또는 project scope에 머물러야 함).
API Key 사용
Authorization 헤더에 Bearer 토큰으로 Key를 전달:
curl -sS -H "Authorization: Bearer ${TRUSTEDOSS_API_KEY}" \
https://trustedoss.example.com/v1/projects
포털은 추적성을 돕기 위해 모든 요청에 prefix를 로깅합니다.
회전
회전 사유
- 침해 — Key가 공개 레포에 커밋되었거나 CI 러너가 침해됨. 즉시 폐기.
- 인사 변경 — Key를 발급한 team admin이 떠나는 경우. 새 Key 발급 후 CI 시크릿 교체, 옛 Key 폐기.
- 정책 — 분기별 회전을 심층 방어 조치로 진행.