Skip to main content

Module 08: Permission Modes

Controlling how Claude handles tool execution permissions.

What You’ll Learn

  • The four permission modes and when to use each
  • How permission modes affect tool execution
  • Best practices for production vs development

Permission Modes

ModeCLI FlagUse Case
DEFAULT--permission-mode defaultInteractive CLI, human approval
ACCEPT_EDITS--permission-mode acceptEditsAuto-approve edits, prompt for Bash
BYPASS_PERMISSIONS--permission-mode bypassPermissionsAutomated scripts, CI/CD
DANGEROUSLY_SKIP_PERMISSIONS--dangerously-skip-permissionsSandboxed environments only

Using Permission Modes

import org.springaicommunity.claude.agent.sdk.ClaudeClient;
import org.springaicommunity.claude.agent.sdk.ClaudeSyncClient;
import org.springaicommunity.claude.agent.sdk.config.PermissionMode;
import java.nio.file.Path;

// BYPASS_PERMISSIONS - most common for automated scripts
try (ClaudeSyncClient client = ClaudeClient.sync()
        .workingDirectory(Path.of("."))
        .permissionMode(PermissionMode.BYPASS_PERMISSIONS)
        .build()) {

    // Claude executes tools without prompting
    String answer = client.connectText("List files in the current directory");
    System.out.println(answer);
}

Mode Details

DEFAULT

.permissionMode(PermissionMode.DEFAULT)
  • Prompts for every tool use
  • Best for interactive CLI sessions
  • User must approve each operation

ACCEPT_EDITS

.permissionMode(PermissionMode.ACCEPT_EDITS)
  • Auto-approves file editing tools (Read, Write, Edit)
  • Still prompts for shell commands (Bash)
  • Good balance of automation and safety

BYPASS_PERMISSIONS

.permissionMode(PermissionMode.BYPASS_PERMISSIONS)
  • Skips all permission prompts
  • Most common for SDK usage
  • Use with allowedTools/disallowedTools for safety

DANGEROUSLY_SKIP_PERMISSIONS

.permissionMode(PermissionMode.DANGEROUSLY_SKIP_PERMISSIONS)
  • Uses a different CLI flag (--dangerously-skip-permissions) than BYPASS_PERMISSIONS (--permission-mode bypassPermissions)
  • Both skip permission prompts; the behavioral difference is minimal
  • The explicit “dangerous” naming serves as a code-level warning to reviewers
  • Intended for fully sandboxed environments (containers, VMs) without network access
  • Use BYPASS_PERMISSIONS for most automated use cases; reserve this for true sandboxes

Best Practices

EnvironmentRecommended ModeAdditional Safety
DevelopmentBYPASS_PERMISSIONSNone needed
CI/CDBYPASS_PERMISSIONSdisallowedTools(["Bash"])
ProductionBYPASS_PERMISSIONSallowedTools to limit scope
SandboxDANGEROUSLY_SKIP_PERMISSIONSNetwork isolation

Combining with Tool Permissions

For maximum safety, combine permission modes with tool restrictions:
try (ClaudeSyncClient client = ClaudeClient.sync()
        .workingDirectory(Path.of("."))
        .permissionMode(PermissionMode.BYPASS_PERMISSIONS)
        .allowedTools(List.of("Read", "Grep", "Glob"))  // Only these tools
        .build()) {

    // Claude can only read, not modify
    String answer = client.connectText("What's in the README?");
    System.out.println(answer);
}

Tradeoffs

  • DEFAULT mode provides safety but blocks automation - Claude waits for approval that never comes in non-interactive contexts.
  • BYPASS_PERMISSIONS is required for automation but shifts responsibility to your code for safety (use tool restrictions).
  • Permission modes are session-wide. You cannot require approval for some tools while bypassing others (use permission callbacks for fine-grained control - see Module 13).
  • No audit log is generated when permissions are bypassed. Implement your own logging if needed.
  • Claude may still refuse unsafe operations even with permissions bypassed, based on its training.

Source Code

View on GitHub

Running the Example

mvn compile exec:java -pl module-08-permission-modes

Next Module

Module 09: Structured Outputs - Get Claude to return structured JSON responses.