SpyBara
Go Premium

plugins/mods/admin.md 2026-11-11 22:59 UTC to 2026-11-12 21:00 UTC

No changes for this document in this history range.

2026
Tue 10 21:57 Wed 11 22:59

Kelola mod untuk organisasi Anda

Kontrol mod Claude Code dengan pengaturan terkelola: hentikan mod yang dipasang pengguna, izinkan hanya milik Anda sendiri, tinjau apa yang dapat dilakukan mod, dan terapkan kebijakan dengan mod Anda sendiri.

Sebuah mod adalah plugin yang menjalankan kode di dalam Claude Code dengan izin pengguna yang memasangnya. Mod tidak disandboxkan. Melalui pengaturan terkelola, Anda memutuskan apakah mod berjalan di mesin pengguna Anda, mod mana, dan dalam urutan apa. Anda juga dapat memasang mod Anda sendiri yang mengawasi atau menolak apa yang dilakukan mod lain.

Halaman ini untuk orang yang menerapkan pengaturan terkelola untuk Claude Code, baik sebagai file, melalui MDM, atau dari konsol admin claude.ai. Mod aktif secara default di Claude Code v2.1.286 dan yang lebih baru. Mulai dengan bagian yang sesuai dengan apa yang ingin Anda lakukan:

[!NOTE]

Kasus-kasus ini tercakup di halaman lain:

Hentikan mod yang dipasang pengguna dari memuat

Untuk mencegah setiap mod yang dibawa pengguna Anda menjalankan hook-nya, atur opsi allowManagedModsOnly pada penjaga bawaan, mod kebijakan yang dimuat Claude Code sebelum setiap mod yang dipasang pengguna. Opsi ini masuk dalam pengaturan terkelola di bawah pluginConfigs, dengan kunci cc-plugin-sec-default@builtin:

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

Dengan opsi yang diatur dalam pengaturan terkelola:

  • Tidak ada mod yang dibawa pengguna yang menjalankan hook-nya: itu mencakup mod dalam plugin yang dipasang pengguna, mod yang dimuat dengan --plugin-dir, dan mod yang ditulis Claude selama sesi
  • Mod organisasi Anda tetap berjalan: mod yang dihitung sebagai milik organisasi Anda tidak diperiksa. Setiap mod lainnya dihitung sebagai milik pengguna dan ditolak. Itu termasuk mod dalam plugin yang Anda aktifkan dari GitHub atau marketplace jarak jauh lainnya, dan yang diaktifkan organisasi Anda untuk anggotanya di claude.ai. Jika tidak ada yang dihitung sebagai milik Anda, tidak ada mod terpasang yang menjalankan hook-nya.
  • Pengguna tidak dapat membatalkannya: penjaga membaca opsi dari pengaturan terkelola saja, jadi entri yang sama dalam file pengaturan pengguna, proyek, atau lokal, atau dalam file yang dilewatkan dengan --settings, tidak mengubah apa pun
  • File atau kebijakan MDM mencakup setiap penyedia: saat Anda mengirimkan opsi sebagai file atau melalui MDM, opsi ini bekerja dengan cara yang sama di Amazon Bedrock, Agent Platform Google Cloud, dan Microsoft Foundry. Untuk pengiriman dari konsol admin claude.ai, lihat Ketersediaan Platform
  • Kustomisasi lain pengguna tetap berfungsi: hook mereka dalam file pengaturan dan dalam hooks/hooks.json milik plugin, baris status, dan /goal tidak terpengaruh
  • Mod bawaan tetap berjalan: mod yang dibangun ke dalam Claude Code, seperti dukungan AGENTS.md, masing-masing memiliki sakelar mereka sendiri

Untuk mengonfirmasi opsi di mesin pengguna, mulai Claude Code di sana dengan --plugin-dir dan jalur direktori yang menyimpan mod, seperti claude --plugin-dir ./first-mod. Hook mod tidak berjalan, dan transkrip serta log debug memiliki pesan penjaga, yang menyebutkan nama mod dan allowManagedModsOnly. Jika pesan tersebut tidak ada, lihat Periksa bahwa kebijakan berlaku dan aturan yang memutuskan apakah opsi berlaku.

Jika Anda menetapkan CLAUDE_CODE_ENABLE_FUNCTION_HOOKS ke 0 selama akses awal, gantikan dengan opsi ini. Claude Code v2.1.287 dan yang lebih baru mengabaikan variabel pada nilai apa pun, jadi 0 di sana membiarkan mod tetap aktif.

Ketahui apa yang terjadi secara default

Tanpa pengaturan mod milik Anda sendiri, inilah yang didapatkan pengguna Anda:

  • Mod aktif. Pengguna dapat menginstal plugin yang berisi mod dari marketplace mana pun yang diizinkan oleh pengaturan plugin Anda, atau memuatnya dari sebuah direktori dengan --plugin-dir.

  • Penjaga bawaan berjalan lebih dulu. Claude Code memuat mod bawaan bernama sec-default@builtin sebelum setiap mod yang diinstal pengguna. Pengguna tidak dapat mematikannya. /plugin dan log debug mencantumkannya sebagai cc-plugin-sec-default. Penjaga dimuat ketika salah satu dari kondisi berikut terpenuhi:

    Pengguna dengan kunci API, atau yang menggunakan Amazon Bedrock, Agent Platform milik Google Cloud, atau Microsoft Foundry, hanya mendapatkan penjaga pada mesin yang memiliki pengaturan terkelola atau managed-mcp.json. Sesi yang berjalan dengan CLAUDE_CODE_OAUTH_TOKEN berumur panjang juga tidak dihitung sebagai login tersebut, bahkan ketika login Team atau Enterprise tersimpan di mesin.

  • Penjaga melindungi apa yang Anda kelola. Mod milik pengguna tidak dapat mengubah apa yang diterima atau diputuskan oleh hook terkelola Anda, system prompt, CLAUDE.md terkelola Anda dan instruksi terkelola lainnya, apa yang dibaca mod mana pun sebagai pengaturan, atau tool dan deskripsi dari server MCP terkelola Anda.

  • Di luar apa yang Anda kelola, mod milik pengguna bertindak sebagai pengguna tersebut. Mod mempertahankan izin pengguna tersebut: mod masih dapat membaca dan menulis file, memulai proses, dan membuat permintaan jaringan. Mod juga dapat menulis ulang panggilan tool dan prompt, menolak panggilan tool, dan menggambar di antarmuka.

  • Aturan izin dan hook PreToolUse diutamakan daripada mod milik pengguna. Dengan penjaga dimuat, secara default mod milik pengguna tidak dapat menyetujui panggilan yang ditolak oleh aturan deny atau yang memerlukan permintaan izin menurut aturan ask, di file pengaturan mana pun aturan tersebut berada. Mod juga tidak dapat menyetujui panggilan yang diblokir oleh hook PreToolUse mana pun.

    Aturan izin dan hook PreToolUse berlaku untuk panggilan tool Claude, bukan untuk panggilan $.fs dan $.process milik mod. Dengan Read(.env) ditolak, mod masih dapat membaca file tersebut dengan $.fs.read atau memulai program yang melakukannya. Untuk membatasi panggilan $.fs dan $.process milik mod itu sendiri, cegah mod agar tidak dimuat atau tangani panggilan tersebut dalam mod kebijakan.

  • Mod milik pengguna masih dapat melewati beberapa permintaan izin. Dalam auto mode, panggilan yang disetujui mod berjalan tanpa pemeriksaan pengklasifikasi, kecuali jika penjaga dimuat dan sesi berjalan dengan --permission-prompt-tool atau callback canUseTool dari Agent SDK. Dalam kasus tersebut, pengklasifikasi memeriksa panggilan terlebih dahulu. Untuk permintaan izin yang tidak dilewati oleh persetujuan mod, lihat Memperluas izin dengan hook.

Kode sumber penjaga bersifat publik di direktori mods/sec-default pada repositori Claude Code.

Ketahui kontrol mana yang masih berlaku

Mod tidak menggantikan kontrol yang sudah Anda miliki:

  • Hook pengaturan tetap berfungsi. Hook command, HTTP, prompt, dan agent di file pengaturan dan di hooks/hooks.json milik plugin berjalan seperti sebelumnya, berdampingan dengan mod.

  • Aturan deny diutamakan di tempat penjaga dimuat. Mod milik pengguna tidak dapat menyetujui panggilan yang ditolak oleh aturan deny, kecuali jika Anda menetapkan allowModsToOverrideDenyRules.

  • Hook terkelola berjalan lebih dulu. Hook PreToolUse di pengaturan terkelola berjalan sebelum hook tool.call milik mod mana pun, dan ketika hook terkelola tersebut memblokir panggilan tool, tidak ada hook tool.call milik mod yang berjalan untuk panggilan tersebut. Jika panggilan dilanjutkan dan sebuah mod menulis ulangnya, hook terkelola Anda berjalan lagi pada panggilan yang ditulis ulang, sehingga secara default hook tersebut masih dapat memblokirnya.

    Hook PreToolUse dari file pengaturan lain dan dari plugin berjalan setelah mod terakhir. Jika sebuah mod menjawab panggilan tool itu sendiri, tool tidak pernah berjalan dan hook tersebut juga tidak. Lihat Urutan berjalannya mod.

  • Kebijakan jaringan mencakup $.http.fetch.

    Tidak satu pun dari hal ini mencakup program yang dimulai mod dengan $.process.run, yang menjangkau jaringan dengan akses milik pengguna sendiri.

  • Kontrol plugin mencakup mod. Mod adalah plugin, sehingga pengaturan yang membatasi apa yang dapat diinstal pengguna, seperti strictKnownMarketplaces, menentukan apakah mod dapat diinstal sama sekali.

  • Mod tidak dapat mengubah dialog izin. Mod dapat mengubah gaya sebagian besar antarmuka Claude Code, tetapi tidak dialog izin, sehingga mod tidak dapat mengubah apa yang ditampilkan dialog tersebut. Mod masih dapat menyetujui atau menolak panggilan tool sebelum dialog izin muncul, seperti yang dijelaskan dalam Ketahui apa yang terjadi secara default.

  • Dialog kepercayaan muncul lebih dulu. Dalam sesi interaktif di direktori yang belum dipercayai pengguna, tidak ada mod yang dimuat hingga pengguna menjawab dialog kepercayaan.

  • --safe-mode mematikan mod yang terinstal, termasuk milik Anda. Mulai sesi dengan claude --safe-mode untuk memeriksa apakah sebuah mod menyebabkan masalah.

Tidak satu pun dari kontrol ini menjalankan mod dalam sandbox. Mod yang Anda izinkan berjalan sebagai pengguna, dengan akses pengguna ke file, proses, dan jaringan.

Ketahui hook mana dari mod milik pengguna yang tidak berjalan

Di tempat penjaga bawaan dimuat, hook yang didaftarkan mod milik pengguna pada salah satu event berikut tidak pernah berjalan, dan /plugin memberi tahu pengguna tersebut melalui sebuah catatan. Pada baris session.append, door adalah jenis baris tersimpan yang menjadi filter hook tersebut.

Hook pada Apa event tersebut
classic.<Event>, seperti classic.Stop Sebuah event hook pengaturan
prompt.compose Daftar bagian dari system prompt
prompt.section Satu bagian dari system prompt
prompt.context Konteks yang dikirim bersama pesan pertama percakapan
prompt.attachment Pesan yang ditambahkan Claude Code untuk Claude, seperti pengingat
skill.prompt Teks skill saat diperluas untuk Claude
attribution.text Teks atribusi commit atau pull request
session.compact Compaction dari percakapan
settings.read Pembacaan pengaturan, seperti panggilan $.settings.read milik mod
session.append{door=attachment} Baris tersimpan untuk pesan yang ditambahkan Claude Code untuk Claude
session.append{door=hook-context} Baris tersimpan untuk konteks dari hook pengaturan
session.append{door=compaction} Baris tersimpan untuk ringkasan dan batas dari compaction

Penjaga juga melewati hook milik pengguna dalam beberapa kasus lain, seperti deskripsi tool organisasi Anda, pada tool.describe, dan baris tersimpan untuk teks skill. /plugin tidak menampilkan catatan untuk kasus tersebut. Jika hook pada event lain tidak melakukan apa pun, lihat Cari tahu mengapa mod tidak melakukan apa pun.

Catatan tersebut muncul di detail plugin dan di tab Errors pada /plugin. Catatan ini memerlukan Claude Code v2.1.299 atau yang lebih baru. Catatan tersebut menyebutkan setiap hook dari tabel sebagaimana mod mendaftarkannya, seperti dalam contoh ini:

Its hooks on classic.Stop, prompt.section do not run here: where an organization manages Claude Code, these events pass over the plugins you install
Only a plugin that counts as your organization's own runs hooks on these events. An administrator sets that up in managed settings

Untuk membiarkan hook ini berjalan, ubah pengaturan terkelola dengan salah satu dari dua cara:

  • Jalankan mod sebagai milik organisasi Anda: instal mod sehingga dihitung sebagai milik Anda. Hook miliknya pada event ini kemudian berjalan, dan penjaga tetap dimuat untuk setiap mod lainnya. Mod aktif untuk semua orang yang menerima pengaturan ini, dan mod harus berada di direktori yang Anda tempatkan di setiap mesin. Jika Anda mencantumkannya di prependPlugins, pertahankan sec-default@builtin dalam daftar.
  • Hapus penjaga: jangan sertakan sec-default@builtin dalam prependPlugins. Daftar kosong, "prependPlugins": [], sudah cukup. Anda kehilangan seluruh penjaga, bukan hanya event ini. Mod milik pengguna kemudian dapat melakukan apa yang sebaliknya dicegah oleh penjaga, dan opsi penjaga tidak berlaku.

Jika Anda mengirimkan daftar tanpa penjaga melalui pengaturan yang dikelola server, penjaga tetap dimuat hingga server mengonfirmasi pengaturan untuk sesi tersebut. Untuk mengonfirmasi salah satu perubahan pada mesin yang menjalankan v2.1.299 atau yang lebih baru, buka /plugin dalam sesi di mesin tersebut dan periksa bahwa catatan tersebut sudah hilang.

Hook session.append tanpa filter door tetap berjalan dan tidak mendapatkan catatan, tetapi baris tersimpan dalam tabel tidak sampai kepadanya.

Putuskan apakah akan membiarkan mod tetap aktif

Mod dapat melakukan lebih banyak daripada bagian lain dari plugin karena berjalan di dalam Claude Code. Ini melihat setiap prompt dan panggilan alat, dapat mengubahnya, dan dapat mengizinkan atau menolak panggilan alat sebelum prompt izin muncul.

Apa yang dapat dimuat pengguna sebagai mod tergantung pada kontrol plugin yang sudah Anda miliki:

Kontrol plugin Anda hari ini Apa yang dapat dimuat pengguna sebagai mod
Tidak ada Mod dari pasar apa pun, dari direktori apa pun dengan --plugin-dir, atau yang ditulis Claude selama sesi
Daftar izin pasar Mod dari pasar yang Anda izinkan, atau dari direktori apa pun dengan --plugin-dir. Mod yang ditulis Claude selama sesi memuat hanya saat daftar izin mencakup skills-dir.
Daftar izin pasar dan disableSideloadFlags Mod dari pasar yang Anda izinkan

Kelola plugin untuk organisasi Anda mencantumkan cara-cara plugin dimuat dan pengaturan yang mengontrol masing-masing.

Untuk memeriksa mod dalam pasar sebelum pengguna Anda memasangnya, lihat Tinjau apa yang dapat dilakukan mod. Untuk menjaga mod pengguna tetap keluar sampai Anda melakukannya, lihat Hentikan mod yang dipasang pengguna dari memuat.

Tinjau apa yang dapat dilakukan mod

Anda dapat melihat apa yang dapat dilakukan mod tanpa menjalankannya. Di shell Anda, jalankan claude plugin validate pada direktori plugin:

claude plugin validate ./some-mod

Baris hooks: dan calls: dalam output menjelaskan kode mod:

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

Baris hooks: mencantumkan peristiwa yang diterima mod. Baris calls: mencantumkan metode API mod yang dipanggil kodenya. API mod, ditulis $ dalam kode mod, adalah cara mod menjangkau file, proses, dan jaringan. Claude Code menolak untuk memuat mod yang menggunakan API mod dengan cara yang tidak dapat dibaca perintah ini.

Lihat baris calls: untuk ini:

Panggilan Apa artinya
$.fs.read, $.fs.write Membaca atau menulis file di mana pun pengguna dapat
$.process.run, $.process.spawn Memulai program sebagai pengguna
$.http.fetch Membuat permintaan jaringan
$.env.get, $.settings.read Membaca variabel lingkungan dan pengaturan, yang dapat menyimpan kunci API. Baris env reads: dalam output menyebutkan setiap variabel.
$.env.set Menetapkan variabel lingkungan untuk Claude Code dan untuk setiap perintah dan server MCP yang dimulainya setelahnya, yang dapat mengubah apa yang dijalankan program tersebut. Baris env writes: menyebutkan setiap variabel.
$.mcp.call Memanggil alat pada server MCP yang terhubung, di bawah aturan izin sesi
$.model.complete Menggunakan paket atau kunci API pengguna untuk panggilan model
$.prompt.submit Mengirimkan prompt, dan dapat mengirimkannya sebagai kata-kata pengguna sendiri
$.session.send Mengirimkan pesan yang dibaca oleh Claude milik sesi lain, subagent, atau rekan tim

Dalam baris hooks:, tool.call dan prompt.submit berarti mod melihat setiap panggilan tool dan setiap prompt, dan dapat mengubahnya. session.append berarti mod dapat menulis ulang setiap baris percakapan sebelum disimpan, kecuali baris yang dilewati oleh guard. ui.render{component=AskUserQuestion} berarti mod dapat menggambar ulang dialog yang digunakan Claude untuk menanyakan pengguna. tool.check berarti mod dapat menyetujui atau menolak panggilan tool sebelum permintaan izin muncul. Ketahui apa yang terjadi secara default mencantumkan aturan dan hook mana dari Anda yang diutamakan daripada jawabannya.

Pilih seberapa banyak yang diizinkan

Kebijakan mod berkisar dari tidak ada mod terinstal sama sekali hingga mod apa pun yang dipilih pengguna, dengan mod Anda sendiri yang memeriksa mod lainnya, dan masing-masing hanya berupa beberapa pengaturan terkelola. Temukan kebijakan yang Anda inginkan di kolom pertama dan atur apa yang disebutkan di kolom kedua. Men-deploy pengaturan terkelola menjelaskan lokasi pengaturan terkelola.

Yang Anda inginkan Pengaturan
Tidak ada mod terinstal yang berjalan, dengan hook pengaturan tidak tersentuh Atur allowManagedModsOnly dan jangan men-deploy mod Anda sendiri
Tidak ada mod terinstal dan tidak ada hook sama sekali, termasuk hook terkelola Anda Atur disableAllHooks ke true
Hanya mod organisasi Anda Atur opsi allowManagedModsOnly pada penjaga, dan instal mod Anda agar dihitung sebagai milik Anda
Mod apa pun dari marketplace yang Anda setujui Pertahankan pembatasan marketplace Anda, dan atur disableSideloadFlags ke true
Mod apa pun, dengan mod Anda sendiri yang memeriksa mod lainnya Instal mod Anda, dan cantumkan bersama sec-default@builtin di prependPlugins

Fungsi setiap pengaturan:

  • allowManagedModsOnly: opsi pada penjaga bawaan. Claude Code menolak mod milik pengguna sendiri, sehingga tidak ada hook mereka yang berjalan. Hook pengaturan pengguna, baris status, dan /goal tetap berfungsi. Hentikan pemuatan mod yang diinstal pengguna mencantumkan apa saja yang dicakupnya.
  • allowManagedHooksOnly: pengaturan yang lebih luas. Hanya mod organisasi Anda dan mod yang terpasang bawaan di Claude Code yang dimuat. Mod yang diinstal pengguna sendiri tidak dimuat. Pengaturan ini juga memblokir hook di file pengaturan milik pengguna sendiri. Baca Apa yang berjalan di bawah allowManagedHooksOnly sebelum Anda mengaturnya.
  • disableAllHooks: pengaturan yang paling luas. Dalam pengaturan terkelola, pengaturan ini menghentikan mod di setiap plugin yang terinstal, termasuk milik Anda, dan mematikan setiap hook di file pengaturan, sehingga hook PreToolUse di pengaturan terkelola Anda tidak lagi memblokir apa pun. Baris status kustom dan /goal juga berhenti berfungsi. Baca disableAllHooks sebelum Anda mengaturnya.
  • disableSideloadFlags: menolak --plugin-dir dan --plugin-url saat startup, dan mencegah mod yang ditulis Claude selama sesi agar tidak dimuat. Pengaturan ini juga menolak --agents dan --mcp-config. Baca disableSideloadFlags sebelum Anda mengaturnya.

Mod yang terpasang bawaan di Claude Code, seperti dukungan AGENTS.md, tidak terpengaruh oleh pengaturan ini. Masing-masing memiliki saklarnya sendiri.

Pengguna yang mod-nya ditolak atau tidak dimuat dapat menemukan alasannya di log debug mereka. Pesan penolakan mencantumkan baris untuk allowManagedHooksOnly dan disableAllHooks, dan Pesan dari penjaga bawaan memuat baris untuk allowManagedModsOnly.

Izinkan hanya mod organisasi Anda

Untuk menjalankan mod organisasi Anda dan memblokir mod yang dibawa pengguna, deploy pengaturan dari baris Hanya mod organisasi Anda pada tabel kebijakan, ditambah disableSideloadFlags. Dengan managed-settings.json lengkap ini, Claude Code menolak mod milik pengguna sendiri, sehingga tidak ada hook mereka yang berjalan, dan mod kebijakan Anda berjalan lebih dahulu daripada mod lainnya:

{
  "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
}

Setiap kelompok kunci melakukan satu tugas:

  • extraKnownMarketplaces, enabledPlugins, dan prependPlugins: menginstal mod Anda agar dihitung sebagai milik Anda, dan menjalankannya lebih dahulu dengan penjaga setelahnya. Instal mod organisasi Anda dan atur urutannya menjelaskan direktori yang dituju oleh kunci-kunci ini.
  • pluginConfigs: mengatur opsi allowManagedModsOnly pada penjaga, sehingga Claude Code menolak mod milik pengguna sendiri. Hook pengaturan, baris status, dan /goal mereka tetap berfungsi.
  • disableSideloadFlags: lihat disableSideloadFlags untuk flag yang ditolaknya saat startup

Untuk mengonfirmasi kebijakan pada mesin uji, di shell Anda mulai sesi dengan claude --debug dan baca log debug:

  • Mod Anda: baris hooks module-nya memuat tier prepend
  • Mod yang diinstal pengguna: sebuah baris berbunyi refused by cc-plugin-sec-default: mods are limited to your organization's by policy (allowManagedModsOnly). Baris sebelumnya menyatakan modul hook mod tersebut loaded, jadi cari baris penolakannya.
  • Direktori plugin: claude --plugin-dir ./any-mod keluar dengan pesan yang diawali --plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)

Untuk juga membatasi marketplace mana yang dapat ditambahkan pengguna, gabungkan file ini dengan pembatasan marketplace Anda.

Terapkan kontrol plugin Anda pada mod

Mod adalah plugin, sehingga cara Anda mengelola plugin untuk organisasi Anda juga berlaku untuk plugin yang memuat mod:

Atur opsi pada penjaga bawaan

Penjaga bawaan menerima opsi. Atur opsi tersebut di pengaturan terkelola di bawah pluginConfigs, dengan kunci cc-plugin-sec-default@builtin, seperti yang dilakukan contoh di Hentikan pemuatan mod yang diinstal pengguna.

Tabel berikut menunjukkan apa yang didapat pengguna Anda dengan setiap opsi tidak diatur dan dengan opsi diatur ke true:

Opsi Tidak diatur true
allowManagedModsOnly Mod milik pengguna sendiri berjalan Hanya mod organisasi Anda, dan mod yang terpasang bawaan di Claude Code, yang menjalankan hook-nya. Claude Code menolak setiap mod lainnya, termasuk mod yang diinstal pengguna atau disebutkan dengan --plugin-dir.
allowModsToOverrideDenyRules Aturan deny diutamakan daripada mod pengguna Mod pengguna yang menyetujui panggilan tool dapat menyetujui panggilan melewati sebagian besar hasil yang tetap berlaku secara default, termasuk aturan deny

Aturan berikut menentukan apakah suatu opsi berlaku:

  • ID hanya memiliki satu bentuk di sini: Claude Code membaca opsi hanya di bawah cc-plugin-sec-default@builtin. prependPlugins juga menerima sec-default@builtin, sedangkan pluginConfigs tidak.
  • Hanya pengaturan terkelola yang dihitung: entri yang sama di file pengaturan pengguna, proyek, atau lokal, atau di file yang diteruskan dengan --settings, tidak mengatur opsi dan tidak melonggarkannya
  • Penjaga harus dimuat: jika Anda mengatur prependPlugins, sebutkan penjaga dalam daftar. Jika penjaga tidak dimuat, kedua opsi tidak berlaku.
  • Penjaga gagal dalam keadaan tertutup: jika penjaga tidak dapat membaca pengaturan terkelola, penjaga menolak setiap mod pengguna saat pemuatan. Jika penjaga tidak dapat memeriksa aturan deny untuk panggilan yang disetujui oleh mod pengguna, penjaga menolak panggilan tersebut.

Pesan dari penjaga bawaan adalah apa yang dilihat pengguna Anda ketika salah satu opsi berlaku.

Jalankan mod organisasi Anda sendiri

Anda dapat menerapkan mod Anda sendiri ke setiap pengguna, memilih di mana mereka berjalan relatif terhadap mod pengguna, dan menggunakan satu untuk menegakkan kebijakan.

Pasang mod organisasi Anda dan atur urutan

Mod organisasi Anda memuat di mana mod pengguna tidak dan dapat berjalan sebelum mereka, jadi Claude Code harus dapat mengatakan bahwa mod berasal dari Anda. Ini memperlakukan mod sebagai milik organisasi Anda hanya saat semua ini benar:

  • Managed enabledPlugins menetapkan plugin mod ke true
  • Pengaturan terkelola menyebutkan marketplace plugin sebagai direktori di mesin pengguna, menurut jalur absolut. Entri extraKnownMarketplaces melakukan itu dan juga mendaftarkan marketplace untuk pengguna.
  • Marketplace mencantumkan plugin menurut jalur relatif, jadi Claude Code memuatnya di tempat dari direktori itu

Untuk memenuhinya, buat manajemen perangkat Anda menyalin direktori marketplace ke jalur yang sama di setiap mesin. Buat direktori dan setiap direktori di atasnya dapat ditulis hanya oleh administrator, seperti file pengaturan terkelola. Siapa pun yang dapat menulis di sana dapat menulis ulang mod Anda. Pengaturan terkelola yang Anda kirimkan dari konsol admin claude.ai dapat membawa kunci, tetapi tidak dapat menempatkan direktori di mesin.

Direktori menyimpan manifes marketplace dan plugin:

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

Manifes mencantumkan plugin menurut jalurnya relatif terhadap direktori itu:

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

Plugin yang disalin Claude Code ke dalam cache-nya dihitung sebagai milik pengguna, bahkan saat managed enabledPlugins mengaktifkannya. Itu mencakup setiap plugin dari sumber GitHub, git, URL, atau npm. Modnya berjalan di antara mod pengguna, prependPlugins dan appendPlugins melewatinya, allowManagedModsOnly menolaknya, dan allowManagedHooksOnly mencegahnya dimuat. Log debug pengguna memiliki baris yang dimulai dengan id plugin dan is enabled by managed settings, but.

Claude Code menaikkan peristiwa setiap kali akan bertindak, seperti menjalankan tool, dan meneruskannya ke setiap mod secara bergantian. Mod yang dihitung sebagai milik Anda berjalan sebelum mod pengguna bahkan saat Anda tidak mencantumkannya di mana pun. Untuk menetapkan tempatnya, cantumkan id-nya dalam salah satu dari dua pengaturan. Id adalah nama plugin, @, dan nama marketplace, seperti acme-guard@acme-tools.

  • prependPlugins: mod Anda melihat setiap peristiwa sebelum mod pengguna apa pun dan setiap hasil setelahnya. Ini dapat mengubah peristiwa, menolaknya, atau melewati mod pengguna.
  • appendPlugins: mod Anda berjalan setelah setiap mod pengguna, jadi hanya melihat peristiwa yang dilewatkan mod tersebut, dalam bentuk yang mereka lewatkan

Contoh ini mendeklarasikan marketplace acme-tools di /opt/acme/claude-plugins, mengaktifkan acme-guard darinya, dan menjalankan mod itu terlebih dahulu, dengan penjaga bawaan setelahnya:

{
  "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"]
}

Setiap kunci melakukan satu pekerjaan:

  • extraKnownMarketplaces: menyebutkan direktori yang menyimpan marketplace acme-tools. path adalah jalur absolut direktori yang berisi .claude-plugin/marketplace.json.
  • enabledPlugins: mengaktifkan acme-guard untuk setiap pengguna yang menerima pengaturan terkelola ini
  • prependPlugins: menempatkan acme-guard terlebih dahulu dan penjaga bawaan kedua, keduanya sebelum mod apa pun yang dipasang pengguna. Claude Code mengikuti urutan yang Anda cantumkan.

Untuk mengonfirmasi bahwa mesin pengguna menerima pengaturan, lihat Periksa bahwa kebijakan berlaku.

Untuk mengonfirmasi di mana mod berjalan, mulai sesi di mesin itu dengan claude --debug dan cari log debug untuk id mod:

  • hooks module acme-guard@acme-tools loaded, dengan tier prepend: mod dihitung sebagai milik organisasi Anda dan berjalan terlebih dahulu
  • Baris yang sama dengan tier user: Claude Code memperlakukannya sebagai mod pengguna. Baris kedua, prependPlugins names acme-guard@acme-tools, which is not an enabled managed plugin with a hooks module; skipped, mengatakan daftar melewatinya.

Aturan-aturan ini memutuskan id mana dalam dua daftar yang berlaku:

  • Daftar menggantikan default: saat Anda menetapkan prependPlugins dalam pengaturan terkelola, sebutkan sec-default@builtin di dalamnya untuk menjaga penjaga bawaan. Penjaga dibangun dan tidak memerlukan entri enabledPlugins.
  • Id Anda sendiri harus dihitung sebagai milik Anda: dalam pengaturan terkelola, Claude Code melewati id yang pluginnya tidak memenuhi kondisi untuk mod organisasi
  • Repositori tidak dapat menetapkan kedua daftar: Claude Code mengabaikan keduanya dalam file pengaturan repositori, jadi tetapkan keduanya dalam pengaturan terkelola.
  • Pengguna dapat menetapkannya untuk mengurutkan mod mereka sendiri: dalam ~/.claude/settings.json, hanya di mesin tanpa pengaturan terkelola atau file managed-mcp.json, dan hanya saat kredensial sesi bukan /login Team atau Enterprise. Di tempat lain, Claude Code mengabaikan kedua kunci dalam pengaturan pengguna. Daftar di sana tidak menambah atau menghapus penjaga bawaan.

Terapkan kebijakan dengan mod Anda sendiri

Untuk menjaga setiap mod pengguna keluar, Anda tidak memerlukan mod Anda sendiri. Atur allowManagedModsOnly. Tulis mod kebijakan saat Anda ingin mengizinkan beberapa mod pengguna dan menolak yang lain, atau untuk mencatat apa yang dilakukan mod.

Setiap kali mod lain akan memuat, mod Anda menerima daftar yang dicetak claude plugin validate, dalam peristiwa bernama plugin.register. Mod dalam prependPlugins dapat membaca daftar itu dan menolak mod. Ini juga dapat menangani panggilan API mods apa pun menurut nama untuk mencatat atau menolak panggilan itu untuk setiap mod lainnya. Nama adalah metode tanpa $., jadi hook pada fs.write melihat setiap panggilan $.fs.write.

Mod kebijakan ini menolak mod pengguna apa pun yang kodenya sendiri memanggil $.process.run atau $.process.spawn. Ini juga menyimpan log audit, menulis setiap panggilan tool dan setiap file yang ditulis mod ke log debug. Karena berjalan terlebih dahulu, log mencatat apa yang diminta, sebelum mod pengguna apa pun mengubahnya. Simpan sebagai 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)
  })
}

File mendaftarkan tiga hook:

  • plugin.register: memutuskan apakah mod lain memuat. Ini menolak mod pengguna yang memanggil metode yang diblokir dan meneruskan setiap mod lainnya.
  • tool.call: menulis baris seperti audit tool.call Bash ke log debug untuk setiap panggilan tool, dan tidak mengubah apa pun
  • fs.write: menulis baris seperti audit fs.write by reader "/tmp/notes.md" untuk setiap panggilan $.fs.write yang dibuat mod lain, dan tidak mengubah apa pun. Nama mod datang terlebih dahulu dan jalurnya dikutip, jadi jalur yang dipilih mod tidak dapat lulus sebagai bidang lain dari baris.

Hook plugin.register membaca dua bidang peristiwa:

  • e.tier: di mana mod akan berjalan, salah satu dari prepend, user, append, atau builtin. Setiap mod yang dipasang orang adalah user.
  • e.uses.calls: metode API mods yang dipanggil mod, masing-masing ditulis namespace.method seperti process.run, tanpa $. yang dicetak claude plugin validate

Saat pengguna memasang mod yang memanggil $.process.run, mod tidak memuat, dan log debug mereka memiliki baris yang berakhir dengan refused by acme-guard: dan alasan Anda. Penolakan juga mencapai transkrip dalam sesi yang memuat ulang panas direktori plugin. Untuk memblokir panggilan tanpa menolak seluruh mod, kembalikan { deny: 'your reason' } dari hook pada nama panggilan itu.

Untuk mengirim baris audit ke tempat lain selain log debug, panggil $.http.fetch dari hook yang sama.

Sesi dapat berjalan tanpa mod Anda. Jika thread pekerja yang menjalankan mod yang dipasang mogok tiga kali, Claude Code membongkar setiap mod yang bukan bawaan, termasuk milik Anda, sampai pengguna menjalankan /reload-plugins atau memulai sesi baru. Dan pengguna yang memulai Claude Code dengan --safe-mode berjalan tanpa mod yang dipasang, termasuk milik Anda.

Buat mod mencakup file yang dibutuhkan mod. Uji mod kebijakan memiliki file uji untuk mod kebijakan ini.

Tolak mod saat pemeriksaan Anda gagal

Jika hook plugin.register Anda melempar atau melampaui batas waktu, Claude Code melewati hook, jadi pemeriksaan gagal terbuka dan mod yang diperiksa memuat. Untuk gagal tertutup dan menolak mod pengguna, pindahkan pemeriksaan ke fungsi bernama dan tambahkan handler .catch yang mengembalikan penolakan. Versi file ini menunjukkan hanya hook plugin.register, jadi simpan dua hook audit dari versi pertama dalam register:

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' }
  })
}

Dengan handler di tempat, mod yang sedang diperiksa saat pemeriksaan melempar atau kehabisan waktu tidak memuat, dan baris penolakan membawa alasan kedua, seperti dalam refused by acme-guard: Acme policy check failed, so this mod was not loaded. Handler meneruskan setiap mod di luar tier user ke next(e), jadi pemeriksaan yang gagal tidak menghentikan mod yang dicantumkan organisasi Anda. Tangani hook yang gagal mencakup .catch untuk peristiwa lain.

Langkah berikutnya