> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Solicitudes de permiso

> Controla las solicitudes de permiso de Laravel Copilot SDK con los valores por defecto, los handlers integrados y callbacks de aprobación personalizados.

## Solicitudes de permiso

## Comportamiento por defecto (`deny-all`)

Cuando `permission_approve` de `config/copilot.php` vale `"deny-all"` (valor por defecto), las solicitudes de permiso en `Copilot::run()` y `Copilot::start()` se **deniegan** automáticamente.

En usos centrados en generación de texto no suele hacer falta ningún permiso, así que es un valor seguro por defecto.

```php theme={null}
// config/copilot.php
'permission_approve' => env('COPILOT_PERMISSION_APPROVE', 'deny-all'),
```

## Valores configurables

| Valor              | Comportamiento                                                                  |
| ------------------ | ------------------------------------------------------------------------------- |
| `"deny-all"`       | Deniega todo automáticamente (**por defecto**)                                  |
| `"approve-safety"` | Deniega solo `shell` y `write`, aprueba el resto automáticamente                |
| `"approve-all"`    | Aprueba todo automáticamente                                                    |
| `false`            | Sin handler. `onPermissionRequest` es obligatorio (igual que en el SDK oficial) |

```php theme={null}
// .env
COPILOT_PERMISSION_APPROVE="approve-safety"
```

<Warning>
  Si aceptas prompts de entrada del usuario, `"approve-safety"` y `"approve-all"` son peligrosos.
  Usa siempre `false` o `"deny-all"`.
  Incluso con permisos de solo lectura, es posible que se lea el código de tu proyecto Laravel.
</Warning>

## `PermissionHandler::approveAll()`

`PermissionHandler::approveAll()` aprueba todas las solicitudes automáticamente.

```php theme={null}
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Support\PermissionHandler;
use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    onPermissionRequest: PermissionHandler::approveAll(),
);

$response = Copilot::run(prompt: 'Hello', config: $config);
```

## `PermissionHandler::approveSafety()`

`PermissionHandler::approveSafety()` deniega únicamente los permisos de alto riesgo (`shell`, `write`) y aprueba el resto automáticamente.

```php theme={null}
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Support\PermissionHandler;
use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    onPermissionRequest: PermissionHandler::approveSafety(),
);

$response = Copilot::run(prompt: 'Hello', config: $config);
```

Aun así, no es completamente seguro.
Si quieres controlar de forma estricta, implementa un handler personalizado y decide inspeccionando `$request['kind']`.

## `PermissionHandler::denyAll()`

`PermissionHandler::denyAll()` deniega todo.

```php theme={null}
use Revolution\Copilot\Support\PermissionHandler;
use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    onPermissionRequest: PermissionHandler::denyAll(),
);
```

## Al usar Client directamente

Si utilizas `CopilotClient` directamente, indicar `onPermissionRequest` es **obligatorio**, igual que en el SDK oficial.

```php theme={null}
use Revolution\Copilot\Client;
use Revolution\Copilot\Support\PermissionHandler;

$client = new Client([
    'cli_path' => 'copilot',
    'cli_args' => [],
    'cwd' => base_path(),
    'log_level' => 'info',
    'env' => null,
]);
$client->start();

// onPermissionRequest es obligatorio
$session = $client->createSession([
    'onPermissionRequest' => PermissionHandler::approveSafety(),
]);

// Si lo omites, se lanza InvalidArgumentException
// $session = $client->createSession([]); // ¡Error!
```

## Handler personalizado

Para controlar autorización/denegación por tipo de solicitud, pasa una clausura.
`$request` e `$invocation` son arrays como los siguientes.

```php theme={null}
use Illuminate\Support\Facades\Artisan;
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Support\PermissionRequestResultKind;
use Revolution\Copilot\Types\SessionConfig;

use function Laravel\Prompts\{confirm, note, spin, text};

Artisan::command('copilot:chat', function () {
    $config = new SessionConfig(
        onPermissionRequest: function (array $request, array $invocation) {
            $confirm = confirm(
                label: 'Do you accept the requested permissions?',
            );
            if ($confirm) {
                return PermissionRequestResultKind::approveOnce();
            } else {
                return PermissionRequestResultKind::reject();
            }
        },
    );

    Copilot::start(function (CopilotSession $session) use ($config) {
        while (true) {
            $prompt = text(
                label: 'Enter your prompt',
                placeholder: 'Ask me anything...',
                required: true,
                hint: 'Ctrl+C to exit',
            );

            $response = spin(
                callback: fn () => $session->sendAndWait($prompt),
                message: 'Waiting for Copilot response...',
            );

            note($response->content());
        }
    }, config: $config);
});
```

### `$request`

Los campos distintos de `kind` y `toolCallId` varían según `kind`.

```text theme={null}
kind: "shell" | "write" | "mcp" | "read" | "url" | "custom-tool" | "memory" | "hook"
```

```php theme={null}
[
  "kind" => "shell",
  "toolCallId" => "toolu_...",
  "fullCommandText" => "...",
  "intention" => "Run copilot:ping to test permission request",
  "commands" => [
    [
      "identifier" => "bash",
      "readOnly" => false,
    ]
  ]
  "possiblePaths" => [],
  "possibleUrls" => [],
  "hasWriteFileRedirection" => false,
  "canOfferSessionApproval" => false,
]
```

### `$invocation`

```php theme={null}
[
  "sessionId" => "...",
]
```

## Response

El resultado de la decisión de permiso se devuelve como array.
La clase `PermissionRequestResultKind` mejora la legibilidad.

```php theme={null}
return PermissionRequestResultKind::approveOnce();
return PermissionRequestResultKind::reject();
```

## Detalle del protocolo

En Protocol v3 (el valor por defecto actual), las solicitudes de permiso se entregan como eventos de sesión (`permission.requested`), no como peticiones JSON-RPC.
El SDK las procesa internamente y responde con el RPC `session.permissions.handlePendingPermissionRequest`.

**El uso de `SessionConfig` no cambia.**
Si pasas un handler a `onPermissionRequest`, el SDK absorbe las diferencias de protocolo.

## PermissionRequestResultKind

También puedes devolver directamente algo como `['kind' => 'approve-once']`, pero usar `PermissionRequestResultKind` resulta más claro.

```php theme={null}
use Revolution\Copilot\Support\PermissionRequestResultKind;

$confirm = confirm(
    label: 'Do you accept the requested permissions?',
);

if ($confirm) {
    return PermissionRequestResultKind::approveOnce();
} else {
    return PermissionRequestResultKind::reject();
}
```

### Métodos disponibles

| Método                 | Valor                  | Descripción                                                                               |
| ---------------------- | ---------------------- | ----------------------------------------------------------------------------------------- |
| `approveOnce()`        | `approve-once`         | Aprueba solo esta solicitud                                                               |
| `approveForSession()`  | `approve-for-session`  | Aprueba todas las solicitudes del mismo tipo durante esta sesión                          |
| `approveForLocation()` | `approve-for-location` | Aprueba todas las solicitudes del mismo tipo desde esta ubicación (ruta de archivo, etc.) |
| `reject()`             | `reject`               | Rechaza la solicitud                                                                      |
| `userNotAvailable()`   | `user-not-available`   | Estado en el que el usuario no puede responder (entornos no interactivos, etc.)           |
| `noResult()`           | `no-result`            | Cuando el handler no puede devolver un resultado (omite la llamada RPC)                   |

Si quieres usar `Laravel\Prompts\select`, puedes obtener las opciones con `PermissionRequestResultKind::select()`.

```php theme={null}
use Revolution\Copilot\Support\PermissionRequestResultKind;
use function Laravel\Prompts\select;

$select = select(
    label: 'Do you accept the requested permissions?',
    options: PermissionRequestResultKind::select(),
);

return ['kind' => $select];
```

### no-result

Si el handler no puede devolver un resultado (por ejemplo, en un entorno no interactivo), puedes devolver `no-result`.
Al hacerlo, se omite la llamada RPC y se aplica la denegación por defecto de Copilot CLI.

```php theme={null}
return PermissionRequestResultKind::noResult();
// o ['kind' => 'no-result']
```

<Info>
  Consulta la información más reciente en el [repositorio de GitHub](https://github.com/invokable/laravel-copilot-sdk).
</Info>


## Related topics

- [Autenticación Service Account - Google Sheets API for Laravel](/es/packages/laravel-google-sheets/service-account.md)
- [Autorización (gates y policies)](/es/authorization.md)
- [Despliegue](/es/deployment.md)
- [Cloud Sessions](/es/packages/laravel-copilot-sdk/cloud-sessions.md)
- [Primeros pasos - GitHub Copilot SDK for Laravel](/es/packages/laravel-copilot-sdk/getting-started.md)
