Simplify auth modes to Anthropic and Bedrock, fix Windows taskbar icon
Replace the three auth modes (Login, API Key, Bedrock) with two (Anthropic, Bedrock). The Anthropic mode uses OAuth via `claude login` inside the terminal, which generates and stores its own API key in the persistent config volume. The separate API Key mode is removed because Claude Code now requires interactive approval of externally-provided keys, making the injected ANTHROPIC_API_KEY approach unreliable. Old projects stored as "login" or "api_key" are automatically migrated to "anthropic" via serde aliases. Also fix the Windows taskbar icon showing as a black square by loading icon.png instead of icon.ico for the runtime window icon. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -47,8 +47,7 @@ Triple-C is a cross-platform desktop application that sandboxes Claude Code insi
|
||||
|
||||
Each project can independently use one of:
|
||||
|
||||
- **`/login`** (OAuth): User runs `claude login` inside the terminal. Token persisted in the config volume.
|
||||
- **API Key**: Stored in the OS keychain, injected as `ANTHROPIC_API_KEY` env var.
|
||||
- **Anthropic** (OAuth): User runs `claude login` inside the terminal on first use. Token persisted in the config volume across restarts and resets.
|
||||
- **AWS Bedrock**: Per-project AWS credentials (static keys, profile, or bearer token).
|
||||
|
||||
### Container Spawning (Sibling Containers)
|
||||
|
||||
@@ -126,12 +126,7 @@ pub async fn start_project_container(
|
||||
|
||||
// Get API key only if auth mode requires it
|
||||
let api_key = match project.auth_mode {
|
||||
AuthMode::ApiKey => {
|
||||
let key = secure::get_api_key()?
|
||||
.ok_or_else(|| "No API key configured. Please set your Anthropic API key in Settings.".to_string())?;
|
||||
Some(key)
|
||||
}
|
||||
AuthMode::Login => {
|
||||
AuthMode::Anthropic => {
|
||||
None
|
||||
}
|
||||
AuthMode::Bedrock => {
|
||||
|
||||
@@ -43,7 +43,7 @@ pub fn run() {
|
||||
exec_manager: ExecSessionManager::new(),
|
||||
})
|
||||
.setup(|app| {
|
||||
match tauri::image::Image::from_bytes(include_bytes!("../icons/icon.ico")) {
|
||||
match tauri::image::Image::from_bytes(include_bytes!("../icons/icon.png")) {
|
||||
Ok(icon) => {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.set_icon(icon);
|
||||
|
||||
@@ -46,20 +46,21 @@ pub enum ProjectStatus {
|
||||
}
|
||||
|
||||
/// How the project authenticates with Claude.
|
||||
/// - `Login`: User runs `claude login` inside the container (OAuth, persisted via config volume)
|
||||
/// - `ApiKey`: Uses the API key stored in the OS keychain
|
||||
/// - `Anthropic`: User runs `claude login` inside the container (OAuth via Anthropic Console,
|
||||
/// persisted in the config volume)
|
||||
/// - `Bedrock`: Uses AWS Bedrock with per-project AWS credentials
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AuthMode {
|
||||
Login,
|
||||
ApiKey,
|
||||
/// Backward compat: old projects stored as "login" or "api_key" map to Anthropic.
|
||||
#[serde(alias = "login", alias = "api_key")]
|
||||
Anthropic,
|
||||
Bedrock,
|
||||
}
|
||||
|
||||
impl Default for AuthMode {
|
||||
fn default() -> Self {
|
||||
Self::Login
|
||||
Self::Anthropic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ const mockProject: Project = {
|
||||
paths: [{ host_path: "/home/user/project", mount_name: "project" }],
|
||||
container_id: null,
|
||||
status: "stopped",
|
||||
auth_mode: "login",
|
||||
auth_mode: "anthropic",
|
||||
bedrock_config: null,
|
||||
allow_docker_access: false,
|
||||
ssh_key_path: null,
|
||||
|
||||
@@ -267,26 +267,15 @@ export default function ProjectCard({ project }: Props) {
|
||||
<div className="flex items-center gap-1 text-xs">
|
||||
<span className="text-[var(--text-secondary)] mr-1">Auth:</span>
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); handleAuthModeChange("login"); }}
|
||||
onClick={(e) => { e.stopPropagation(); handleAuthModeChange("anthropic"); }}
|
||||
disabled={!isStopped}
|
||||
className={`px-2 py-0.5 rounded transition-colors ${
|
||||
project.auth_mode === "login"
|
||||
project.auth_mode === "anthropic"
|
||||
? "bg-[var(--accent)] text-white"
|
||||
: "text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-primary)]"
|
||||
} disabled:opacity-50`}
|
||||
>
|
||||
/login
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); handleAuthModeChange("api_key"); }}
|
||||
disabled={!isStopped}
|
||||
className={`px-2 py-0.5 rounded transition-colors ${
|
||||
project.auth_mode === "api_key"
|
||||
? "bg-[var(--accent)] text-white"
|
||||
: "text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--bg-primary)]"
|
||||
} disabled:opacity-50`}
|
||||
>
|
||||
API key
|
||||
Anthropic
|
||||
</button>
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); handleAuthModeChange("bedrock"); }}
|
||||
|
||||
@@ -34,7 +34,7 @@ export type ProjectStatus =
|
||||
| "stopping"
|
||||
| "error";
|
||||
|
||||
export type AuthMode = "login" | "api_key" | "bedrock";
|
||||
export type AuthMode = "anthropic" | "bedrock";
|
||||
|
||||
export type BedrockAuthMethod = "static_credentials" | "profile" | "bearer_token";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user