🔥 Issue 개요
백엔드에 BYOK(Bring Your Own Key) AI 크리덴셜 API 가 추가된다(Dvely_springboot PR #245, Issue #242). 사용자가 자기 공식 AI API 키를 등록하면, 그 키로 Claude Code / Codex 코딩 에이전트가 격리 컨테이너에서 실행되고 사용량은 사용자 계정으로 직접 청구된다.
FE 는 이 키를 등록·확인·삭제하는 화면이 필요하다. 엔드포인트 3개는 이미 구현·테스트 완료 상태다.
왜 구독 연동이 아닌가 — 구독(Claude Pro/Max, ChatGPT Plus) 자격증명을 제3자 제품에 임베딩하는 것은 Anthropic 이 공식 금지하고 OpenAI 도 지원하지 않는다. 사용자에게 "구독 계정 연결" 로 안내하면 안 되고, "본인 API 키 등록" 이라는 표현이 정확하다.
🎯 목표
✅ 작업 범위
포함 범위
- AI 크리덴셜 관리 UI (목록 / 등록·교체 / 삭제)
AI_CREDENTIAL_NOT_REGISTERED 에러 처리 → 키 등록 화면 유도
- 등록 시 입력 검증 안내(공백·제어문자 포함 키는 400)
제외 범위 (지금 하지 말 것)
CLAUDE_CODE / CODEX 를 AI 제공자 선택지에 노출하지 말 것. 코딩 에이전트는 아직 채팅/CODE 플로우에 배선되지 않은 휴면 상태이고, GET /api/v1/agent/ai-providers 목록에도 나오지 않는다. 지금 선택지로 넣으면 400 이 난다. 배선 완료 시 별도 이슈로 요청한다.
- 사용량·비용 표시 (백엔드 미제공)
📋 API 계약
전부 Authorization: Bearer {accessToken} 필요.
1) 목록 조회
GET /api/v1/ai-credentials
→ 200 [
{
"aiProviderCredentialId": 1,
"provider": "ANTHROPIC",
"maskedApiKey": "sk-ant****",
"label": "개인 계정",
"createdAt": "2026-09-05T10:00:00",
"updatedAt": "2026-09-05T10:00:00"
}
]
본인이 등록한 것만 반환된다(소유자는 토큰에서만 결정되며 요청 파라미터가 없다).
2) 등록 / 교체
PUT /api/v1/ai-credentials/{provider}
{ "apiKey": "sk-ant-api03-...", "label": "개인 계정" } // label 은 선택(nullable, 최대 64자)
→ 200 (위 목록과 동일한 객체 1개)
등록과 교체가 같은 동작이다(PUT). 벤더당 키 하나이므로, 이미 등록돼 있으면 새 키로 교체된다. "이미 등록됨" 409 같은 건 없다 — 유출 직후 교체가 한 번의 호출로 끝나야 하기 때문.
3) 삭제
DELETE /api/v1/ai-credentials/{provider}
→ 204
→ 404 (등록돼 있지 않음)
{provider} 값
벤더만 받는다: ANTHROPIC · OPENAI · GLM
CLAUDE_CODE / CODEX 로 등록을 시도하면 400 이고, 응답 메시지가 어느 벤더로 등록해야 하는지 알려준다. 이유: Claude Code 는 Anthropic 키를, Codex 는 OpenAI 키를 쓰므로 사용자는 벤더당 키를 한 번만 넣으면 된다. UI 에서도 "Claude Code 용 키" / "Codex 용 키" 로 나누지 말고 벤더 단위로 하나씩 두는 게 맞다.
🎨 UI 참고 사항
⚠️ 에러 처리
| 상황 |
응답 |
FE 처리 |
| 키 미등록 상태로 코딩 에이전트 사용 |
400 AI_CREDENTIAL_NOT_REGISTERED |
키 등록 화면으로 유도. 서버가 운영자 키로 대신 채워주지 않는다(제공사 약관상 사용자를 대신한 결제·중개 금지) |
| 키에 공백/제어문자 포함 |
400 |
붙여넣기 시 개행이 섞인 경우가 흔하다. 입력값 trim 후 전송하고, 그래도 400 이면 메시지 노출 |
실행 모드(CLAUDE_CODE 등)로 등록 시도 |
400 |
위 "provider 값" 참고 — 발생하지 않도록 UI 를 벤더 단위로 구성 |
| 미등록 항목 삭제 |
404 |
목록 갱신 후 안내 |
✅ 완료 기준
📌 참고
- 백엔드:
Dvely/Dvely_springboot Issue #242 / PR #245
- API 문서:
docs/FRONTEND_API_GUIDE.md §4.12 (해당 PR 에 포함)
- 설계 배경:
docs/byok-coding-agent-design.md
- 백엔드 머지 전에는 dev 서버에 엔드포인트가 없다. PR #245 머지 후 착수하거나, 그 전에는 목업으로 진행.
🔥 Issue 개요
백엔드에 BYOK(Bring Your Own Key) AI 크리덴셜 API 가 추가된다(
Dvely_springbootPR #245, Issue #242). 사용자가 자기 공식 AI API 키를 등록하면, 그 키로 Claude Code / Codex 코딩 에이전트가 격리 컨테이너에서 실행되고 사용량은 사용자 계정으로 직접 청구된다.FE 는 이 키를 등록·확인·삭제하는 화면이 필요하다. 엔드포인트 3개는 이미 구현·테스트 완료 상태다.
🎯 목표
✅ 작업 범위
포함 범위
AI_CREDENTIAL_NOT_REGISTERED에러 처리 → 키 등록 화면 유도제외 범위 (지금 하지 말 것)
CLAUDE_CODE/CODEX를 AI 제공자 선택지에 노출하지 말 것. 코딩 에이전트는 아직 채팅/CODE 플로우에 배선되지 않은 휴면 상태이고,GET /api/v1/agent/ai-providers목록에도 나오지 않는다. 지금 선택지로 넣으면 400 이 난다. 배선 완료 시 별도 이슈로 요청한다.📋 API 계약
전부
Authorization: Bearer {accessToken}필요.1) 목록 조회
본인이 등록한 것만 반환된다(소유자는 토큰에서만 결정되며 요청 파라미터가 없다).
2) 등록 / 교체
등록과 교체가 같은 동작이다(PUT). 벤더당 키 하나이므로, 이미 등록돼 있으면 새 키로 교체된다. "이미 등록됨" 409 같은 건 없다 — 유출 직후 교체가 한 번의 호출로 끝나야 하기 때문.
3) 삭제
{provider}값벤더만 받는다:
ANTHROPIC·OPENAI·GLMCLAUDE_CODE/CODEX로 등록을 시도하면 400 이고, 응답 메시지가 어느 벤더로 등록해야 하는지 알려준다. 이유: Claude Code 는 Anthropic 키를, Codex 는 OpenAI 키를 쓰므로 사용자는 벤더당 키를 한 번만 넣으면 된다. UI 에서도 "Claude Code 용 키" / "Codex 용 키" 로 나누지 말고 벤더 단위로 하나씩 두는 게 맞다.🎨 UI 참고 사항
maskedApiKey는 앞 6자만 남긴 형태(sk-ant****). 뒤 4자를 보여주는 흔한 관례와 다른데, 꼬리가 실제 키 엔트로피라 의도적으로 가린 것이다. 그대로 표시하면 된다.400 AI_CREDENTIAL_NOT_REGISTERED400CLAUDE_CODE등)로 등록 시도400404✅ 완료 기준
AI_CREDENTIAL_NOT_REGISTERED유도 플로우 확인📌 참고
Dvely/Dvely_springbootIssue #242 / PR #245docs/FRONTEND_API_GUIDE.md§4.12 (해당 PR 에 포함)docs/byok-coding-agent-design.md