# `ClaudeAgentSDK.Permission`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.15.0/lib/claude_agent_sdk/permission.ex#L1)

Permission System for Claude Agent SDK.

This module provides a structured permission system for controlling tool execution
at runtime through callbacks and permission modes.

## Permission Modes

The SDK supports six permission modes that control how tool permissions are handled:

- `:default` - All tools go through the permission callback
- `:accept_edits` - Edit operations (Write, Edit, MultiEdit) are auto-allowed
- `:plan` - Claude creates a plan, shows it to user, then executes after approval
- `:bypass_permissions` - All tools are allowed without callback invocation
- `:delegate` - Delegate tool execution to the SDK (CLI does not run built-in tools)
- `:dont_ask` - Do not prompt for permissions; tools proceed without callback

## Permission Callbacks

Permission callbacks allow fine-grained control over tool execution. They receive
context about the tool being used and return a permission result.

### Callback Signature

    (Context.t() -> Result.t())

### Example

    callback = fn context ->
      case context.tool_name do
        "Bash" ->
          if String.contains?(context.tool_input["command"], "rm -rf") do
            Result.deny("Dangerous command detected")
          else
            Result.allow()
          end

        "Write" ->
          # Redirect system file writes to safe location
          file_path = context.tool_input["file_path"]
          if String.starts_with?(file_path, "/etc/") do
            safe_path = "/tmp/safe_output/" <> Path.basename(file_path)
            Result.allow(updated_input: %{context.tool_input | "file_path" => safe_path})
          else
            Result.allow()
          end

        _ ->
          Result.allow()
      end
    end

    options = %Options{
      can_use_tool: callback,
      permission_mode: :default
    }

## Runtime Mode Switching

Permission mode can be changed at runtime using `Client.set_permission_mode/2`:

    {:ok, client} = Client.start_link(options)

    # Switch to plan mode
    Client.set_permission_mode(client, :plan)

    # Switch back to default
    Client.set_permission_mode(client, :default)

## Integration with Hooks

The permission system integrates with the existing hooks system. Permission
callbacks are invoked via the control protocol when the CLI requests permission
to use a tool. If the CLI does not emit `can_use_tool` requests, the SDK
automatically invokes the callback via a PreToolUse hook when possible.
In that hook-based path, `updated_permissions` updates are ignored.
When `can_use_tool` is set, the SDK enables partial messages and configures
the CLI permission prompt tool to `"stdio"` internally.

See:
- `ClaudeAgentSDK.Permission.Context` - Permission context structure
- `ClaudeAgentSDK.Permission.Result` - Permission result types

# `callback`

```elixir
@type callback() :: (ClaudeAgentSDK.Permission.Context.t() -&gt;
                 ClaudeAgentSDK.Permission.Result.t())
```

Permission callback function type.

Receives permission context and returns permission result.

# `permission_mode`

```elixir
@type permission_mode() ::
  :default | :accept_edits | :plan | :bypass_permissions | :delegate | :dont_ask
```

Permission mode controlling how tool permissions are handled.

# `mode_to_string`

```elixir
@spec mode_to_string(permission_mode()) :: String.t()
```

Converts permission mode atom to CLI string format.

## Examples

    iex> ClaudeAgentSDK.Permission.mode_to_string(:accept_edits)
    "acceptEdits"

    iex> ClaudeAgentSDK.Permission.mode_to_string(:default)
    "default"

# `string_to_mode`

```elixir
@spec string_to_mode(String.t()) :: permission_mode() | nil
```

Converts CLI permission mode string to atom.

Returns `nil` for unknown mode strings.

## Examples

    iex> ClaudeAgentSDK.Permission.string_to_mode("acceptEdits")
    :accept_edits

    iex> ClaudeAgentSDK.Permission.string_to_mode("invalid")
    nil

# `valid_mode?`

```elixir
@spec valid_mode?(term()) :: boolean()
```

Validates a permission mode.

Returns `true` if the mode is valid, `false` otherwise.

## Examples

    iex> ClaudeAgentSDK.Permission.valid_mode?(:default)
    true

    iex> ClaudeAgentSDK.Permission.valid_mode?(:invalid)
    false

# `valid_modes`

```elixir
@spec valid_modes() :: [permission_mode()]
```

Returns all valid permission modes.

## Examples

    iex> ClaudeAgentSDK.Permission.valid_modes()
    [:default, :accept_edits, :plan, :bypass_permissions, :delegate, :dont_ask]

# `validate_callback`

```elixir
@spec validate_callback(term()) :: :ok | {:error, String.t()}
```

Validates a permission callback function.

Returns `:ok` if the callback is valid, `{:error, reason}` otherwise.

## Examples

    iex> callback = fn _context -> Result.allow() end
    iex> ClaudeAgentSDK.Permission.validate_callback(callback)
    :ok

    iex> ClaudeAgentSDK.Permission.validate_callback("not a function")
    {:error, "Permission callback must be a function"}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
