본문으로 건너뛰기

ADR-0043: 개인 트래킹 키 — per-user Keycloak client 셀프서비스

배경

ADR-0038 로 외부 학습 서버가 표준 mlflow SDK 로 GenD 에 로깅할 수 있게 됐지만, 자격증명 트랙이 실사용에서 갈라졌습니다:

  • M2M 서비스 클라이언트 — 발급 API 전 핸들러가 require_admin. 개인 DS 는 admin 에게 요청해야 키를 받습니다.
  • 개인 SSO (gend auth login) — 셀프서비스지만 prod 실측 ssoSessionMaxLifespan=36000 (10시간) 에 걸립니다. 메트릭을 계속 쏘면 idle(30분)은 갱신되지만 세션 최대 수명은 갱신되지 않아, 10시간을 넘는 학습은 중간에 로깅이 죽습니다. 며칠짜리 LLM 학습이 정확히 여기 걸립니다.

wandb 는 이 문제를 개인 API 키(만료 없음, 설정 화면에서 복사)로 풉니다. 사용자 요구도 동일했습니다 — "개인이 키를 발급해서 코드에 넣을 수 있어야 한다."

결정

개인 키의 실체 = 사용자당 Keycloak confidential client.

ADR-0038 결정 5 — "만료 없는 자체 API 키 체계는 도입하지 않는다(Keycloak 단일 자격증명 원천 유지)" — 는 유지합니다. 발급물이 Keycloak client 이므로 자체 토큰 저장소·서명·검증 코드가 전혀 없고, 폐기 = client 삭제 = 즉시 무효화입니다. "자체 키 체계"가 아니라 기존 M2M 트랙의 셀프서비스 확장입니다.

  1. POST /api/v1/me/tracking-credentials — 인증된 사용자 본인이 발급 (admin 불필요). client_id 는 서버가 생성 (gend-user-<username>-<hex>), secret 은 응답에서 1회만 노출.
  2. 소유권 = client attribute gend.owner=<sub> — 목록/회전/폐기의 유일한 근거. 미존재와 타인 소유를 모두 404 로 응답해 키 인벤토리 열거를 막는다.
  3. 워크스페이스 바인딩은 본인 멤버십 안에서만 — JWT workspace_slugs (Keycloak groups 파싱) 검증, 위반 시 403 fail-closed. admin 발급 API 가 임의 slug 를 받는 것과 다른 점 — 개인 셀프서비스는 타 워크스페이스로의 태깅 쓰기 경로가 되면 안 된다.
  4. 감사 귀속 — hardcoded-claim gend_user=<username> 매퍼를 부착해, 이 키로 들어온 요청이 감사 로그에서 개인으로 귀속된다 (기존 M2M 은 클라이언트 이름까지만).
  5. 쿼터: 사용자당 활성 키 상한 (기본 5, GEND_PERSONAL_TRACKING_KEY_QUOTA).
  6. role 은 analyst 고정 — 개인 키로 권한을 셀프 상승시킬 수 없다.

자격증명 3트랙 (최종)

트랙대상발급수명
개인 트래킹 키 (이번)개인 학습 서버셀프서비스무기한 (폐기 시까지)
M2M 서비스 클라이언트팀 공용·CIadmin무기한
SSO (gend auth login)대화형·단기셀프서비스세션 10h

기각한 대안

  • 자체 PAT 테이블 — ADR-0038 결정 5 정면 위반. 토큰 검증 코드·저장소·회전 로직을 GenD 가 떠안는다.
  • offline_access 토큰 — Keycloak 정합성은 좋지만 "복사할 키" 가 없어 학습 서버에서 로그인해야 하고(wandb UX 아님), gend-cli 클라이언트에 offline_access 스코프도 없다(prod 실측). 보완재로 후속 검토는 가능.
  • admin 발급 완화(모두에게 service-clients 개방) — 이름 공간·role 선택·타 ws 바인딩까지 개방되어 경계가 사라진다. 개인 트랙은 서버가 이름을 만들고 role 을 고정하는 별도 표면이어야 한다.

결과

  • 플러그인/resolver/프록시 변경 0 — 발급된 키는 기존 GEND_CLIENT_ID/SECRET 경로를 그대로 탄다.
  • UI 발급 패널은 #3018, 사용자 가이드는 #3021.
  • admin 은 기존 /admin/service-clients 목록에서 gend-user- prefix 로 개인 키를 볼 수 있다 (비상 폐기 경로).