SpyBara
Go Premium

plugins/mods/admin.md 2026-10-01 23:59 UTC to 2026-10-02 20:57 UTC

This page contains 195 additions and 144 deletions.

2026
Thu 1 23:59 Fri 2 22:00

Gestire i mod per la tua organizzazione

Controlla i mod di Claude Code con le impostazioni gestite: blocca i mod installati dagli utenti, consenti solo i tuoi, verifica cosa può fare un mod e applica le policy con un tuo mod.

Un mod è un plugin che esegue codice all'interno di Claude Code con i permessi dell'utente che lo ha installato. I mod non sono isolati in una sandbox. Tramite le impostazioni gestite, decidi se i mod vengono eseguiti sui computer dei tuoi utenti, quali e in quale ordine. Puoi anche installare un tuo mod che osserva o rifiuta ciò che fanno gli altri mod.

Questa pagina è rivolta a chi distribuisce le impostazioni gestite per Claude Code, sia come file, tramite MDM o dalla console di amministrazione di claude.ai. I mod sono attivi per impostazione predefinita in Claude Code v2.1.287 e versioni successive. Inizia dalla sezione che corrisponde a ciò che vuoi fare:

Impedire il caricamento dei mod installati dagli utenti

Per impedire il caricamento di tutti i mod portati dai tuoi utenti, imposta l'opzione allowManagedModsOnly sulla protezione integrata, un mod di criteri che Claude Code carica prima di ogni mod installato da un utente. L'opzione va nelle impostazioni gestite sotto pluginConfigs, con chiave cc-plugin-sec-default@builtin:

{
  "pluginConfigs": {
    "cc-plugin-sec-default@builtin": {
      "options": {
        "allowManagedModsOnly": true
      }
    }
  }
}

Con l'opzione impostata nelle impostazioni gestite:

  • Nessun mod portato da un utente viene caricato: questo include un mod in un plugin installato dall'utente, un mod caricato con --plugin-dir e un mod scritto da Claude durante una sessione
  • I mod della tua organizzazione vengono comunque caricati: un mod che conta come appartenente alla tua organizzazione non viene controllato. Ogni altro mod conta come appartenente a un utente e non viene caricato. Questo include un mod in un plugin che abiliti da GitHub o da un altro marketplace remoto, e uno che la tua organizzazione attiva per i propri membri su claude.ai. Se nessuno conta come tuo, nessun mod installato viene caricato.
  • Gli utenti non possono annullarlo: la protezione integrata legge l'opzione solo dalle impostazioni gestite, quindi la stessa voce in un file di impostazioni utente, di progetto o locale, o in un file passato con --settings, non cambia nulla
  • Un file o un criterio MDM copre ogni provider: quando distribuisci l'opzione come file o tramite MDM, funziona allo stesso modo su Amazon Bedrock, Agent Platform di Google Cloud e Microsoft Foundry. Per la distribuzione dalla console di amministrazione di claude.ai, consulta Disponibilità delle piattaforme
  • Le altre personalizzazioni degli utenti continuano a funzionare: i loro hook nei file di impostazioni, le righe di stato e /goal non sono interessati
  • I mod integrati continuano a funzionare: i mod integrati in Claude Code, come il supporto per AGENTS.md, hanno ciascuno il proprio interruttore

Per verificare l'opzione sul computer di un utente, avvia lì Claude Code con --plugin-dir e il percorso di una directory che contiene un mod, ad esempio claude --plugin-dir ./first-mod. Gli hook del mod non vengono eseguiti, e la trascrizione e il log di debug contengono il messaggio della protezione integrata, che indica il nome del mod e allowManagedModsOnly. Se il mod viene caricato, consulta Verificare che un criterio sia in vigore e le regole che determinano se un'opzione ha effetto.

Se durante l'accesso anticipato hai impostato CLAUDE_CODE_ENABLE_FUNCTION_HOOKS su 0, sostituiscila con questa opzione. Claude Code v2.1.287 e versioni successive ignorano la variabile con qualsiasi valore, quindi un 0 lascia i mod attivi.

Sapere cosa succede per impostazione predefinita

Senza impostazioni dei mod tue, ecco cosa ottengono i tuoi utenti:

  • I mod sono attivi. Un utente può installare un plugin che contiene un mod da qualsiasi marketplace consentito dalle tue impostazioni dei plugin, oppure caricarne uno da una directory con --plugin-dir.

  • Una protezione integrata viene eseguita per prima. Claude Code carica un mod integrato chiamato sec-default@builtin prima di ogni mod installato da un utente. Gli utenti non possono disattivarlo. /plugin e il log di debug lo elencano come cc-plugin-sec-default. La protezione viene caricata quando è vera una di queste condizioni:

    • La macchina ha impostazioni gestite
    • L'utente ha effettuato l'accesso a Claude Code con un piano Team o Enterprise

    Un utente che si autentica con una chiave API, oppure tramite Amazon Bedrock, Agent Platform di Google Cloud o Microsoft Foundry, ottiene la protezione solo su una macchina che ha impostazioni gestite.

  • La protezione tutela ciò che gestisci. Il mod di un utente non può modificare ciò che i tuoi hook gestiti ricevono o decidono, il prompt di sistema, il tuo CLAUDE.md gestito e le altre istruzioni gestite, ciò che qualsiasi mod legge come impostazioni, né gli strumenti e le descrizioni dei tuoi server MCP gestiti.

  • Tutto il resto è consentito. La protezione non aggiunge altre restrizioni. Il mod di un utente può comunque leggere e scrivere file, avviare processi, effettuare richieste di rete, riscrivere chiamate agli strumenti e prompt, negare una chiamata a uno strumento, approvarne una che altrimenti richiederebbe conferma e disegnare nell'interfaccia, il tutto con i permessi di quell'utente.

  • Le regole deny e i tuoi hook gestiti hanno la precedenza. Dove la protezione viene caricata, il mod di un utente non può approvare una chiamata che una regola deny rifiuta, qualunque sia il file di impostazioni che contiene la regola. Anche un blocco da un hook PreToolUse nelle impostazioni gestite è definitivo. Entrambi si applicano alle chiamate agli strumenti di Claude. Nessuno dei due si applica alle chiamate $.fs e $.process del mod stesso: con Read(.env) negato, un mod può comunque leggere quel file con $.fs.read o avviare un programma che lo fa. Per limitare quelle chiamate, impedisci il caricamento del mod oppure gestisci la chiamata in un mod di criteri.

  • Gli altri controlli dei permessi possono essere aggirati. Il mod di un utente che approva le chiamate agli strumenti può approvare una chiamata per cui una regola ask chiederebbe conferma, oppure che un hook PreToolUse esterno alle impostazioni gestite ha bloccato. In modalità auto, una chiamata approvata dal mod viene eseguita senza un controllo del classificatore.

Il codice sorgente della protezione è pubblico nella directory mods/sec-default del repository di Claude Code.

Sapere quali controlli continuano ad applicarsi

I mod non sostituiscono i controlli che hai già:

  • Gli hook delle impostazioni continuano a funzionare. Gli hook di tipo command, HTTP, prompt e agent nei file di impostazioni e in hooks/hooks.json dei plugin vengono eseguiti come prima, insieme ai mod. Nulla di essi è deprecato.
  • Le regole deny hanno la precedenza dove la protezione viene caricata. Il mod di un utente non può approvare una chiamata che una regola deny rifiuta, a meno che tu non imposti allowModsToOverrideDenyRules.
  • Gli hook gestiti vengono eseguiti per primi. Un hook PreToolUse nelle impostazioni gestite viene eseguito prima che qualsiasi mod veda la chiamata allo strumento, e il suo blocco è definitivo. Se poi un mod riscrive la chiamata, i tuoi hook gestiti vengono eseguiti di nuovo sulla chiamata riscritta, quindi un blocco si applica comunque. Gli hook PreToolUse provenienti da altri file di impostazioni e dai plugin vengono eseguiti dopo l'ultimo mod, quindi un mod che restituisce un proprio risultato invece di eseguire lo strumento ne impedisce l'esecuzione. Consulta L'ordine in cui vengono eseguiti i mod.
  • La policy di rete copre $.http.fetch. Se la tua organizzazione disattiva il recupero web, oppure il traffico di rete non essenziale è disattivato per la sessione, Claude Code rifiuta una richiesta di rete che un mod effettua con $.http.fetch. La policy non copre un programma che il mod avvia con $.process.run. Quel programma raggiunge la rete con l'accesso dell'utente stesso.
  • I controlli dei plugin coprono i mod. Un mod è un plugin, quindi le impostazioni che limitano ciò che gli utenti possono installare, come strictKnownMarketplaces, decidono se può essere installato o meno.
  • I mod non possono modificare la richiesta di permesso. Un mod può cambiare lo stile di gran parte dell'interfaccia di Claude Code, ma non della richiesta di permesso, quindi non può modificare ciò che una richiesta mostra. Un mod può comunque approvare o negare una chiamata a uno strumento prima che compaia la richiesta, come descritto in Sapere cosa succede per impostazione predefinita.
  • Le richieste di attendibilità vengono prima. In una sessione interattiva in una directory che l'utente non ha ancora considerato attendibile, nessun mod viene caricato finché l'utente non risponde alla richiesta di attendibilità.
  • --safe-mode disattiva i mod installati, compresi i tuoi. Avvia una sessione con claude --safe-mode per verificare se un mod ha causato un problema.

Nessuno di questi controlli esegue un mod in una sandbox. Un mod che consenti viene eseguito come l'utente, con l'accesso dell'utente a file, processi e rete.

Decidi se lasciare attivi i mod

Un mod può fare più delle altre parti di un plugin perché viene eseguito all'interno di Claude Code. Vede ogni prompt e ogni chiamata a uno strumento, può modificarli e può consentire o negare una chiamata a uno strumento prima che compaia una richiesta di permesso.

Ciò che un utente può caricare come mod dipende dai controlli sui plugin che hai già:

I tuoi controlli sui plugin oggi Cosa può caricare un utente come mod
Nessuno Un mod da qualsiasi marketplace, da qualsiasi directory con --plugin-dir, o che Claude scrive durante una sessione
Un'allowlist di marketplace Un mod dai marketplace che consenti, o da qualsiasi directory con --plugin-dir. Un mod che Claude scrive durante una sessione viene caricato solo quando l'allowlist include skills-dir.
Un'allowlist di marketplace e disableSideloadFlags Un mod dai marketplace che consenti

Gestire i plugin per la tua organizzazione elenca i modi in cui un plugin viene caricato e l'impostazione che controlla ciascuno di essi.

Per controllare i mod in un marketplace prima che i tuoi utenti li installino, consulta Verifica cosa può fare un mod. Per impedire il caricamento dei mod degli utenti finché non l'hai fatto, consulta Impedisci il caricamento dei mod installati dagli utenti.

Verifica cosa può fare un mod

Puoi vedere cosa è in grado di fare un mod senza eseguirlo. Nella tua shell, esegui claude plugin validate sulla directory del plugin:

claude plugin validate ./some-mod

Due righe dell'output descrivono il codice del mod:

  ❯ ./register.js hooks: session.start, tool.call, ui.render{component=Pane}
  ❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.open

La riga hooks: elenca gli eventi che il mod riceve. La riga calls: elenca i metodi dell'API dei mod che il suo codice chiama. L'API dei mod, scritta $ nel codice di un mod, è il modo in cui un mod accede a file, processi e rete. Claude Code si rifiuta di caricare un mod che usa l'API dei mod in un modo che questo comando non riesce a leggere.

Cerca questi elementi nella riga calls::

Chiamata Cosa significa
$.fs.read, $.fs.write Legge o scrive file ovunque possa farlo l'utente
$.process.run, $.process.spawn Avvia programmi come l'utente
$.http.fetch Effettua richieste di rete
$.env.get, $.settings.read Legge variabili d'ambiente e impostazioni, che possono contenere chiavi API. Una riga env reads: nell'output indica il nome di ciascuna variabile.
$.env.set Imposta una variabile d'ambiente per Claude Code e per ogni comando e server MCP che avvia successivamente, il che può cambiare ciò che quei programmi eseguono. Una riga env writes: indica il nome di ciascuna variabile.
$.mcp.call Chiama uno strumento su un server MCP connesso, secondo le regole di permesso della sessione
$.model.complete Usa il piano o la chiave API dell'utente per le chiamate al modello
$.prompt.submit Invia un prompt e può inviarlo come se fossero parole dell'utente stesso
$.session.send Invia un messaggio che viene letto dal Claude di un'altra sessione o di un subagent

Nella riga hooks:, tool.call e prompt.submit indicano che il mod vede ogni chiamata a uno strumento e ogni prompt, e può modificarli. session.append indica che il mod può riscrivere ogni riga della conversazione prima che venga memorizzata. ui.render{component=AskUserQuestion} indica che il mod può ridisegnare la finestra di dialogo che Claude usa per porre una domanda all'utente. tool.check indica che il mod può approvare o negare una chiamata a uno strumento prima che compaia una richiesta di permesso. Sapere cosa succede per impostazione predefinita elenca quali delle tue regole e dei tuoi hook hanno la precedenza sulla sua risposta.

Scegli quanto consentire

I criteri per i mod vanno dal non consentire alcun mod installato fino a consentire qualsiasi mod scelto da un utente, con il tuo mod che controlla gli altri, e ciascuno corrisponde a poche impostazioni gestite. Trova il criterio che desideri nella prima colonna e imposta ciò che indica la seconda colonna. Distribuire le impostazioni gestite spiega dove si trovano le impostazioni gestite.

Cosa desideri Impostazioni
Nessun mod installato, con gli hook non toccati Imposta allowManagedModsOnly e non distribuire alcun mod tuo
Nessun mod installato e nessun hook, inclusi i tuoi hook gestiti Imposta disableAllHooks su true
Solo i mod della tua organizzazione Imposta l'opzione allowManagedModsOnly della protezione, e installa i tuoi mod in modo che vengano considerati tuoi
Qualsiasi mod dai marketplace che approvi Mantieni le tue restrizioni sui marketplace, e imposta disableSideloadFlags su true
Qualsiasi mod, con il tuo mod che controlla gli altri Installa il tuo mod, ed elencalo insieme a sec-default@builtin in prependPlugins

Cosa fa ciascuna impostazione:

  • allowManagedModsOnly: un'opzione della protezione integrata. I mod degli utenti non vengono caricati, mentre i loro hook delle impostazioni, le righe di stato e /goal continuano a funzionare. Impedire il caricamento dei mod installati dagli utenti elenca cosa copre.
  • allowManagedHooksOnly: un'impostazione più ampia. Vengono caricati solo i mod della tua organizzazione e i mod integrati in Claude Code. Un mod installato da un utente non viene caricato. L'impostazione blocca anche gli hook nei file di impostazioni degli utenti. Leggi Cosa viene eseguito con allowManagedHooksOnly prima di impostarla.
  • disableAllHooks: l'impostazione più ampia. Nelle impostazioni gestite, blocca i mod in ogni plugin installato, inclusi i tuoi, e disattiva ogni hook nei file di impostazioni, quindi un hook PreToolUse nelle tue impostazioni gestite non blocca più nulla. Anche le righe di stato personalizzate e /goal smettono di funzionare. Leggi disableAllHooks prima di impostarla.
  • disableSideloadFlags: rifiuta --plugin-dir e --plugin-url all'avvio, e impedisce il caricamento dei mod che Claude scrive durante una sessione. L'impostazione rifiuta anche --agents e --mcp-config. Leggi disableSideloadFlags prima di impostarla.

I mod integrati in Claude Code, come il supporto per AGENTS.md, non sono interessati da queste impostazioni. Ognuno ha il proprio interruttore.

Un utente il cui mod non è stato caricato trova il motivo nel proprio log di debug. Messaggi di rifiuto elenca le righe per allowManagedHooksOnly e disableAllHooks, e Messaggi dalla protezione integrata riporta la riga per allowManagedModsOnly.

Consentire solo i mod della tua organizzazione

Per eseguire i mod della tua organizzazione e bloccare quelli portati dagli utenti, distribuisci le impostazioni della riga Solo i mod della tua organizzazione della tabella dei criteri, più disableSideloadFlags. Con questo managed-settings.json completo, Claude Code rifiuta i mod degli utenti, quindi nessuno dei loro hook viene eseguito, e il tuo mod di criteri viene eseguito prima degli altri mod:

{
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": { "source": "directory", "path": "/opt/acme/claude-plugins" }
    }
  },
  "enabledPlugins": { "acme-guard@acme-tools": true },
  "prependPlugins": ["acme-guard@acme-tools", "sec-default@builtin"],
  "pluginConfigs": {
    "cc-plugin-sec-default@builtin": {
      "options": { "allowManagedModsOnly": true }
    }
  },
  "disableSideloadFlags": true
}

Ogni gruppo di chiavi svolge un compito:

  • extraKnownMarketplaces, enabledPlugins e prependPlugins: installano il tuo mod in modo che venga considerato tuo, e lo eseguono per primo con la protezione subito dopo. Installare i mod della tua organizzazione e impostare l'ordine descrive la directory a cui puntano queste chiavi.
  • pluginConfigs: imposta l'opzione allowManagedModsOnly della protezione, così Claude Code rifiuta i mod degli utenti. I loro hook delle impostazioni, le righe di stato e /goal continuano a funzionare.
  • disableSideloadFlags: consulta disableSideloadFlags per i flag che rifiuta all'avvio

Per verificare il criterio su una macchina di test, nella tua shell avvia una sessione con claude --debug e leggi il log di debug:

  • Il tuo mod: la sua riga hooks module contiene tier prepend
  • Un mod installato dall'utente: una riga riporta refused by cc-plugin-sec-default: mods are limited to your organization's by policy (allowManagedModsOnly). Una riga precedente indica che il modulo degli hook di quel mod è loaded, quindi cerca il rifiuto.
  • Una directory di plugin: claude --plugin-dir ./any-mod termina con un messaggio che inizia con --plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)

Per limitare anche i marketplace che gli utenti possono aggiungere, combina questo file con le tue restrizioni sui marketplace.

Applicare i controlli sui plugin ai mod

Un mod è un plugin, quindi i modi in cui gestisci i plugin per la tua organizzazione si applicano anche a un plugin che contiene un mod:

Impostare le opzioni della protezione integrata

La protezione integrata accetta delle opzioni. Impostale nelle impostazioni gestite sotto pluginConfigs, con la chiave cc-plugin-sec-default@builtin, come fa l'esempio in Impedire il caricamento dei mod installati dagli utenti.

La tabella indica cosa ottengono i tuoi utenti con ciascuna opzione non impostata e impostata su true:

Opzione Non impostata true
allowManagedModsOnly I mod degli utenti vengono caricati Vengono caricati solo i mod della tua organizzazione e i mod integrati in Claude Code. Claude Code rifiuta ogni altro mod, incluso uno installato da un utente o indicato con --plugin-dir.
allowModsToOverrideDenyRules Le regole deny hanno la precedenza sui mod degli utenti Un mod di un utente che approva le chiamate agli strumenti può approvare una chiamata che una regola deny rifiuta

Queste regole stabiliscono se un'opzione ha effetto:

  • L'id ha una sola forma qui: Claude Code legge le opzioni solo sotto cc-plugin-sec-default@builtin. prependPlugins accetta anche sec-default@builtin, mentre pluginConfigs no.
  • Contano solo le impostazioni gestite: la stessa voce in un file di impostazioni utente, di progetto o locale, o in un file passato con --settings, non imposta né allenta un'opzione
  • La protezione deve essere caricata: se imposti prependPlugins, indica la protezione nell'elenco. Dove la protezione non viene caricata, nessuna delle due opzioni si applica.
  • La protezione fallisce in modo chiuso: se la protezione non riesce a leggere le impostazioni gestite, rifiuta ogni mod degli utenti al caricamento. Se non riesce a verificare le regole deny per una chiamata approvata dal mod di un utente, rifiuta la chiamata.

I messaggi dalla protezione integrata sono ciò che vedono i tuoi utenti quando si applica una delle due opzioni.

Esegui i mod della tua organizzazione

Puoi distribuire i tuoi mod a ogni utente, scegliere dove vengono eseguiti rispetto ai mod degli utenti e usarne uno per applicare un criterio.

Installa i mod della tua organizzazione e imposta l'ordine

I mod della tua organizzazione vengono caricati dove quelli degli utenti non lo sono e possono essere eseguiti prima di essi, quindi Claude Code deve essere in grado di capire che un mod proviene da te. Considera un mod come appartenente alla tua organizzazione solo quando tutte queste condizioni sono vere:

  • L'impostazione gestita enabledPlugins imposta il plugin del mod su true
  • Le impostazioni gestite indicano il marketplace del plugin come una directory sulla macchina dell'utente, tramite percorso assoluto. Una voce extraKnownMarketplaces fa proprio questo e registra anche il marketplace per l'utente.
  • Il marketplace elenca il plugin tramite un percorso relativo, così Claude Code lo carica sul posto da quella directory

Per soddisfarle, fai in modo che il tuo sistema di gestione dei dispositivi copi la directory del marketplace nello stesso percorso su ogni macchina. Rendi la directory e ogni directory sovrastante scrivibili solo da un amministratore, come il file delle impostazioni gestite. Chiunque possa scrivere lì può riscrivere il tuo mod. Le impostazioni gestite che distribuisci dalla console di amministrazione di claude.ai possono contenere le chiavi, ma non possono collocare la directory su una macchina.

La directory contiene il manifest del marketplace e il plugin:

/opt/acme/claude-plugins/
├── .claude-plugin/
│   └── marketplace.json
└── plugins/
    └── acme-guard/
        ├── .claude-plugin/
        │   └── plugin.json
        └── hooks/
            ├── hooks.json
            └── register.js

Il manifest elenca il plugin tramite il suo percorso relativo a quella directory:

{
  "name": "acme-tools",
  "owner": { "name": "Acme" },
  "plugins": [
    { "name": "acme-guard", "source": "./plugins/acme-guard", "description": "Acme policy mod" }
  ]
}

Un plugin che Claude Code copia nella sua cache viene considerato di un utente, anche quando l'impostazione gestita enabledPlugins lo abilita. Questo vale per ogni plugin proveniente da una sorgente GitHub, git, URL o npm. Il suo mod viene eseguito tra i mod degli utenti, prependPlugins e appendPlugins lo ignorano e non viene caricato con allowManagedModsOnly o allowManagedHooksOnly. Il log di debug dell'utente contiene una riga che inizia con l'id del plugin e is enabled by managed settings, but.

Claude Code genera un evento ogni volta che sta per compiere un'azione, come eseguire uno strumento, e lo passa a ciascun mod a turno. Un mod che viene considerato tuo viene eseguito prima dei mod degli utenti anche se non lo elenchi da nessuna parte. Per impostarne la posizione, elenca il suo id in una delle due impostazioni. L'id è il nome del plugin, @ e il nome del marketplace, ad esempio acme-guard@acme-tools.

  • prependPlugins: il tuo mod vede ogni evento prima di qualsiasi mod degli utenti e ogni risultato dopo. Può modificare l'evento, rifiutarlo o saltare i mod degli utenti.
  • appendPlugins: il tuo mod viene eseguito dopo ogni mod degli utenti, quindi vede solo gli eventi che quei mod trasmettono, nella forma in cui li trasmettono

Questo esempio dichiara il marketplace acme-tools in /opt/acme/claude-plugins, abilita acme-guard da esso ed esegue quel mod per primo, seguito dalla protezione integrata:

{
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": { "source": "directory", "path": "/opt/acme/claude-plugins" }
    }
  },
  "enabledPlugins": { "acme-guard@acme-tools": true },
  "prependPlugins": ["acme-guard@acme-tools", "sec-default@builtin"]
}

Ogni chiave svolge un compito:

  • extraKnownMarketplaces: indica la directory che contiene il marketplace acme-tools. path è il percorso assoluto della directory che contiene .claude-plugin/marketplace.json.
  • enabledPlugins: attiva acme-guard per ogni utente che riceve queste impostazioni gestite
  • prependPlugins: mette acme-guard al primo posto e la protezione integrata al secondo, entrambi prima di qualsiasi mod installato da un utente. Claude Code segue l'ordine che elenchi.

Per verificare che la macchina di un utente abbia ricevuto le impostazioni, consulta Verifica che un criterio sia in vigore.

Per verificare dove viene eseguito il mod, avvia una sessione su quella macchina con claude --debug e cerca l'id del mod nel log di debug:

  • hooks module acme-guard@acme-tools loaded, con tier prepend: il mod viene considerato della tua organizzazione e viene eseguito per primo
  • La stessa riga con tier user: Claude Code lo tratta come un mod di un utente. Una seconda riga, prependPlugins names acme-guard@acme-tools, which is not an enabled managed plugin with a hooks module; skipped, indica che l'elenco lo ha ignorato.

Queste regole stabiliscono quali id nei due elenchi hanno effetto:

  • L'elenco sostituisce il valore predefinito: quando imposti prependPlugins nelle impostazioni gestite, includi sec-default@builtin per mantenere la protezione integrata. La protezione è integrata e non richiede una voce enabledPlugins.
  • I tuoi id devono essere considerati tuoi: nelle impostazioni gestite, Claude Code ignora un id il cui plugin non soddisfa le condizioni per un mod dell'organizzazione
  • I repository non possono impostarle: Claude Code legge entrambe le impostazioni dalle impostazioni gestite e mai dal file di impostazioni di un repository. Un utente può impostarle in ~/.claude/settings.json per ordinare i propri mod solo su una macchina senza impostazioni gestite, e solo quando non ha effettuato l'accesso con un piano Team o Enterprise. In qualsiasi altro caso, Claude Code ignora entrambe le chiavi nelle impostazioni utente. Un elenco lì non aggiunge né rimuove la protezione integrata.

Applica un criterio con un tuo mod

Per escludere tutti i mod degli utenti, non hai bisogno di un tuo mod. Imposta allowManagedModsOnly. Scrivi un mod di criteri quando vuoi consentire alcuni mod degli utenti e rifiutarne altri, oppure per registrare ciò che fanno i mod.

Ogni volta che un altro mod sta per essere caricato, il tuo mod riceve l'elenco che claude plugin validate stampa, in un evento denominato plugin.register. Un mod in prependPlugins può leggere quell'elenco e rifiutare il mod. Può anche gestire qualsiasi chiamata all'API dei mod per nome per registrare o rifiutare quella chiamata per ogni altro mod. Il nome è il metodo senza $., quindi un hook su fs.write vede ogni chiamata $.fs.write.

Questo mod di criteri rifiuta qualsiasi mod di un utente il cui codice chiama $.process.run o $.process.spawn. Mantiene anche un log di audit, scrivendo nel log di debug ogni chiamata a uno strumento e ogni file scritto da un mod. Poiché viene eseguito per primo, il log registra ciò che è stato richiesto, prima che qualsiasi mod degli utenti lo modifichi. Salvalo come acme-guard/hooks/register.js:

// The methods no user's mod may call, each spelled namespace.method
const BLOCKED_CALLS = ['process.run', 'process.spawn']

export function register(on) {
  // Runs each time another mod is about to load
  on('plugin.register', async ($, e, next) => {
    // Keep the calls in that mod's code that are on the blocked list
    const blocked = e.uses.calls.filter((call) => BLOCKED_CALLS.includes(call))
    if (e.tier === 'user' && blocked.length > 0) {
      // Returning refuse keeps the mod from loading, and the text is the reason
      return { refuse: 'Acme policy: mods may not call ' + blocked.join(', ') }
    }
    // Let every other mod load
    return next(e)
  })

  // Record each tool call, then let it go ahead unchanged
  on('tool.call', async ($, e, next) => {
    $.ui.log('audit tool.call ' + e.tool, { to: 'debug' })
    return next(e)
  })

  // Record which mod wrote a file, then the path, quoted because the mod chose it
  on('fs.write', async ($, e, next) => {
    $.ui.log('audit fs.write by ' + next.origin.plugin + ' ' + JSON.stringify(e.path), { to: 'debug' })
    return next(e)
  })
}

Il file registra tre hook:

  • plugin.register: decide se un altro mod viene caricato. Rifiuta un mod di un utente che chiama un metodo bloccato e lascia passare ogni altro mod.
  • tool.call: scrive nel log di debug una riga come audit tool.call Bash per ogni chiamata a uno strumento, senza modificare nulla
  • fs.write: scrive una riga come audit fs.write by reader "/tmp/notes.md" per ogni chiamata $.fs.write effettuata da un altro mod, senza modificare nulla. Il nome del mod viene prima e il percorso è tra virgolette, così un percorso scelto da un mod non può spacciarsi per un altro campo della riga.

L'hook plugin.register legge due campi dell'evento:

  • e.tier: dove verrebbe eseguito il mod, uno tra prepend, user, append o builtin. Ogni mod installato da una persona è user.
  • e.uses.calls: i metodi dell'API dei mod che il mod chiama, ciascuno scritto come namespace.method, ad esempio process.run, senza il $. che claude plugin validate stampa

Quando un utente installa un mod che chiama $.process.run, il mod non viene caricato e il suo log di debug contiene una riga che termina con refused by acme-guard: seguita dal tuo motivo. Il rifiuto compare anche nella trascrizione in una sessione che ricarica a caldo una directory di plugin. Per bloccare una chiamata senza rifiutare l'intero mod, restituisci { deny: 'your reason' } da un hook sul nome di quella chiamata.

Per inviare le righe di audit in un posto diverso dal log di debug, chiama $.http.fetch dagli stessi hook.

Una sessione può essere eseguita senza il tuo mod. Se il thread di lavoro che esegue i mod installati si arresta in modo anomalo tre volte, Claude Code scarica ogni mod non integrato, compreso il tuo, finché l'utente non esegue /reload-plugins o avvia una nuova sessione. Inoltre, un utente che avvia Claude Code con --safe-mode lavora senza mod installati, compreso il tuo.

Crea un mod descrive i file di cui un mod ha bisogno. Testa un mod di criteri contiene un file di test per questo mod di criteri.

Rifiuta i mod quando il tuo controllo fallisce

Se il tuo hook plugin.register genera un'eccezione o supera il suo limite di tempo, Claude Code salta l'hook, quindi il controllo fallisce in modo aperto e il mod che stava controllando viene caricato. Per fallire in modo chiuso e rifiutare i mod degli utenti, sposta il controllo in una funzione con nome e aggiungi un gestore .catch che restituisca il rifiuto. Questa versione del file mostra solo l'hook plugin.register, quindi mantieni in register i due hook di audit della prima versione:

const BLOCKED_CALLS = ['process.run', 'process.spawn']

// The same check as before, moved into a function of its own
async function checkMod($, e, next) {
  const blocked = e.uses.calls.filter((call) => BLOCKED_CALLS.includes(call))
  if (e.tier === 'user' && blocked.length > 0) {
    return { refuse: 'Acme policy: mods may not call ' + blocked.join(', ') }
  }
  return next(e)
}

export function register(on) {
  // The handler runs only when checkMod throws or exceeds its time limit
  on('plugin.register', checkMod).catch(async ($, e, next) => {
    // Let your organization's mods and built-in mods load
    if (e.tier !== 'user') return next(e)
    // Refuse the user's mod that couldn't be checked
    return { refuse: 'Acme policy check failed, so this mod was not loaded' }
  })
}

Con il gestore in funzione, un mod che era in fase di controllo quando il controllo ha generato un'eccezione o è scaduto non viene caricato, e la riga di rifiuto riporta il secondo motivo, come in refused by acme-guard: Acme policy check failed, so this mod was not loaded. Il gestore passa a next(e) ogni mod al di fuori del livello user, quindi un controllo fallito non blocca i mod elencati dalla tua organizzazione. Gestisci un hook che fallisce descrive .catch per altri eventi.

Passaggi successivi