- Notifications
You must be signed in to change notification settings - Fork 132
OAuth client secret migration and backward compatibility for existing workloads #2231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@ ## main #2231 +/- ## ========================================== - Coverage 53.43% 53.34% -0.10% ========================================== Files 230 231 +1 Lines 29385 29529 +144 ========================================== + Hits 15703 15753 +50 - Misses 12552 12644 +92 - Partials 1130 1132 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
@claude Can you review this PR please? |
Claude finished @ChrisJBurns's task —— View job Code Review CompleteI've reviewed the OAuth client secret migration and backward compatibility implementation. Here's my comprehensive feedback: 🎯 Overall AssessmentStrengths:
Concerns:
🔍 Detailed Findings1. Test Coverage (Critical Priority)The codecov report shows 130 lines missing coverage across the changes:
Recommendations:
File: 2. Migration Logic - Error HandlingIssue: Migration failures are logged as warnings but the workload continues loading with potentially unresolved state. Location: if err := migrateOAuthClientSecret(&config); err != nil { logger.Warnf("Failed to migrate OAuth client secret for workload %s: %v", config.Name, err) // Don't fail the load - just log the warning and continue } Concern: If migration fails, the workload loads with plain text secret still in config, but the secret might not be stored in the secrets manager. This could lead to:
Recommendation:
Add comments explaining each failure scenario and why it's handled that way. 3. Backward Compatibility - UnmarshalJSONIssue: The detection logic assumes PascalCase format if Location: if _, isOld := raw["ClientID"]; isOld { Concern: What happens if someone has a JSON file with both Recommendation:
4. Secret Name GenerationIssue: Timestamp-based uniqueness might not be sufficient for high-frequency operations. Location: timestamp := time.Now().Unix() uniqueName := fmt.Sprintf("%s_%d", baseName, timestamp) Concern: If two migrations happen within the same second (e.g., during bulk import or testing), they could generate the same secret name, leading to overwrites. Recommendation:
5. Package DependenciesObservation: The new Location: Concern: If Recommendation:
6. Code Quality - Positive NotesWell done:
7. Migration IdempotencyPositive: The migration correctly checks if a secret is already in CLI format before processing: Location: if _, err := secrets.ParseSecretParameter(config.RemoteAuthConfig.ClientSecret); err == nil { return nil // Already in CLI format, no migration needed } This ensures the migration is idempotent and won't double-process secrets. Good design! ✅ 8. Missing Test CasesBased on the code, here are critical test scenarios that should be covered:
📋 Recommendations SummaryHigh Priority (Must Address):
Medium Priority (Should Address):
Low Priority (Nice to Have):
🏁 ConclusionThis is a well-architected solution to a real backward compatibility problem. The approach is sound, and the code organization is clean. However, the lack of test coverage is a significant blocker that should be addressed before merging. The migration logic itself is solid, but needs comprehensive testing to ensure it handles all edge cases correctly, especially given that this code will be handling sensitive OAuth credentials. Recommendation: Request changes to add comprehensive test coverage before approving. |
@claude please review this with a security point of view. |
Claude finished @JAORMX's task —— View job Security Review Performing security-focused code review of OAuth client secret migration implementation. Tasks
Security Analysis CompleteI've conducted a thorough security review of the OAuth client secret migration implementation. Here are my findings: 🔒 Critical Security Findings1. Secret Exposure in Warning Logs - HIGH SEVERITY |
Finding | Severity | Likelihood | Impact | Priority |
---|---|---|---|---|
Race condition in secret generation | Medium | Medium | High | HIGH |
Orphaned secrets on SaveState failure | Medium | Low | Medium | MEDIUM |
Missing security tests | High | N/A | High | HIGH |
Secret exposure in logs | Low | Low | High | MEDIUM |
Plain text in memory | Low | Very Low | Medium | LOW |
Problem
Existing workloads with plain text OAuth client secrets stored in their
RunConfig
would fail to restart after new ToolHive UI releases. This occurred because:ClientID
,ClientSecret
) but new code expected snake_case (client_id
,client_secret
)Solution
🔧 Backward Compatibility
UnmarshalJSON()
method toRemoteAuthConfig
that handles both old PascalCase and new snake_case formats🔄 Migration Hook
migrateOAuthClientSecret()
function inReadJSON()
that automatically converts plain text OAuth secrets to CLI format🛠️ Shared Utility Package
pkg/oauth/client_secret.go
with shared OAuth secret processing functionsGenerateUniqueSecretName()
function🔒 Security Improvements
"SECRET_NAME,target=oauth_secret"
formatWithSecrets()
Key Changes
Files Modified
pkg/runner/config.go
: Added backward compatibility and migration hookpkg/oauth/client_secret.go
: New shared utility packagecmd/thv/app/run_flags.go
: Updated to use shared utilitypkg/api/v1/workloads.go
: Export API now returns object format secretspkg/api/v1/workload_types.go
: Updated conversion functionsNew Functions
RemoteAuthConfig.UnmarshalJSON()
: Handles both JSON formatsmigrateOAuthClientSecret()
: Converts plain text to CLI formatoauth.ProcessOAuthClientSecret()
: Shared secret processingoauth.GenerateUniqueSecretName()
: Unified name generationTesting
Impact
Before: Existing workloads with plain text OAuth secrets would fail to restart
After: Seamless migration and backward compatibility for all existing workloads
This ensures that existing ToolHive deployments can continue running without interruption while benefiting from the new secure OAuth secret handling.