Add per-project full permissions toggle for --dangerously-skip-permissions
All checks were successful
Build App / compute-version (push) Successful in 4s
Build App / build-macos (push) Successful in 2m19s
Build App / build-windows (push) Successful in 2m35s
Build App / build-linux (push) Successful in 4m43s
Build App / create-tag (push) Successful in 4s
Build App / sync-to-github (push) Successful in 11s

New projects default to standard permission mode (Claude asks before acting).
Existing projects default to full permissions ON, preserving current behavior.
UI toggle uses red/caution styling to highlight the security implications.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 08:58:13 -07:00
parent d7d7a83aec
commit b952b8e8de
6 changed files with 62 additions and 8 deletions

View File

@@ -17,10 +17,11 @@ fn build_terminal_cmd(project: &Project, state: &AppState) -> Vec<String> {
.unwrap_or(false);
if !is_bedrock_profile {
return vec![
"claude".to_string(),
"--dangerously-skip-permissions".to_string(),
];
let mut cmd = vec!["claude".to_string()];
if project.full_permissions {
cmd.push("--dangerously-skip-permissions".to_string());
}
return cmd;
}
// Resolve AWS profile: project-level → global settings → "default"
@@ -33,6 +34,12 @@ fn build_terminal_cmd(project: &Project, state: &AppState) -> Vec<String> {
// Build a bash wrapper that validates credentials, re-auths if needed,
// then exec's into claude.
let claude_cmd = if project.full_permissions {
"exec claude --dangerously-skip-permissions"
} else {
"exec claude"
};
let script = format!(
r#"
echo "Validating AWS session for profile '{profile}'..."
@@ -58,9 +65,10 @@ else
echo ""
fi
fi
exec claude --dangerously-skip-permissions
{claude_cmd}
"#,
profile = profile
profile = profile,
claude_cmd = claude_cmd
);
vec![

View File

@@ -24,6 +24,10 @@ fn default_protocol() -> String {
"tcp".to_string()
}
fn default_full_permissions() -> bool {
true
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Project {
pub id: String,
@@ -40,6 +44,8 @@ pub struct Project {
pub allow_docker_access: bool,
#[serde(default)]
pub mission_control_enabled: bool,
#[serde(default = "default_full_permissions")]
pub full_permissions: bool,
pub ssh_key_path: Option<String>,
#[serde(skip_serializing, default)]
pub git_token: Option<String>,
@@ -162,6 +168,7 @@ impl Project {
openai_compatible_config: None,
allow_docker_access: false,
mission_control_enabled: false,
full_permissions: false,
ssh_key_path: None,
git_token: None,
git_user_name: None,

View File

@@ -712,6 +712,32 @@ export default function ProjectCard({ project }: Props) {
</button>
</div>
{/* Full Permissions toggle */}
<div className="flex items-center gap-2">
<label className="text-xs text-[var(--text-secondary)]">
Full Permissions
<span className="text-[var(--error)] font-semibold ml-1">(CAUTION)</span>
<Tooltip text="When enabled, Claude runs with --dangerously-skip-permissions and auto-approves all tool calls without prompting. Only enable this if you trust the sandboxed environment to contain all actions. When disabled, Claude will ask for your approval before running commands, editing files, etc." />
</label>
<button
onClick={async () => {
try {
await update({ ...project, full_permissions: !project.full_permissions });
} catch (err) {
console.error("Failed to update full permissions setting:", err);
}
}}
disabled={!isStopped}
className={`px-2 py-0.5 text-xs rounded transition-colors disabled:opacity-50 ${
project.full_permissions
? "bg-[var(--error)] text-white"
: "bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-secondary)]"
}`}
>
{project.full_permissions ? "ON" : "OFF"}
</button>
</div>
{/* Environment Variables */}
<div className="flex items-center justify-between">
<label className="text-xs text-[var(--text-secondary)]">

View File

@@ -26,6 +26,7 @@ export interface Project {
openai_compatible_config: OpenAiCompatibleConfig | null;
allow_docker_access: boolean;
mission_control_enabled: boolean;
full_permissions: boolean;
ssh_key_path: string | null;
git_token: string | null;
git_user_name: string | null;