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

# 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](/docs/id/plugins/mods/overview) adalah plugin yang menjalankan kode di dalam Claude Code dengan izin pengguna yang memasangnya. Mod tidak disandboxkan. Melalui [pengaturan terkelola](/docs/id/managed-settings), 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.287 dan yang lebih baru. Mulai dengan bagian yang sesuai dengan apa yang ingin Anda lakukan:

* **Jauhkan mod milik pengguna, dengan atau tanpa mod milik Anda sendiri**: [Hentikan mod yang dipasang pengguna dari memuat](#stop-user-installed-mods-from-loading)
* **Lihat apa yang didapat pengguna Anda saat Anda tidak mengubah apa pun**: [Ketahui apa yang terjadi secara default](#know-what-happens-by-default)
* **Biarkan mod tetap aktif dengan batasan lain**: [Pilih berapa banyak yang akan diizinkan](#choose-how-much-to-allow)

<Note>
  Kasus-kasus ini tercakup di halaman lain:

  * **Anda belum pernah menerapkan pengaturan terkelola sebelumnya**: mulai dengan [Terapkan pengaturan terkelola](/docs/id/managed-settings)
  * **Anda ingin mengontrol plugin mana yang dapat dipasang pengguna**: lihat [Kelola plugin untuk organisasi Anda](/docs/id/plugins/org)
</Note>

<h2 id="stop-user-installed-mods-from-loading">
  Hentikan mod yang dipasang pengguna dari memuat
</h2>

Untuk mencegah setiap mod yang dibawa pengguna Anda dari memuat, atur opsi `allowManagedModsOnly` pada [penjaga bawaan](#know-what-happens-by-default), 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`:

```json managed-settings.json theme={null}
{
  "pluginConfigs": {
    "cc-plugin-sec-default@builtin": {
      "options": {
        "allowManagedModsOnly": true
      }
    }
  }
}
```

Dengan opsi yang diatur dalam pengaturan terkelola:

* **Tidak ada mod yang dibawa pengguna yang memuat**: itu mencakup mod dalam plugin yang dipasang pengguna, mod yang dimuat dengan `--plugin-dir`, dan mod [yang ditulis Claude selama sesi](/docs/id/plugins/mods/create#ask-claude-for-a-mod)
* **Mod organisasi Anda masih memuat**: mod yang [dihitung sebagai milik organisasi Anda](#install-your-organizations-mods) tidak diperiksa. Setiap mod lainnya dihitung sebagai milik pengguna dan tidak memuat. Itu termasuk mod dalam plugin yang Anda aktifkan dari GitHub atau pasar jarak jauh lainnya, dan yang diaktifkan organisasi Anda untuk anggotanya di claude.ai. Jika tidak ada yang dihitung sebagai milik Anda, tidak ada mod yang dipasang yang memuat.
* **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](/docs/id/server-managed-settings#platform-availability)
* **Kustomisasi lain pengguna tetap berfungsi**: [hook mereka dalam file pengaturan](/docs/id/hooks), 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](/docs/id/plugins/mods/overview#mods-built-into-claude-code)

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](/docs/id/plugins/mods/troubleshoot#messages-from-the-built-in-guard), yang menyebutkan nama mod dan `allowManagedModsOnly`. Jika mod memuat, lihat [Periksa bahwa kebijakan berlaku](/docs/id/managed-settings#check-that-a-policy-is-in-force) dan [aturan yang memutuskan apakah opsi berlaku](#set-options-on-the-built-in-guard).

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.

<h2 id="know-what-happens-by-default">
  Ketahui apa yang terjadi secara default
</h2>

Tanpa pengaturan mod Anda sendiri, inilah yang didapat pengguna Anda:

* **Mod aktif.** Pengguna dapat memasang plugin yang berisi mod dari pasar apa pun yang diizinkan pengaturan plugin Anda, atau memuat satu dari direktori dengan `--plugin-dir`.
* **Penjaga bawaan berjalan terlebih dahulu.** Claude Code memuat mod bawaan bernama `sec-default@builtin` sebelum setiap mod yang dipasang pengguna. Pengguna tidak dapat mematikannya. `/plugin` dan log debug mencantumkannya sebagai `cc-plugin-sec-default`. Penjaga memuat saat salah satu dari ini benar:

  * Mesin memiliki pengaturan terkelola
  * Pengguna masuk ke Claude Code dengan paket Team atau Enterprise

  Pengguna yang mengautentikasi dengan kunci API, atau melalui Amazon Bedrock, Agent Platform Google Cloud, atau Microsoft Foundry, mendapatkan penjaga hanya di mesin yang memiliki pengaturan terkelola.
* **Penjaga melindungi apa yang Anda kelola.** Mod pengguna tidak dapat mengubah apa yang diterima atau diputuskan hook terkelola Anda, prompt sistem, `CLAUDE.md` terkelola Anda dan instruksi terkelola lainnya, apa yang dibaca mod apa pun sebagai pengaturan, atau alat dan deskripsi server MCP terkelola Anda.
* **Semuanya yang lain diizinkan.** Penjaga tidak menambahkan batasan lain. Mod pengguna masih dapat membaca dan menulis file, memulai proses, membuat permintaan jaringan, menulis ulang panggilan alat dan prompt, menolak panggilan alat, menyetujui yang sebaliknya akan meminta, dan menggambar di antarmuka, semuanya dengan izin pengguna itu.
* **Aturan penolakan dan hook terkelola Anda memiliki prioritas.** Di mana penjaga memuat, mod pengguna tidak dapat menyetujui panggilan yang ditolak aturan `deny`, file pengaturan mana pun yang menyimpan aturan. Blok dari hook `PreToolUse` dalam pengaturan terkelola juga final. Keduanya berlaku untuk panggilan alat Claude. Tidak satupun berlaku untuk panggilan [`$.fs` dan `$.process` milik mod](/docs/id/plugins/mods/api#reach-files-processes-and-the-network): dengan `Read(.env)` ditolak, mod masih dapat membaca file itu dengan `$.fs.read` atau memulai program yang melakukannya. Untuk membatasi panggilan tersebut, jauhkan mod dari memuat atau hook panggilan dalam [mod kebijakan](#enforce-a-policy-with-a-mod-of-your-own).
* **Pemeriksaan izin lainnya dapat ditimpa.** Mod pengguna yang menyetujui panggilan alat dapat menyetujui panggilan yang akan diminta aturan `ask`, atau yang diblokir hook `PreToolUse` di luar pengaturan terkelola. Dalam mode otomatis, panggilan yang disetujui mod berjalan tanpa pemeriksaan pengklasifikasi.

Sumber penjaga bersifat publik di [direktori `mods/sec-default` dari repositori Claude Code](https://github.com/anthropics/claude-code/tree/main/mods/sec-default).

<h3 id="know-which-controls-still-apply">
  Ketahui kontrol mana yang masih berlaku
</h3>

Mod tidak menggantikan kontrol yang sudah Anda miliki:

* **Hook pengaturan tetap berfungsi.** Hook perintah, HTTP, prompt, dan agen dalam file pengaturan dan dalam `hooks/hooks.json` plugin berjalan seperti sebelumnya, bersama mod. Tidak ada yang sudah usang tentang mereka.
* **Aturan penolakan memiliki prioritas di mana penjaga memuat.** Mod pengguna tidak dapat menyetujui panggilan yang ditolak aturan `deny`, kecuali Anda menetapkan [`allowModsToOverrideDenyRules`](#set-options-on-the-built-in-guard).
* **Hook terkelola berjalan terlebih dahulu.** Hook `PreToolUse` dalam pengaturan terkelola berjalan sebelum mod apa pun melihat panggilan alat, dan bloknya final. Jika mod kemudian menulis ulang panggilan, hook terkelola Anda berjalan lagi pada panggilan yang ditulis ulang, jadi blok masih berlaku. Hook `PreToolUse` dari file pengaturan lain dan dari plugin berjalan setelah mod terakhir, jadi mod yang mengembalikan hasilnya sendiri sebagai pengganti menjalankan alat mencegah yang lain berjalan. Lihat [Urutan mod berjalan](/docs/id/plugins/mods/events#the-order-mods-run-in).
* **Kebijakan jaringan mencakup `$.http.fetch`.** Jika organisasi Anda mematikan pengambilan web, atau lalu lintas jaringan yang tidak penting dimatikan untuk sesi, Claude Code menolak permintaan jaringan yang dibuat mod dengan `$.http.fetch`. Kebijakan tidak mencakup program yang dimulai mod dengan `$.process.run`. Program itu menjangkau jaringan dengan akses pengguna mereka sendiri.
* **Kontrol plugin mencakup mod.** Mod adalah plugin, jadi [pengaturan yang membatasi apa yang dapat dipasang pengguna](/docs/id/plugins/org#restrict-what-users-can-install), seperti `strictKnownMarketplaces`, memutuskan apakah itu dapat dipasang sama sekali.
* **Mod tidak dapat mengubah prompt izin.** Mod dapat mengubah gaya banyak antarmuka Claude Code, tetapi bukan prompt izin, jadi tidak dapat mengubah apa yang ditampilkan prompt. Mod masih dapat menyetujui atau menolak panggilan alat sebelum prompt muncul, seperti yang dijelaskan [Ketahui apa yang terjadi secara default](#know-what-happens-by-default).
* **Prompt kepercayaan datang terlebih dahulu.** Dalam sesi interaktif di direktori yang belum dipercaya pengguna, tidak ada mod yang memuat sampai mereka menjawab prompt kepercayaan.
* **`--safe-mode` mematikan mod yang dipasang, termasuk milik Anda.** Mulai sesi dengan `claude --safe-mode` untuk memeriksa apakah mod menyebabkan masalah.

Tidak satupun dari kontrol ini mensandboxkan mod. Mod yang Anda izinkan berjalan sebagai pengguna, dengan akses pengguna ke file, proses, dan jaringan.

<h2 id="decide-whether-to-leave-mods-on">
  Putuskan apakah akan membiarkan mod tetap aktif
</h2>

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`](/docs/id/plugins/org#keep-skills-directory-plugins-loading). |
| Daftar izin pasar dan `disableSideloadFlags` | Mod dari pasar yang Anda izinkan |

[Kelola plugin untuk organisasi Anda](/docs/id/plugins/org) mencantumkan setiap cara plugin memuat dan pengaturan yang mengontrol masing-masing.

Untuk memeriksa mod dalam pasar sebelum pengguna Anda memasangnya, lihat [Tinjau apa yang dapat dilakukan mod](#review-what-a-mod-can-do). Untuk menjaga mod pengguna tetap keluar sampai Anda melakukannya, lihat [Hentikan mod yang dipasang pengguna dari memuat](#stop-user-installed-mods-from-loading).

<h3 id="review-what-a-mod-can-do">
  Tinjau apa yang dapat dilakukan mod
</h3>

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

```bash theme={null}
claude plugin validate ./some-mod
```

Dua baris dalam output menjelaskan kode mod:

```text theme={null}
  ❯ ./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](/docs/id/plugins/mods/api), 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 sesi lain atau subagen Claude |

Dalam baris `hooks:`, [`tool.call`](/docs/id/plugins/mods/reference#tools) dan [`prompt.submit`](/docs/id/plugins/mods/reference#prompts-and-what-claude-reads) berarti mod melihat setiap panggilan alat dan setiap prompt, dan dapat mengubahnya. [`session.append`](/docs/id/plugins/mods/reference#session) berarti mod dapat menulis ulang setiap baris percakapan sebelum disimpan. [`ui.render{component=AskUserQuestion}`](/docs/id/plugins/mods/interface#change-what-claude-code-already-draws) berarti mod dapat menggambar ulang dialog yang digunakan Claude untuk menanyakan pengguna. `tool.check` berarti mod dapat menyetujui atau menolak panggilan alat sebelum prompt izin muncul. [Ketahui apa yang terjadi secara default](#know-what-happens-by-default) mencantumkan aturan dan hook mana dari Anda yang memiliki prioritas atas jawabannya.

<h2 id="choose-how-much-to-allow">
  Pilih berapa banyak yang akan diizinkan
</h2>

Kebijakan mod berkisar dari tidak ada mod yang dipasang sama sekali hingga mod apa pun yang dipilih pengguna, dengan mod Anda sendiri memeriksa yang lain, dan masing-masing adalah beberapa pengaturan terkelola. Temukan kebijakan yang Anda inginkan di kolom pertama dan atur apa yang dinamai kolom kedua. [Terapkan pengaturan terkelola](/docs/id/managed-settings) mencakup di mana pengaturan terkelola berada.

| Apa yang Anda inginkan | Pengaturan |
| :- | :- |
| Tidak ada mod yang dipasang, dengan hook tidak tersentuh | Atur [`allowManagedModsOnly`](#set-options-on-the-built-in-guard) dan jangan terapkan mod Anda sendiri |
| Tidak ada mod yang dipasang dan tidak ada hook sama sekali, termasuk hook terkelola Anda | Atur `disableAllHooks` ke `true` |
| Hanya mod organisasi Anda | Atur opsi [`allowManagedModsOnly`](#stop-user-installed-mods-from-loading) penjaga, dan [pasang mod Anda](#install-your-organizations-mods) sehingga dihitung sebagai milik Anda |
| Mod apa pun dari pasar yang Anda setujui | Pertahankan [pembatasan pasar Anda](/docs/id/plugins/org#restrict-what-users-can-install), dan atur `disableSideloadFlags` ke `true` |
| Mod apa pun, dengan mod Anda sendiri memeriksa yang lain | [Pasang mod Anda](#install-your-organizations-mods), dan cantumkan dengan `sec-default@builtin` dalam `prependPlugins` |

Apa yang dilakukan setiap pengaturan:

* **`allowManagedModsOnly`**: opsi pada penjaga bawaan. Mod pengguna tidak memuat, dan hook pengaturan, baris status, dan `/goal` mereka tetap berfungsi. [Hentikan mod yang dipasang pengguna dari memuat](#stop-user-installed-mods-from-loading) mencantumkan apa yang dicakupnya.
* **`allowManagedHooksOnly`**: pengaturan yang lebih luas. Hanya [mod organisasi Anda](#install-your-organizations-mods) dan mod yang dibangun ke dalam Claude Code yang memuat. Mod yang dipasang pengguna sendiri tidak. Pengaturan juga memblokir hook dalam file pengaturan pengguna mereka sendiri. Baca [Apa yang berjalan di bawah `allowManagedHooksOnly`](/docs/id/settings-reference#what-runs-under-allowmanagedhooksonly) sebelum Anda menetapkannya.
* **`disableAllHooks`**: pengaturan terluas. Dalam pengaturan terkelola, ini menghentikan mod dalam setiap plugin yang dipasang, termasuk milik Anda, dan mematikan setiap hook dalam file pengaturan, jadi hook `PreToolUse` dalam pengaturan terkelola Anda tidak lagi memblokir apa pun. Baris status khusus dan `/goal` juga berhenti bekerja. Baca [`disableAllHooks`](/docs/id/settings-reference#disableallhooks) sebelum Anda menetapkannya.
* **`disableSideloadFlags`**: menolak `--plugin-dir` dan `--plugin-url` saat startup, jadi tidak ada yang memuat mod dari direktori, dan menjaga mod yang ditulis Claude selama sesi dari memuat. Pengaturan juga menolak `--agents` dan `--mcp-config`. Baca [`disableSideloadFlags`](/docs/id/settings-reference#disablesideloadflags) sebelum Anda menetapkannya.

Mod yang dibangun ke dalam Claude Code, seperti dukungan `AGENTS.md`, tidak terpengaruh oleh pengaturan ini. Masing-masing memiliki [sakelar sendiri](/docs/id/plugins/mods/overview#mods-built-into-claude-code).

Pengguna yang modnya tidak memuat menemukan alasannya dalam log debug mereka. [Pesan penolakan](/docs/id/plugins/mods/troubleshoot#refusal-messages) mencantumkan baris untuk `allowManagedHooksOnly` dan `disableAllHooks`, dan [Pesan dari penjaga bawaan](/docs/id/plugins/mods/troubleshoot#messages-from-the-built-in-guard) memiliki baris untuk `allowManagedModsOnly`.

<h3 id="set-options-on-the-built-in-guard">
  Atur opsi pada penjaga bawaan
</h3>

Penjaga bawaan mengambil dua opsi. Atur dalam pengaturan terkelola di bawah `pluginConfigs`, dengan kunci `cc-plugin-sec-default@builtin`, seperti yang dilakukan contoh dalam [Hentikan mod yang dipasang pengguna dari memuat](#stop-user-installed-mods-from-loading).

Tabel memberikan apa yang didapat pengguna Anda dengan setiap opsi tidak diatur dan dengan diatur ke `true`:

| Opsi | Tidak diatur | `true` |
| :- | :- | :- |
| `allowManagedModsOnly` | Mod pengguna memuat | Hanya [mod organisasi Anda](#install-your-organizations-mods), dan mod yang dibangun ke dalam Claude Code, yang memuat. Claude Code menolak setiap mod lainnya, termasuk yang dipasang pengguna atau dinamai dengan `--plugin-dir`. |
| `allowModsToOverrideDenyRules` | Aturan penolakan memiliki prioritas atas mod pengguna | Mod pengguna yang menyetujui panggilan alat dapat menyetujui panggilan yang ditolak aturan `deny` |

Aturan-aturan ini memutuskan apakah opsi berlaku:

* **Id memiliki satu ejaan di sini**: Claude Code membaca opsi hanya di bawah `cc-plugin-sec-default@builtin`. `prependPlugins` menerima `sec-default@builtin` juga, dan `pluginConfigs` tidak.
* **Hanya pengaturan terkelola yang dihitung**: entri yang sama dalam file pengaturan pengguna, proyek, atau lokal, atau dalam file yang dilewatkan dengan `--settings`, tidak menetapkan opsi atau melonggarkan opsi
* **Penjaga harus memuat**: jika Anda menetapkan `prependPlugins`, [sebutkan penjaga dalam daftar](#install-your-organizations-mods). Di mana penjaga tidak memuat, opsi tidak berlaku.
* **Penjaga gagal tertutup**: jika penjaga tidak dapat membaca pengaturan terkelola, penjaga menolak setiap mod pengguna saat memuat. Jika tidak dapat memeriksa aturan penolakan untuk panggilan yang disetujui mod pengguna, penjaga menolak panggilan.

[Pesan dari penjaga bawaan](/docs/id/plugins/mods/troubleshoot#messages-from-the-built-in-guard) adalah apa yang dilihat pengguna Anda saat opsi berlaku.

<h2 id="run-your-organization’s-own-mods">
  Jalankan mod organisasi Anda sendiri
</h2>

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

<h3 id="install-your-organizations-mods">
  Pasang mod organisasi Anda dan atur urutan
</h3>

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 [pasar](/docs/id/plugins/create-marketplace) plugin sebagai direktori di mesin pengguna, menurut jalur absolut. Entri `extraKnownMarketplaces` melakukan itu dan juga mendaftarkan pasar untuk pengguna.
* Pasar mencantumkan plugin menurut jalur relatif, jadi Claude Code [memuatnya di tempat](/docs/id/plugins/loading#in-place-and-copied-plugins) dari direktori itu

Untuk memenuhinya, buat manajemen perangkat Anda menyalin direktori pasar 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 pasar dan plugin:

```text theme={null}
/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:

```json /opt/acme/claude-plugins/.claude-plugin/marketplace.json theme={null}
{
  "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, dan tidak memuat di bawah `allowManagedModsOnly` atau `allowManagedHooksOnly`. 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 alat, dan meneruskannya ke setiap mod secara bergantian. Mod yang dihitung sebagai milik Anda [berjalan sebelum mod pengguna](/docs/id/plugins/mods/events#the-order-mods-run-in) 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 pasar, 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 pasar `acme-tools` di `/opt/acme/claude-plugins`, mengaktifkan `acme-guard` darinya, dan menjalankan mod itu terlebih dahulu, dengan penjaga bawaan setelahnya:

```json managed-settings.json theme={null}
{
  "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 pasar `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](/docs/id/managed-settings#check-that-a-policy-is-in-force).

Untuk mengonfirmasi di mana mod berjalan, mulai sesi di mesin itu dengan `claude --debug` dan cari [log debug](/docs/id/plugins/mods/troubleshoot#read-the-debug-log) 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 tiga kondisi untuk mod organisasi
* **Repositori tidak dapat menetapkannya**: Claude Code membaca kedua pengaturan dari pengaturan terkelola dan tidak pernah dari file pengaturan repositori. Pengguna dapat menetapkannya dalam `~/.claude/settings.json` untuk mengurutkan mod mereka sendiri hanya di mesin tanpa pengaturan terkelola, dan hanya saat tidak masuk dengan paket Team atau Enterprise. Di tempat lain, Claude Code mengabaikan kedua kunci dalam pengaturan pengguna. Daftar di sana tidak menambah atau menghapus penjaga bawaan.

<h3 id="enforce-a-policy-with-a-mod-of-your-own">
  Terapkan kebijakan dengan mod Anda sendiri
</h3>

Untuk menjaga setiap mod pengguna keluar, Anda tidak memerlukan mod Anda sendiri. Atur [`allowManagedModsOnly`](#stop-user-installed-mods-from-loading). Tulis mod kebijakan saat Anda ingin mengakui 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`](/docs/id/plugins/mods/reference#other-mods). Mod dalam `prependPlugins` dapat membaca daftar itu dan menolak mod. Ini juga dapat [hook panggilan API mod apa pun menurut nama](/docs/id/plugins/mods/api#reach-files-processes-and-the-network) 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 alat 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`:

```javascript acme-guard/hooks/register.js theme={null}
// Metode yang tidak boleh dipanggil mod pengguna apa pun, masing-masing dieja namespace.method
const BLOCKED_CALLS = ['process.run', 'process.spawn']

export function register(on) {
  // Berjalan setiap kali mod lain akan memuat
  on('plugin.register', async ($, e, next) => {
    // Simpan panggilan dalam kode mod itu yang ada dalam daftar yang diblokir
    const blocked = e.uses.calls.filter((call) => BLOCKED_CALLS.includes(call))
    if (e.tier === 'user' && blocked.length > 0) {
      // Mengembalikan refuse menjaga mod dari memuat, dan teksnya adalah alasannya
      return { refuse: 'Acme policy: mods may not call ' + blocked.join(', ') }
    }
    // Biarkan setiap mod lain memuat
    return next(e)
  })

  // Catat setiap panggilan alat, kemudian biarkan maju tanpa perubahan
  on('tool.call', async ($, e, next) => {
    $.ui.log('audit tool.call ' + e.tool, { to: 'debug' })
    return next(e)
  })

  // Catat mod mana yang menulis file, kemudian jalurnya, dikutip karena mod memilihnya
  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 alat, 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 mod yang dipanggil mod, masing-masing dieja `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](/docs/id/plugins/mods/troubleshoot#find-out-why-a-mod-does-nothing). 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](/docs/id/plugins/mods/troubleshoot#mods-that-run-in-the-hooks-worker-are-off-for-this-session), 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](/docs/id/plugins/mods/create) mencakup file yang dibutuhkan mod. [Uji mod yang menilai mod lain](/docs/id/plugins/mods/test#test-a-mod-that-judges-other-mods) memiliki file uji untuk mod kebijakan ini.

<h4 id="refuse-mods-when-your-check-fails">
  Tolak mod saat pemeriksaan Anda gagal
</h4>

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`:

```javascript acme-guard/hooks/register.js theme={null}
const BLOCKED_CALLS = ['process.run', 'process.spawn']

// Pemeriksaan yang sama seperti sebelumnya, dipindahkan ke fungsi miliknya sendiri
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) {
  // Handler berjalan hanya saat checkMod melempar atau melampaui batas waktu
  on('plugin.register', checkMod).catch(async ($, e, next) => {
    // Biarkan mod organisasi Anda dan mod bawaan memuat
    if (e.tier !== 'user') return next(e)
    // Tolak mod pengguna yang tidak dapat diperiksa
    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](/docs/id/plugins/mods/events#handle-a-hook-that-fails) mencakup `.catch` untuk peristiwa lain.

<h2 id="next-steps">
  Langkah berikutnya
</h2>

* [Keamanan plugin](/docs/id/plugins/security): apa yang dapat dilakukan plugin apa pun di mesin pengguna, dan cara meninjau satu sebelum dipasang
* [Ikhtisar mod](/docs/id/plugins/mods/overview): apa itu mod dan bagaimana perbandingannya dengan hook, skill, dan server MCP
* [Urutan mod berjalan](/docs/id/plugins/mods/events#the-order-mods-run-in): bagaimana `prependPlugins` dan `appendPlugins` cocok dengan mod pengguna
* [Pengaturan dan variabel lingkungan](/docs/id/plugins/mods/reference#settings-and-environment-variables): setiap pengaturan yang dinamai di halaman ini dalam satu tabel
