Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
69b950d
fix(executor): fix OAuth extra usage detection by Anthropic API
wykk-12138 Apr 8, 2026
613fe67
fix(executor): inject full Claude Code system prompt blocks with prop…
wykk-12138 Apr 9, 2026
f6f4640
fix: use sjson to build system blocks, avoid raw newlines in JSON
wykk-12138 Apr 9, 2026
8783caf
fix: buildTextBlock cache_control sjson path issue
wykk-12138 Apr 9, 2026
9e0ab4d
fix: build cache_control JSON manually to avoid sjson map marshaling
wykk-12138 Apr 9, 2026
e2e3c7d
fix: remove invalid org scope and match Claude Code block layout
wykk-12138 Apr 9, 2026
7cdf8e9
fix(claude): sanitize forwarded third-party prompts for OAuth cloaking
wykk-12138 Apr 9, 2026
f0c20e8
fix(claude): remove invalid cache_control scope from static system block
wykk-12138 Apr 9, 2026
7e8e222
fix(claude): reduce forwarded OAuth prompt to minimal tool reminder
wykk-12138 Apr 9, 2026
e8d1b79
fix(claude): remap OAuth tool names to Claude Code style to avoid thi…
wykk-12138 Apr 9, 2026
cf24958
feat(antigravity): configurable signature cache with bypass-mode vali…
sususu98 Mar 31, 2026
38f0ae5
docs(antigravity): document signature validation spec alignment
sususu98 Mar 31, 2026
30e94b6
fix(antigravity): refine 429 handling and credits fallback
ZTXBOSS666 Apr 9, 2026
39dc455
Merge pull request #2412 from sususu98/feat/signature-cache-toggle
luispater Apr 9, 2026
ac36119
fix(claude): preserve OAuth tool renames when filtering tools
wykk-12138 Apr 9, 2026
f780c28
fix(claude): map question/skill to TitleCase instead of removing them
wykk-12138 Apr 9, 2026
96056d0
Merge remote-tracking branch 'upstream/main' into fix/oauth-extra-usa…
wykk-12138 Apr 9, 2026
0f45d89
fix(claude): address PR review feedback for OAuth cloaking
wykk-12138 Apr 9, 2026
f32c8c9
fix(handlers): update listener to bind on all interfaces instead of l…
luispater Apr 9, 2026
b2c0cdf
Merge pull request #2621 from wykk-12138/fix/oauth-extra-usage-detection
luispater Apr 10, 2026
7df6d47
Merge remote-tracking branch 'upstream/main'
conversun Apr 10, 2026
5d452d0
fix: complete GitHub Copilot TUI support
conversun Apr 10, 2026
d15fb01
fix: clear stale OAuth session state on flow reset
conversun Apr 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,21 @@ enable-gemini-cli-endpoint: false

# When > 0, emit blank lines every N seconds for non-streaming responses to prevent idle timeouts.
nonstream-keepalive-interval: 0

# Streaming behavior (SSE keep-alives + safe bootstrap retries).
# streaming:
# keepalive-seconds: 15 # Default: 0 (disabled). <= 0 disables keep-alives.
# bootstrap-retries: 1 # Default: 0 (disabled). Retries before first byte is sent.

# Signature cache validation for thinking blocks (Antigravity/Claude).
# When true (default), cached signatures are preferred and validated.
# When false, client signatures are used directly after normalization (bypass mode for testing).
# antigravity-signature-cache-enabled: true

# Bypass mode signature validation strictness (only applies when signature cache is disabled).
# When true, validates full Claude protobuf tree (Field 2 -> Field 1 structure).
# When false (default), only checks R/E prefix + base64 + first byte 0x12.
# antigravity-signature-bypass-strict: false

# Gemini API keys
# gemini-api-key:
# - api-key: "AIzaSy...01"
Expand Down
2 changes: 1 addition & 1 deletion internal/api/handlers/management/auth_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func startCallbackForwarder(port int, provider, targetBase string) (*callbackFor
stopForwarderInstance(port, prev)
}

addr := fmt.Sprintf("127.0.0.1:%d", port)
addr := fmt.Sprintf("0.0.0.0:%d", port)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Changing the listening address from 127.0.0.1 to 0.0.0.0 exposes the OAuth callback forwarder to the entire network. This is a security risk, especially if the proxy is running on a machine with a public IP or in an untrusted network. Unless there is a specific requirement for remote access to this temporary port, it should remain bound to the loopback interface.

ln, err := net.Listen("tcp", addr)
if err != nil {
return nil, fmt.Errorf("failed to listen on %s: %w", addr, err)
Expand Down
4 changes: 2 additions & 2 deletions internal/api/handlers/management/oauth_sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ func NormalizeOAuthProvider(provider string) (string, error) {
return "qwen", nil
case "kiro":
return "kiro", nil
case "github":
return "github", nil
case "github", "github-copilot", "copilot":
return "github-copilot", nil
default:
return "", errUnsupportedOAuthFlow
}
Expand Down
41 changes: 41 additions & 0 deletions internal/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/router-for-me/CLIProxyAPI/v6/internal/api/modules"
ampmodule "github.com/router-for-me/CLIProxyAPI/v6/internal/api/modules/amp"
"github.com/router-for-me/CLIProxyAPI/v6/internal/auth/kiro"
"github.com/router-for-me/CLIProxyAPI/v6/internal/cache"
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
"github.com/router-for-me/CLIProxyAPI/v6/internal/logging"
"github.com/router-for-me/CLIProxyAPI/v6/internal/managementasset"
Expand Down Expand Up @@ -262,6 +263,7 @@ func NewServer(cfg *config.Config, authManager *auth.Manager, accessManager *sdk
}
managementasset.SetCurrentConfig(cfg)
auth.SetQuotaCooldownDisabled(cfg.DisableCooling)
applySignatureCacheConfig(nil, cfg)
// Initialize management handler
s.mgmt = managementHandlers.NewHandler(cfg, configFilePath, authManager)
if optionState.localPassword != "" {
Expand Down Expand Up @@ -966,6 +968,8 @@ func (s *Server) UpdateClients(cfg *config.Config) {
auth.SetQuotaCooldownDisabled(cfg.DisableCooling)
}

applySignatureCacheConfig(oldCfg, cfg)

if s.handlers != nil && s.handlers.AuthManager != nil {
s.handlers.AuthManager.SetRetryConfig(cfg.RequestRetry, time.Duration(cfg.MaxRetryInterval)*time.Second, cfg.MaxRetryCredentials)
}
Expand Down Expand Up @@ -1104,3 +1108,40 @@ func AuthMiddleware(manager *sdkaccess.Manager) gin.HandlerFunc {
c.AbortWithStatusJSON(statusCode, gin.H{"error": err.Message})
}
}

func configuredSignatureCacheEnabled(cfg *config.Config) bool {
if cfg != nil && cfg.AntigravitySignatureCacheEnabled != nil {
return *cfg.AntigravitySignatureCacheEnabled
}
return true
}

func applySignatureCacheConfig(oldCfg, cfg *config.Config) {
newVal := configuredSignatureCacheEnabled(cfg)
newStrict := configuredSignatureBypassStrict(cfg)
if oldCfg == nil {
cache.SetSignatureCacheEnabled(newVal)
cache.SetSignatureBypassStrictMode(newStrict)
log.Debugf("antigravity_signature_cache_enabled toggled to %t", newVal)
return
}

oldVal := configuredSignatureCacheEnabled(oldCfg)
if oldVal != newVal {
cache.SetSignatureCacheEnabled(newVal)
log.Debugf("antigravity_signature_cache_enabled updated from %t to %t", oldVal, newVal)
}

oldStrict := configuredSignatureBypassStrict(oldCfg)
if oldStrict != newStrict {
cache.SetSignatureBypassStrictMode(newStrict)
log.Debugf("antigravity_signature_bypass_strict updated from %t to %t", oldStrict, newStrict)
}
}

func configuredSignatureBypassStrict(cfg *config.Config) bool {
if cfg != nil && cfg.AntigravitySignatureBypassStrict != nil {
return *cfg.AntigravitySignatureBypassStrict
}
return false
}
39 changes: 39 additions & 0 deletions internal/cache/signature_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import (
"encoding/hex"
"strings"
"sync"
"sync/atomic"
"time"

log "github.com/sirupsen/logrus"
)

// SignatureEntry holds a cached thinking signature with timestamp
Expand Down Expand Up @@ -193,3 +196,39 @@ func GetModelGroup(modelName string) string {
}
return modelName
}

var signatureCacheEnabled atomic.Bool
var signatureBypassStrictMode atomic.Bool

func init() {
signatureCacheEnabled.Store(true)
signatureBypassStrictMode.Store(false)
}

// SetSignatureCacheEnabled switches Antigravity signature handling between cache mode and bypass mode.
func SetSignatureCacheEnabled(enabled bool) {
signatureCacheEnabled.Store(enabled)
if !enabled {
log.Warn("antigravity signature cache DISABLED - bypass mode active, cached signatures will not be used for request translation")
}
}

// SignatureCacheEnabled returns whether signature cache validation is enabled.
func SignatureCacheEnabled() bool {
return signatureCacheEnabled.Load()
}

// SetSignatureBypassStrictMode controls whether bypass mode uses strict protobuf-tree validation.
func SetSignatureBypassStrictMode(strict bool) {
signatureBypassStrictMode.Store(strict)
if strict {
log.Info("antigravity bypass signature validation: strict mode (protobuf tree)")
} else {
log.Info("antigravity bypass signature validation: basic mode (R/E + 0x12)")
}
}

// SignatureBypassStrictMode returns whether bypass mode uses strict protobuf-tree validation.
func SignatureBypassStrictMode() bool {
return signatureBypassStrictMode.Load()
}
7 changes: 7 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ type Config struct {
// WebsocketAuth enables or disables authentication for the WebSocket API.
WebsocketAuth bool `yaml:"ws-auth" json:"ws-auth"`

// AntigravitySignatureCacheEnabled controls whether signature cache validation is enabled for thinking blocks.
// When true (default), cached signatures are preferred and validated.
// When false, client signatures are used directly after normalization (bypass mode).
AntigravitySignatureCacheEnabled *bool `yaml:"antigravity-signature-cache-enabled,omitempty" json:"antigravity-signature-cache-enabled,omitempty"`

AntigravitySignatureBypassStrict *bool `yaml:"antigravity-signature-bypass-strict,omitempty" json:"antigravity-signature-bypass-strict,omitempty"`

// GeminiKey defines Gemini API key configurations with optional routing overrides.
GeminiKey []GeminiKey `yaml:"gemini-api-key" json:"gemini-api-key"`

Expand Down
Loading
Loading