IBM 연동형 vLLM 인증 실패 원인 수정
Some checks failed
Release Gate / gate (push) Has been cancelled

IBM Cloud 계열 vLLM 연결에서 등록 모델 인증 방식이 Bearer와 CP4D만 지원하던 문제를 점검하고, IBM IAM 토큰 교환 경로를 추가했습니다.

- RegisteredModel/AuthType에 ibm_iam 경로를 반영했습니다.

- IbmIamTokenService를 추가해 API 키를 IAM access token으로 교환한 뒤 Bearer 헤더로 적용하도록 했습니다.

- 모델 등록 다이얼로그, 설정 ViewModel, AX Agent 오버레이 모델 목록에도 IBM IAM 표시를 추가했습니다.

- README.md와 docs/DEVELOPMENT.md에 2026-04-06 14:06 (KST) 기준 이력을 반영했습니다.

검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0 / 오류 0)
This commit is contained in:
2026-04-06 15:02:42 +09:00
parent 3feb1f0be4
commit 817fc94f41
8 changed files with 148 additions and 8 deletions

View File

@@ -322,7 +322,7 @@ public partial class LlmService : IDisposable
/// <summary>
/// 현재 활성 모델의 인증 헤더 값을 반환합니다.
/// CP4D 인증인 경우 토큰을 자동 발급/캐싱하여 반환합니다.
/// IBM IAM / CP4D 인증인 경우 토큰을 자동 발급/캐싱하여 반환합니다.
/// </summary>
internal async Task<string?> ResolveAuthTokenAsync(CancellationToken ct = default)
{
@@ -331,6 +331,17 @@ public partial class LlmService : IDisposable
var modelName = ResolveModel();
var registered = FindRegisteredModel(llm, activeService, modelName);
// IBM Cloud IAM 인증 방식인 경우
if (registered != null &&
registered.AuthType.Equals("ibm_iam", StringComparison.OrdinalIgnoreCase))
{
var ibmApiKey = !string.IsNullOrWhiteSpace(registered.ApiKey)
? ResolveSecretValue(registered.ApiKey, llm.EncryptionEnabled)
: GetDefaultApiKey(llm, activeService);
var token = await IbmIamTokenService.GetTokenAsync(ibmApiKey, ct: ct);
return token;
}
// CP4D 인증 방식인 경우
if (registered != null &&
registered.AuthType.Equals("cp4d", StringComparison.OrdinalIgnoreCase) &&
@@ -349,7 +360,7 @@ public partial class LlmService : IDisposable
/// <summary>
/// HttpRequestMessage에 인증 헤더를 적용합니다.
/// CP4D 인증인 경우 자동 토큰 발급, 일반 Bearer인 경우 API 키를 사용합니다.
/// IBM IAM / CP4D 인증인 경우 자동 토큰 발급, 일반 Bearer인 경우 API 키를 사용합니다.
/// </summary>
private async Task ApplyAuthHeaderAsync(HttpRequestMessage req, CancellationToken ct)
{