History

fix(meta): require OAuth storage for DCA tokens and reject them in config meta-api-key

Kenny committed 2 months ago

Commit 1144ae71 parent d09042a5 files · +38 −29Browse files

Unified · Split

5 files
  1. internal/api/handlers/management/api_tools.go +14 −16
  2. internal/config/config_meta_test.go +3 −3
  3. internal/config/config_normalization.go +2 −2
  4. internal/runtime/executor/meta_executor.go +8 −8
  5. internal/runtime/executor/meta_executor_test.go +11 −0
internal/api/handlers/management/api_tools.go+14−16
@@ -384,22 +384,20 @@ func (h *Handler) resolveMetaToken(ctx context.Context, auth *coreauth.Auth, req · 383 unmodified lines
384384 }
385385
386386 var dcaToken string
387− if auth.Metadata != nil {
388− if d, ok := auth.Metadata["dca_token"].(string); ok && strings.TrimSpace(d) != "" {
389− dcaToken = strings.TrimSpace(d)
390− } else if t, ok := auth.Metadata["access_token"].(string); ok && strings.HasPrefix(strings.TrimSpace(t), "dca:") {
391− dcaToken = strings.TrimSpace(t)
392− } else if k, ok := auth.Metadata["api_key"].(string); ok && strings.HasPrefix(strings.TrimSpace(k), "dca:") {
393− dcaToken = strings.TrimSpace(k)
394− }
395− }
396− if dcaToken == "" && auth.Attributes != nil {
397− if d := strings.TrimSpace(auth.Attributes["dca_token"]); d != "" {
398− dcaToken = d
399− } else if t := strings.TrimSpace(auth.Attributes["access_token"]); strings.HasPrefix(t, "dca:") {
400− dcaToken = t
401− } else if k := strings.TrimSpace(auth.Attributes["api_key"]); strings.HasPrefix(k, "dca:") {
402− dcaToken = k
387+ if !coreauth.IsConfigAPIKeyAuth(auth) {
388+ if auth.Metadata != nil {
389+ if d, ok := auth.Metadata["dca_token"].(string); ok && strings.TrimSpace(d) != "" {
390+ dcaToken = strings.TrimSpace(d)
391+ } else if t, ok := auth.Metadata["access_token"].(string); ok && strings.HasPrefix(strings.TrimSpace(t), "dca:") {
392+ dcaToken = strings.TrimSpace(t)
393+ }
394+ }
395+ if dcaToken == "" && auth.Attributes != nil {
396+ if d := strings.TrimSpace(auth.Attributes["dca_token"]); d != "" {
397+ dcaToken = d
398+ } else if t := strings.TrimSpace(auth.Attributes["access_token"]); strings.HasPrefix(t, "dca:") {
399+ dcaToken = t
400+ }
403401 }
404402 }
405403
internal/config/config_meta_test.go+3−3
@@ -9,13 +9,13 @@ func TestMetaConfigDropsUnusableKeys(t *testing.T) { · 8 unmodified lines
99 - base-url: "https://api.meta.ai/v1"
1010 - headers: {X-Trace: placeholder}
1111 - api-key: " LLM|valid "
12− - api-key: "dca:recoverable"
12+ - api-key: "dca:requires-oauth-storage"
1313 `))
1414 if err != nil {
1515 t.Fatal(err)
1616 }
17− if len(cfg.MetaKey) != 2 {
18− t.Fatalf("got %d keys, want only the two usable credentials", len(cfg.MetaKey))
17+ if len(cfg.MetaKey) != 1 {
18+ t.Fatalf("got %d keys, want only the 1 valid API key (DCA tokens require OAuth storage)", len(cfg.MetaKey))
1919 }
2020 if cfg.MetaKey[0].APIKey != "LLM|valid" || cfg.MetaKey[0].BaseURL != "https://api.meta.ai/v1" {
2121 t.Fatalf("valid key not normalized: %#v", cfg.MetaKey[0])
internal/config/config_normalization.go+2−2
@@ -210,8 +210,8 @@ func sanitizeMetaKeyEntries(entries []MetaKey) []MetaKey { · 209 unmodified lines
210210 for i := range entries {
211211 e := entries[i]
212212 e.APIKey = strings.TrimSpace(e.APIKey)
213− // The native Meta executor requires an API key or a DCA token in this field.
214− if e.APIKey == "" {
213+ // meta-api-key requires a valid API key. DCA tokens require OAuth storage (auths/*.json).
214+ if e.APIKey == "" || strings.HasPrefix(e.APIKey, "dca:") {
215215 continue
216216 }
217217 e.Prefix = normalizeModelPrefix(e.Prefix)
internal/runtime/executor/meta_executor.go+8−8
@@ -254,7 +254,7 @@ func (e *MetaExecutor) Refresh(ctx context.Context, auth *cliproxyauth.Auth) (*c · 253 unmodified lines
254254
255255 // ShouldPrepareRequestAuth reports true when a Meta auth has a DCA token but no usable API key.
256256 func (e *MetaExecutor) ShouldPrepareRequestAuth(auth *cliproxyauth.Auth) bool {
257− if auth == nil {
257+ if auth == nil || cliproxyauth.IsConfigAPIKeyAuth(auth) {
258258 return false
259259 }
260260 _, token := metaCreds(auth)
@@ -291,6 +291,12 @@ func (e *MetaExecutor) ensureAuth(ctx context.Context, auth *cliproxyauth.Auth) · 30 unmodified lines
291291 }
292292
293293 if token == "" {
294+ if cliproxyauth.IsConfigAPIKeyAuth(auth) {
295+ return nil, statusErr{
296+ code: http.StatusUnauthorized,
297+ msg: "meta executor: meta-api-key requires a valid API key (DCA tokens require OAuth storage)",
298+ }
299+ }
294300 return nil, statusErr{
295301 code: http.StatusUnauthorized,
296302 msg: "meta executor: missing API key or access token",
@@ -326,7 +332,7 @@ func (e *MetaExecutor) enrichAuth(auth *cliproxyauth.Auth) *cliproxyauth.Auth { · 29 unmodified lines
326332 }
327333
328334 func extractDCAToken(a *cliproxyauth.Auth) string {
329− if a == nil {
335+ if a == nil || cliproxyauth.IsConfigAPIKeyAuth(a) {
330336 return ""
331337 }
332338 if a.Attributes != nil {
@@ -336,9 +342,6 @@ func extractDCAToken(a *cliproxyauth.Auth) string { · 3 unmodified lines
336342 if t := strings.TrimSpace(a.Attributes["access_token"]); strings.HasPrefix(t, "dca:") {
337343 return t
338344 }
339− if k := strings.TrimSpace(a.Attributes["api_key"]); strings.HasPrefix(k, "dca:") {
340− return k
341− }
342345 }
343346 if a.Metadata != nil {
344347 if d, ok := a.Metadata["dca_token"].(string); ok && strings.TrimSpace(d) != "" {
@@ -347,9 +350,6 @@ func extractDCAToken(a *cliproxyauth.Auth) string { · 2 unmodified lines
347350 if t, ok := a.Metadata["access_token"].(string); ok && strings.HasPrefix(strings.TrimSpace(t), "dca:") {
348351 return strings.TrimSpace(t)
349352 }
350− if k, ok := a.Metadata["api_key"].(string); ok && strings.HasPrefix(strings.TrimSpace(k), "dca:") {
351− return strings.TrimSpace(k)
352− }
353353 }
354354 if a.Storage != nil {
355355 if ms, ok := a.Storage.(*metaauth.MetaTokenStorage); ok && ms != nil {
internal/runtime/executor/meta_executor_test.go+11−0
@@ -572,6 +572,17 @@ func TestMetaExecutor_RequestAuthPreparer(t *testing.T) { · 571 unmodified lines
572572 t.Errorf("ShouldPrepareRequestAuth should be false when dca_token is missing")
573573 }
574574
575+ authConfigDCA := &cliproxyauth.Auth{
576+ Provider: "meta",
577+ Attributes: map[string]string{
578+ "api_key": "dca:invalid-for-config",
579+ cliproxyauth.AttributeSource: "config:meta[0]",
580+ },
581+ }
582+ if exec.ShouldPrepareRequestAuth(authConfigDCA) {
583+ t.Errorf("ShouldPrepareRequestAuth should be false for config API key auths")
584+ }
585+
575586 authDCAOnly := &cliproxyauth.Auth{
576587 ID: "meta-prep-test",
577588 Provider: "meta",

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t