feat(auth): add multi-provider authentication with secure credential storage

Authentication System:
- Add credentials crate with keyring (OS keychain) and file fallback storage
- Add auth-manager crate for unified auth across providers
- Implement API key login flow for Anthropic, OpenAI, and Ollama Cloud
- Add CLI commands: login, logout, auth (status)
- Store credentials securely in macOS Keychain / GNOME Keyring / Windows Credential Manager

API Key Helpers:
- Support for password manager integration (1Password, Bitwarden, pass, AWS Secrets, Vault)
- Command-based helpers with TTL caching
- Priority chain: env vars → helpers → cache → stored credentials

Background Token Refresh:
- Automatic OAuth token refresh before expiration
- Configurable check interval and refresh threshold

MCP OAuth Support:
- Add OAuth config to MCP server definitions
- Support for SSE/HTTP transport with OAuth
- Token storage with mcp: prefix

Bug Fixes:
- Fix keyring crate requiring explicit backend features (was using mock store)
- Fix provider index not updated on credential store
- Add User-Agent headers to avoid Cloudflare blocks

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-03 00:27:37 +01:00
parent 4a07b97eab
commit 5b0774958a
21 changed files with 3100 additions and 40 deletions

View File

@@ -36,12 +36,63 @@ pub struct PluginManifest {
/// MCP server configuration in plugin manifest
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct McpServerConfig {
/// Unique name for this MCP server
pub name: String,
pub command: String,
/// Transport type: "stdio" (default), "sse", or "http"
#[serde(default = "default_transport_type")]
pub transport: McpTransportType,
/// Command to spawn (for stdio transport)
#[serde(default)]
pub command: Option<String>,
/// Arguments for the command (for stdio transport)
#[serde(default)]
pub args: Vec<String>,
/// Environment variables (for stdio transport)
#[serde(default)]
pub env: HashMap<String, String>,
/// URL endpoint (for sse/http transports)
#[serde(default)]
pub url: Option<String>,
/// OAuth configuration (for authenticated servers)
#[serde(default)]
pub oauth: Option<McpOAuthConfig>,
}
fn default_transport_type() -> McpTransportType {
McpTransportType::Stdio
}
/// Transport type for MCP servers
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum McpTransportType {
#[default]
Stdio,
Sse,
Http,
}
/// OAuth configuration for MCP servers
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct McpOAuthConfig {
/// OAuth client ID
pub client_id: String,
/// OAuth scopes to request
#[serde(default)]
pub scopes: Vec<String>,
/// Custom authorization URL (optional, uses server default)
pub auth_url: Option<String>,
/// Custom token URL (optional, uses server default)
pub token_url: Option<String>,
}
/// Plugin hook configuration from hooks/hooks.json