Permessi SDK

Il Claude Code SDK fornisce potenti controlli dei permessi che ti permettono di gestire come Claude utilizza gli strumenti nella tua applicazione. Questa guida copre come implementare sistemi di permessi utilizzando il callback canUseTool, gli hook e le regole di permesso di settings.json. Per la documentazione completa dell’API, consulta il riferimento TypeScript SDK.

Panoramica

Il Claude Code SDK fornisce quattro modi complementari per controllare l’uso degli strumenti:
  1. Modalità di Permesso - Impostazioni globali del comportamento dei permessi che influenzano tutti gli strumenti
  2. callback canUseTool - Gestore di permessi runtime per casi non coperti da altre regole
  3. Hook - Controllo granulare su ogni esecuzione di strumento con logica personalizzata
  4. Regole di permesso (settings.json) - Regole dichiarative di permesso/negazione con parsing integrato dei comandi bash
Casi d’uso per ogni approccio:
  • Modalità di permesso - Imposta il comportamento generale dei permessi (pianificazione, accettazione automatica delle modifiche, bypass dei controlli)
  • canUseTool - Approvazione dinamica per casi non coperti, richiede il permesso all’utente
  • Hook - Controllo programmatico su tutte le esecuzioni degli strumenti
  • Regole di permesso - Politiche statiche con parsing intelligente dei comandi bash

Diagramma del Flusso dei Permessi

Ordine di Elaborazione: Hook PreToolUse → Regole Ask → Regole Deny → Controllo Modalità Permesso → Regole Allow → Callback canUseTool → Hook PostToolUse

Modalità di Permesso

Le modalità di permesso forniscono controllo globale su come Claude utilizza gli strumenti. Puoi impostare la modalità di permesso quando chiami query() o cambiarla dinamicamente durante le sessioni di streaming.

Modalità Disponibili

L’SDK supporta quattro modalità di permesso, ognuna con comportamento diverso:
ModalitàDescrizioneComportamento Strumento
defaultComportamento standard dei permessiSi applicano i controlli normali dei permessi
planModalità pianificazione - nessuna esecuzioneClaude può utilizzare solo strumenti di sola lettura; presenta un piano prima dell’esecuzione (Attualmente non supportato nell’SDK)
acceptEditsAccetta automaticamente le modifiche ai fileLe modifiche ai file e le operazioni del filesystem vengono approvate automaticamente
bypassPermissionsBypassa tutti i controlli dei permessiTutti gli strumenti vengono eseguiti senza richieste di permesso (usa con cautela)

Impostazione della Modalità di Permesso

Puoi impostare la modalità di permesso in due modi:

1. Configurazione Iniziale

Imposta la modalità quando crei una query:
import { query } from "@anthropic-ai/claude-code";

const result = await query({
  prompt: "Aiutami a refactorizzare questo codice",
  options: {
    permissionMode: 'default'  // Modalità permesso standard
  }
});

2. Cambiamenti Dinamici della Modalità (Solo Streaming)

Cambia la modalità durante una sessione di streaming:
import { query } from "@anthropic-ai/claude-code";

// Crea un generatore asincrono per l'input di streaming
async function* streamInput() {
  yield { 
    type: 'user',
    message: { 
      role: 'user', 
      content: "Iniziamo con i permessi predefiniti" 
    }
  };
  
  // Più tardi nella conversazione...
  yield {
    type: 'user',
    message: {
      role: 'user',
      content: "Ora acceleriamo lo sviluppo"
    }
  };
}

const q = query({
  prompt: streamInput(),
  options: {
    permissionMode: 'default'  // Inizia in modalità predefinita
  }
});

// Cambia modalità dinamicamente
await q.setPermissionMode('acceptEdits');

// Elabora i messaggi
for await (const message of q) {
  console.log(message);
}

Comportamenti Specifici delle Modalità

Modalità Accetta Modifiche (acceptEdits)

In modalità accetta modifiche:
  • Tutte le modifiche ai file vengono approvate automaticamente
  • Le operazioni del filesystem (mkdir, touch, rm, ecc.) vengono auto-approvate
  • Altri strumenti richiedono ancora permessi normali
  • Accelera lo sviluppo quando ti fidi delle modifiche di Claude
  • Utile per prototipazione rapida e iterazioni
Operazioni auto-approvate:
  • Modifiche ai file (strumenti Edit, MultiEdit, Write)
  • Comandi bash del filesystem (mkdir, touch, rm, mv, cp)
  • Creazione ed eliminazione di file

Modalità Bypass Permessi (bypassPermissions)

In modalità bypass permessi:
  • TUTTI gli usi degli strumenti vengono approvati automaticamente
  • Non appaiono richieste di permesso
  • Gli hook vengono ancora eseguiti (possono ancora bloccare le operazioni)
  • Usa con estrema cautela - Claude ha accesso completo al sistema
  • Raccomandato solo per ambienti controllati

Priorità della Modalità nel Flusso dei Permessi

Le modalità di permesso vengono valutate in un punto specifico del flusso dei permessi:
  1. Gli hook vengono eseguiti per primi - Possono sovrascrivere qualsiasi modalità
  2. Le regole di negazione vengono controllate - Bloccano gli strumenti indipendentemente dalla modalità
  3. Modalità bypassPermissions - Se attiva, permette tutti gli strumenti rimanenti
  4. Le regole di permesso vengono controllate
  5. Altre modalità influenzano comportamenti specifici degli strumenti
  6. Callback canUseTool - Gestisce i casi rimanenti
Questo significa:
  • Gli hook possono sempre bloccare l’uso degli strumenti, anche in modalità bypassPermissions
  • Le regole di negazione esplicite sovrascrivono tutte le modalità di permesso
  • La modalità bypassPermissions sovrascrive le regole di permesso e canUseTool

Migliori Pratiche

  1. Usa la modalità predefinita per l’esecuzione controllata con controlli normali dei permessi
  2. Usa la modalità acceptEdits quando lavori su file o directory isolate
  3. Evita bypassPermissions in produzione o su sistemi con dati sensibili
  4. Combina le modalità con gli hook per controllo granulare
  5. Cambia modalità dinamicamente basandoti sul progresso del compito e sulla fiducia
Esempio di progressione delle modalità:
// Inizia in modalità predefinita per esecuzione controllata
permissionMode: 'default'

// Passa a acceptEdits per iterazione rapida
await q.setPermissionMode('acceptEdits')

canUseTool

Il callback canUseTool viene passato come opzione quando si chiama la funzione query. Riceve il nome dello strumento e i parametri di input, e deve restituire una decisione - permettere o negare. canUseTool si attiva ogni volta che Claude Code mostrerebbe una richiesta di permesso a un utente, ad esempio quando gli hook e le regole di permesso non lo coprono e non è in modalità accettazione automatica. Ecco un esempio completo che mostra come implementare l’approvazione interattiva degli strumenti:
import { query } from "@anthropic-ai/claude-code";

async function promptForToolApproval(toolName: string, input: any) {
  console.log("\n🔧 Richiesta Strumento:");
  console.log(`   Strumento: ${toolName}`);
  
  // Mostra i parametri dello strumento
  if (input && Object.keys(input).length > 0) {
    console.log("   Parametri:");
    for (const [key, value] of Object.entries(input)) {
      let displayValue = value;
      if (typeof value === 'string' && value.length > 100) {
        displayValue = value.substring(0, 100) + "...";
      } else if (typeof value === 'object') {
        displayValue = JSON.stringify(value, null, 2);
      }
      console.log(`     ${key}: ${displayValue}`);
    }
  }
  
  // Ottieni l'approvazione dell'utente (sostituisci con la tua logica UI)
  const approved = await getUserApproval();
  
  if (approved) {
    console.log("   ✅ Approvato\n");
    return {
      behavior: "allow",
      updatedInput: input
    };
  } else {
    console.log("   ❌ Negato\n");
    return {
      behavior: "deny",
      message: "L'utente ha negato il permesso per questo strumento"
    };
  }
}

// Usa il callback dei permessi
const result = await query({
  prompt: "Aiutami ad analizzare questa codebase",
  options: {
    canUseTool: async (toolName, input) => {
      return promptForToolApproval(toolName, input);
    }
  }
});

Utilizzo degli Hook per il Controllo degli Strumenti

Gli hook forniscono controllo programmatico sull’esecuzione degli strumenti in varie fasi. Gli hook vengono chiamati per ogni uso di strumento, dandoti controllo completo sulla pipeline dei permessi.

Implementazione degli Hook

import { query } from "@anthropic-ai/claude-code";

const result = await query({
  prompt: "Aiutami a refactorizzare questo codice",
  options: {
    hooks: {
      PreToolUse: [{
        hooks: [async (input, toolUseId, { signal }) => {
          console.log(`Richiesta strumento: ${input.tool_name}`);
          
          // Analizza e valida l'input dello strumento da solo
          if (input.tool_name === "Bash") {
            const command = input.tool_input.command;
            if (command.startsWith("rm -rf")) {
              return {
                decision: "block",
                reason: "Comando pericoloso bloccato"
              };
            }
          }
          
          return { continue: true };
        }]
      }],
      PostToolUse: [{
        hooks: [async (input, toolUseId, { signal }) => {
          console.log(`Strumento completato: ${input.tool_name}`);
          // Registra o controlla i risultati degli strumenti
          return { continue: true };
        }]
      }]
    }
  }
});

Differenze Chiave da canUseTool

  • Ambito: Gli hook vengono chiamati per tutti gli usi degli strumenti; canUseTool gestisce i casi non coperti dalle regole di permesso
  • Controllo: Gli hook richiedono di analizzare e validare gli input da soli
  • Eventi: Gli hook supportano eventi multipli (PreToolUse, PostToolUse, ecc.) per diverse fasi

Utilizzo delle Regole di Permesso (settings.json)

Le regole di permesso in settings.json forniscono controllo dichiarativo con parsing integrato dei comandi bash. Queste regole vengono valutate prima che venga chiamato canUseTool. Per maggiori dettagli sulla configurazione delle impostazioni, consulta la documentazione delle impostazioni di Claude Code.

Struttura di Configurazione

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Read(~/.zshrc)"
    ],
    "deny": [
      "Bash(curl:*)",
      "Read(./.env)",
      "Read(./secrets/**)",
      "WebFetch"
    ],
    "ask": [
      "Bash(git push:*)",
      "Write(./production/**)"
    ]
  }
}

Sintassi delle Regole

Le regole di permesso seguono il pattern: NomeStrumento(pattern)
  • Regole Bash: Usano corrispondenza per prefisso (non regex). Esempio: Bash(npm:*) corrisponde a qualsiasi comando che inizia con “npm”
  • Regole File: Supportano pattern glob. Esempio: Read(./src/**/*.ts) corrisponde ai file TypeScript in src
  • Regole solo-strumento: Ometti le parentesi per controllare interi strumenti. Esempio: WebFetch blocca tutti i fetch web

Utilizzo con SDK

Mentre le regole non possono ancora essere impostate programmaticamente nell’SDK, verranno lette dal file settings.json nel percorso in cui viene caricato l’SDK.

Ordine di Valutazione dei Permessi

  1. Le regole di negazione vengono controllate per prime - se corrispondono, l’uso dello strumento viene bloccato
  2. Le regole di permesso vengono controllate dopo - se corrispondono, l’uso dello strumento è permesso
  3. Le regole di richiesta vengono controllate - se corrispondono, l’utente viene sollecitato
  4. Il callback canUseTool viene invocato per tutti i casi rimanenti

Parsing dei Comandi Bash

L’SDK include un parser bash integrato che comprende la struttura dei comandi:
  • Gestisce pipe, redirect e sostituzione di comandi
  • Riconosce pattern pericolosi come rm -rf o curl | sh
  • Supporta wildcard e corrispondenza per prefisso
Esempio di come funzionano i pattern bash:
  • Bash(git:*) - Corrisponde a qualsiasi comando git
  • Bash(npm run test) - Corrisponde al comando esatto
  • Bash(npm run test:*) - Corrisponde a npm run test:unit, test:integration, ecc.

Migliori Pratiche

  1. Inizia con la modalità predefinita per controlli standard dei permessi
  2. Usa le regole di permesso per politiche statiche, specialmente comandi bash (vedi impostazioni dei permessi)
  3. Usa gli hook per registrare, controllare o trasformare tutti gli usi degli strumenti (vedi tipi di hook)
  4. Usa canUseTool per decisioni dinamiche sui casi non coperti (vedi tipo CanUseTool)
  5. Stratifica le difese combinando modalità, regole, hook e callback per applicazioni critiche