-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add user credential passthrough mode for projects #158
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
Open
crystalin
wants to merge
15
commits into
main
Choose a base branch
from
feat/account-less-projects-passthrough
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add support for projects to operate without a default organization account, allowing users to provide their own Anthropic credentials via Authorization header. **Changes:** - Database: Migration 015 ensures default_account_id is nullable - Types: Updated CreateProjectRequest and UpdateProjectRequest to accept null default_account_id - Queries: Updated createProject/updateProject to handle null account explicitly - Auth: AuthenticationService now has 3-tier priority: 1. MSL-Account header (explicit account) 2. Project default account 3. User passthrough (Bearer token forwarding) [NEW] - Dashboard: Added "User Account" option in project creation and management UI - Tests: Added comprehensive tests for user passthrough authentication **Documentation:** - ADR-030: Documents decision, rationale, and implementation details - Clear error messages when user credentials required but not provided **Backward Compatibility:** - Existing projects continue working unchanged - Default behavior (random account assignment) preserved - New projects can explicitly choose "User Account" mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Make the MSL-Project-Id header mandatory to ensure proper project identification, especially critical for user passthrough mode where we need to look up whether the project has a default account or requires user-provided credentials. **Changes:** - RequestContext.fromHono() now throws error if MSL-Project-Id header is missing - Removed fallback to config.auth.defaultTrainId and unused import - Updated ADR-030 to document mandatory header requirement - Clear error message guides users to provide the required header **Rationale:** - User passthrough mode requires project lookup to determine authentication method - Explicit project identification improves security and prevents ambiguity - Makes API contract clearer and more predictable 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Remove the fallback to 'default' project ID in project-id-extractor middleware to ensure MSL-Project-Id header is truly mandatory. **Changes:** - Removed fallback logic from projectIdExtractorMiddleware - Removed unused imports (logger, config) - If MSL-Project-Id header is missing, projectId remains unset - RequestContext.fromHono() will catch and error with clear message **Before:** - Middleware set projectId to 'default' if header missing - RequestContext never saw missing header - Fallback behavior was implicit **After:** - Middleware only sets projectId if header present - RequestContext throws explicit error if projectId missing - Clear error message guides users **Testing:** - All authentication tests passing - Typecheck passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Add comprehensive logging of outbound requests to Anthropic API to help debug authentication issues, especially for user passthrough mode. **Changes:** - Log full request details before sending to Anthropic - Include URL, method, and all headers (except body for privacy) - Mask Authorization token (show first 20 chars only) - Helps diagnose authentication_error issues **Log format:** ``` INFO: Outbound request to Anthropic API url: https://api.anthropic.com/v1/messages method: POST headers: Authorization: Bearer sk-ant-... anthropic-version: 2023-06-01 anthropic-beta: oauth-2025-04-20 Content-Type: application/json ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
- Add maskToken helper to show last 4 chars of tokens - Log incoming Authorization header from user - Log all outbound headers sent to Anthropic - Enable comparison of incoming vs outgoing headers for debugging This helps diagnose authentication issues by showing what credentials the proxy receives vs what it forwards to Anthropic. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
In user passthrough mode, the proxy now forwards ALL headers sent by the client (except infrastructure/proxy headers) to ensure proper authentication and API compatibility. Changes: - Extract all client headers in RequestContext (not just selected ones) - Implement header blacklist to filter proxy-specific headers - Pass client headers through to Anthropic API via createHeaders() - Update ClaudeApiClient.forward() signature to accept client headers - Update test to reflect removal of 'default' project ID fallback Blacklisted headers (not forwarded): - host, connection, content-length, accept-encoding (infrastructure) - baggage, sentry-trace, sec-fetch-mode (tracing/security) - x-forwarded-for, x-real-ip (proxy headers) - msl-project-id, msl-account, x-api-key (internal headers) This ensures client headers like anthropic-beta, user-agent, x-stainless-* are properly forwarded to Anthropic API for correct request handling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Removed content-length and accept-encoding from the header blacklist to allow these client headers to be forwarded to Anthropic API. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Restored content-length and accept-encoding to the header blacklist to let fetch handle these headers automatically. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Removed token masking from authorization headers in logs to enable full debugging of authentication issues. Authorization headers are now logged in plain text for both incoming and outbound requests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Removed 'authorization' from the sensitive keys list and removed Bearer token masking to enable full debugging of authentication issues. Authorization headers are now logged in plain text. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Changed authentication priority to ensure user-provided Bearer tokens always take precedence over project default accounts. This allows users to use their own credentials even when a project has a default account. New priority order: 1. MSL-Account header (explicit account selection) 2. Bearer token in Authorization header (user passthrough) 3. Project default account Previously, the project default account would be used even when a user provided their own Bearer token, which prevented user passthrough mode from working correctly. Added test to verify user token takes priority over default account. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Changed authentication priority to make user-provided Bearer tokens the absolute highest priority, even above MSL-Account header. New priority order: 1. Bearer token in Authorization header (user passthrough) 2. MSL-Account header (explicit account selection) 3. Project default account This ensures user credentials are always respected first. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Added 'authorization' to the header blacklist to prevent duplicate Authorization headers when forwarding requests to Anthropic API. The client's authorization header (lowercase) was being included in client headers, and then the auth service was adding Authorization (capitalized) from authHeaders, resulting in both headers being sent. Now the authorization header is filtered from client headers and only the one from authHeaders is used, preventing duplicates. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Updated documentation to reflect final implementation: ADR-030 Updates: - Changed authentication priority: Bearer token now highest priority - Added comprehensive header passthrough section - Documented blacklisted headers and rationale - Added logging note about plain text authorization headers API Reference Updates: - Made MSL-Project-Id mandatory (no longer optional) - Updated authentication priority order - Added User Passthrough Mode section with examples - Clarified billing and credential forwarding behavior 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Moved baggage, sentry-trace, and sec-fetch-mode from blacklisted to forwarded headers section. These tracing/security headers are now forwarded to Anthropic API. Updated header blacklist now only includes: - Infrastructure headers (host, connection, content-length, accept-encoding) - Proxy headers (x-forwarded-for, x-real-ip) - Internal headers (msl-project-id, msl-account, x-api-key, authorization) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implements user credential passthrough mode, allowing projects to accept user-provided Anthropic credentials instead of requiring organization-managed accounts. Users can now pass their own
Authorization: Bearer <token>headers, which are forwarded directly to Anthropic API with full header preservation.Key Features
1. User Passthrough Mode
default_account_id = nullaccept user-provided Bearer tokens2. Authentication Priority (Updated)
3. Comprehensive Header Passthrough
4. Mandatory Project Identification
MSL-Project-Idheader now mandatory for all requests5. Enhanced Logging
Technical Implementation
Database Migration
default_account_idnullable with documentationCore Changes
Dashboard
default_account_id = nullTesting
Documentation
Backward Compatibility
✅ Existing projects continue working unchanged
✅ Default behavior still assigns random organization account
✅ No breaking changes to API or database schema
Usage Example
Related ADRs
Test Plan
🤖 Generated with Claude Code