router-for-me/CLIProxyAPI · error

insecure plugin store url requires matching allow-insecure a

Error message

insecure plugin store url requires matching allow-insecure auth rule

What it means

The store URL uses plain http:// and no matching auth rule has allow-insecure: true. Because cleartext downloads of plugin artifacts are tamperable, pluginstore gates http URLs behind an explicit per-rule opt-in: allowInsecurePluginStoreURL only returns true when a rule matching this URL and request kind carries AllowInsecure. Otherwise the fetch is refused.

Source

Thrown at internal/pluginstore/auth.go:322

	default:
		return false, fmt.Errorf("unsupported plugin store resolved auth type %q", item.Type)
	}
	return true, nil
}

func validatePluginStoreRequestURL(auth []AuthConfig, requestURL string, kind string) error {
	parsed, errParse := url.Parse(strings.TrimSpace(requestURL))
	if errParse != nil || parsed.Scheme == "" || parsed.Host == "" {
		return fmt.Errorf("invalid plugin store url")
	}
	if parsed.User != nil {
		return fmt.Errorf("plugin store url must not contain credentials")
	}
	if hasSensitiveQueryParameter(parsed) {
		return fmt.Errorf("plugin store url contains sensitive query parameter")
	}
	if strings.EqualFold(parsed.Scheme, "http") && !allowInsecurePluginStoreURL(auth, requestURL, kind) {
		return fmt.Errorf("insecure plugin store url requires matching allow-insecure auth rule")
	}
	return nil
}

func allowInsecurePluginStoreURL(auth []AuthConfig, requestURL string, kind string) bool {
	item, ok := matchingAuthConfig(auth, requestURL, kind)
	return ok && item.AllowInsecure
}

func validateResolvedAuthExpiry(auth []ResolvedAuthConfig, expiresAt time.Time, now time.Time, requestURL string, kind string) error {
	if expiresAt.IsZero() {
		return nil
	}
	if _, ok := matchingResolvedAuthConfig(auth, requestURL, kind); !ok {
		return nil
	}
	if !now.Before(expiresAt) {
		return fmt.Errorf("plugin store resolved auth expired")

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Prefer switching the store to https:// (add TLS or a local cert) — the only fully supported option
  2. For trusted internal/dev use, set allow-insecure: true on an auth rule whose match covers the URL and whose apply-to includes the request kind
  3. Verify the match pattern actually matches the URL (scheme+host prefix) — a non-matching rule will not authorize the insecure fetch

Example fix

# before
- match: http://localhost:8080
  type: none

# after
- match: http://localhost:8080
  type: none
  allow-insecure: true
Defensive patterns

Strategy: validation

Validate before calling

func insecureAllowed(rules []AuthConfig, requestURL, kind string) bool {
	u, _ := url.Parse(strings.TrimSpace(requestURL))
	if u == nil || !strings.EqualFold(u.Scheme, "http") {
		return true // not insecure
	}
	for _, r := range rules {
		if r.AllowInsecure && pluginStoreURLMatchesAuthRule(requestURL, r.Match) && authAppliesTo(r, kind) {
			return true
		}
	}
	return false
}

Prevention

When it happens

Trigger: Fetching a registry/metadata/artifact over http:// (e.g. http://localhost:8080/registry.json or an internal mirror) where the matching auth rule lacks allow-insecure, or no rule matches at all.

Common situations: Local development server without TLS; internal corporate mirror on http; adding a new http store URL but forgetting the flag; match pattern does not cover the URL so the allow-insecure rule never matches.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/f408b55c6be52251. Report an issue: GitHub.