Add request sanitizer, background token refresh, and OpenCode support

Sanitizer renames tool names and replaces system prompt patterns
that Anthropic fingerprints to detect non-Claude-Code clients.
Lowercase tool names (bash, read, glob, etc.) combined together
trigger rejection — renaming to PascalCase bypasses this.
Configurable via YAML sanitize rules for tools, system, and body.

Background OAuth token refresh every 30s with 5-minute pre-expiry
lead. Uses Chrome TLS fingerprint for refresh endpoint too.

Adds /messages route (without /v1 prefix) for OpenCode compat.
This commit is contained in:
Alexander
2026-04-09 22:52:43 +02:00
parent c4c1d4daa4
commit 909c8b1894
11 changed files with 428 additions and 89 deletions
+1 -22
View File
@@ -3,7 +3,6 @@ package auth
import (
"context"
"fmt"
"log"
"sync"
"time"
)
@@ -55,25 +54,5 @@ func (p *Pool) MarkSuccess(cred *Credential) {
}
func (p *Pool) RefreshExpiring(ctx context.Context) {
p.mu.Lock()
creds := make([]*Credential, len(p.creds))
copy(creds, p.creds)
p.mu.Unlock()
threshold := time.Now().Add(5 * time.Minute)
for _, cred := range creds {
cred.mu.Lock()
needsRefresh := cred.ExpiresAt.Before(threshold)
email := cred.Email
cred.mu.Unlock()
if needsRefresh {
log.Printf("refreshing token for %s (expires %s)", email, cred.ExpiresAt.Format(time.RFC3339))
if err := RefreshToken(ctx, cred); err != nil {
log.Printf("failed to refresh token for %s: %v", email, err)
} else {
log.Printf("refreshed token for %s, new expiry %s", email, cred.ExpiresAt.Format(time.RFC3339))
}
}
}
refreshAll(p)
}