{"record":{"id":"6aa62f687f9b92d1","repo":"Hmbown/CodeWhale","slug":"agent-profile-may-not-request-allow-shell-true","errorCode":null,"errorMessage":"agent profile {} may not request allow_shell=true","messagePattern":"agent profile (.+?) may not request allow_shell=true","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/profile.rs","lineNumber":442,"sourceCode":"    tools: Option<&AgentProfileTools>,\n    permissions: Option<&AgentProfilePermissionsToml>,\n) -> Result<()> {\n    if let Some(posture) = tools\n        .and_then(|tools| tools.posture.as_deref())\n        .and_then(trimmed_non_empty)\n    {\n        match posture {\n            \"read-only\" | \"readonly\" | \"read_only\" => {}\n            other => bail!(\n                \"agent profile {} tools.posture={other:?} would widen permissions; use FleetProfile policy for grants\",\n                path.display()\n            ),\n        }\n    }\n\n    if let Some(permissions) = permissions {\n        if permissions.allow_shell.unwrap_or(false) {\n            bail!(\n                \"agent profile {} may not request allow_shell=true\",\n                path.display()\n            );\n        }\n        if permissions.trust.unwrap_or(false) {\n            bail!(\n                \"agent profile {} may not request trust=true\",\n                path.display()\n            );\n        }\n        if permissions.approval_required == Some(false) {\n            bail!(\n                \"agent profile {} may not disable approval_required\",\n                path.display()\n            );\n        }\n    }\n    Ok(())","sourceCodeStart":424,"sourceCodeEnd":460,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/profile.rs#L424-L460","documentation":"Agent profile files may not request permissions.allow_shell = true. Shell access is a security-relevant grant that must come from the FleetProfile policy, not from a self-declared profile, so the loader rejects the file outright (the check treats an absent flag as false).","triggerScenarios":"An agent profile TOML containing [permissions] allow_shell = true.","commonSituations":"Trying to let a profile run shell commands by editing its TOML; copying a profile from a setup where shell was profile-level; testing whether the flag is honored.","solutions":["Remove allow_shell (or set it to false) from the profile's [permissions] block","If the worker genuinely needs shell, grant it centrally in the FleetProfile policy with review","Prefer read-only tools in the profile and keep privileged capabilities out of worker-declared files"],"exampleFix":"# before\n[permissions]\nallow_shell = true\n\n# after\n[permissions]\nallow_shell = false","handlingStrategy":"validation","validationCode":"fn profile_permissions_ok(permissions: &Option<AgentProfilePermissionsToml>) -> bool {\n    permissions\n        .as_ref()\n        .map(|p| !p.allow_shell.unwrap_or(false))\n        .unwrap_or(true)\n}","typeGuard":null,"tryCatchPattern":"if let Err(err) = load_agent_profile_file(&path) {\n    if err.to_string().contains(\"allow_shell=true\") {\n        eprintln!(\"remove allow_shell from the profile; grant shell centrally via FleetProfile policy\");\n    }\n    return Err(err.into());\n}","preventionTips":["Never put permission grants in worker-declared profile files","Review FleetProfile policy diffs instead of editing profiles to add capabilities","Lint checked-in profiles for allow_shell/trust keys in CI"],"tags":["fleet","agent-profiles","permissions","security","configuration","rust","codewhale"],"backgroundTag":"permission-escalation-rejected","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}