SpyBara
Go Premium

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

This page contains 204 additions and 153 deletions.

2026
Thu 1 23:59 Fri 2 22:59

조직의 mod 관리

관리형 설정으로 Claude Code mod를 제어합니다. 사용자가 설치한 mod를 차단하고, 자체 mod만 허용하고, mod가 수행할 수 있는 작업을 검토하고, 자체 mod로 정책을 적용합니다.

mod는 설치한 사용자의 권한으로 Claude Code 내부에서 코드를 실행하는 플러그인입니다. mod는 샌드박스화되지 않습니다. 관리형 설정을 통해 사용자 머신에서 mod를 실행할지 여부, 실행할 mod, 실행 순서를 결정할 수 있습니다. 또한 다른 mod의 동작을 감시하거나 거부하는 자체 mod를 설치할 수도 있습니다.

이 페이지는 파일, MDM 또는 claude.ai 관리자 콘솔을 통해 Claude Code용 관리형 설정을 배포하는 담당자를 위한 것입니다. mod는 Claude Code v2.1.287 이상에서 기본적으로 활성화되어 있습니다. 원하는 작업에 해당하는 섹션부터 시작하십시오.

사용자가 설치한 mod 로드 차단하기

사용자가 가져오는 모든 mod가 로드되지 않도록 하려면 기본 제공 가드에서 allowManagedModsOnly 옵션을 설정합니다. 기본 제공 가드는 Claude Code가 사용자가 설치하는 모든 mod보다 먼저 로드하는 정책 mod입니다. 이 옵션은 관리형 설정의 pluginConfigs 아래에 cc-plugin-sec-default@builtin을 키로 하여 지정합니다.

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

관리형 설정에 이 옵션을 지정하면 다음과 같이 동작합니다.

  • 사용자가 가져온 mod는 로드되지 않습니다: 사용자가 설치한 플러그인에 포함된 mod, --plugin-dir로 로드한 mod, 세션 중에 Claude가 작성한 mod가 모두 여기에 해당합니다
  • 조직의 mod는 계속 로드됩니다: 조직의 mod로 간주되는 mod는 검사하지 않습니다. 그 외의 모든 mod는 사용자의 mod로 간주되어 로드되지 않습니다. 여기에는 GitHub 또는 기타 원격 마켓플레이스에서 활성화한 플러그인에 포함된 mod와 조직이 claude.ai에서 구성원을 위해 켠 mod도 포함됩니다. 조직의 mod로 간주되는 mod가 없으면 설치된 mod는 하나도 로드되지 않습니다.
  • 사용자가 되돌릴 수 없습니다: 가드는 관리형 설정에서만 이 옵션을 읽으므로 사용자, 프로젝트 또는 로컬 설정 파일이나 --settings로 전달한 파일에 동일한 항목을 넣어도 아무것도 바뀌지 않습니다
  • 파일 또는 MDM 정책은 모든 제공자에 적용됩니다: 이 옵션을 파일이나 MDM을 통해 배포하면 Amazon Bedrock, Google Cloud의 Agent Platform, Microsoft Foundry에서도 동일하게 동작합니다. claude.ai 관리자 콘솔을 통한 배포는 플랫폼 가용성을 참조하세요
  • 사용자의 다른 사용자 지정 항목은 계속 작동합니다: 설정 파일의 훅, 상태줄, /goal은 영향을 받지 않습니다
  • 기본 제공 mod는 계속 실행됩니다: AGENTS.md 지원과 같이 Claude Code에 기본 제공되는 mod에는 각각 별도의 스위치가 있습니다

사용자의 머신에서 이 옵션이 적용되었는지 확인하려면 해당 머신에서 --plugin-dir와 mod가 들어 있는 디렉터리 경로를 지정하여 Claude Code를 시작합니다(예: claude --plugin-dir ./first-mod). mod의 훅은 실행되지 않으며, 트랜스크립트와 디버그 로그에 mod 이름과 allowManagedModsOnly를 명시한 가드 메시지가 표시됩니다. mod가 로드된다면 정책이 적용 중인지 확인하기와 옵션의 적용 여부를 결정하는 규칙을 참조하세요.

얼리 액세스 기간에 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS를 0으로 설정했다면 이 옵션으로 대체하세요. Claude Code v2.1.287 이상은 이 변수를 값과 관계없이 무시하므로, 0으로 설정해 두어도 mod는 켜진 상태로 유지됩니다.

기본 동작 알아보기

별도의 mod 설정이 없으면 사용자에게 다음과 같이 적용됩니다.

  • mod가 켜져 있습니다. 사용자는 플러그인 설정에서 허용하는 모든 마켓플레이스에서 mod가 포함된 플러그인을 설치하거나, --plugin-dir로 디렉터리에서 플러그인을 불러올 수 있습니다.

  • 기본 제공 가드가 먼저 실행됩니다. Claude Code는 사용자가 설치한 모든 mod보다 먼저 sec-default@builtin이라는 기본 제공 mod를 불러옵니다. 사용자는 이를 끌 수 없습니다. /plugin과 디버그 로그에는 cc-plugin-sec-default로 표시됩니다. 가드는 다음 중 하나에 해당하면 로드됩니다.

    • 머신에 관리형 설정이 있는 경우
    • 사용자가 Team 또는 Enterprise 플랜으로 Claude Code에 로그인한 경우

    API 키로 인증하거나 Amazon Bedrock, Google Cloud의 Agent Platform 또는 Microsoft Foundry를 통해 인증하는 사용자는 관리형 설정이 있는 머신에서만 가드가 적용됩니다.

  • 가드는 관리 대상을 보호합니다. 사용자의 mod는 관리형 훅이 받는 내용이나 결정하는 내용, 시스템 프롬프트, 관리형 CLAUDE.md 및 기타 관리형 지침, 모든 mod가 설정으로 읽는 내용, 관리형 MCP 서버의 도구와 설명을 변경할 수 없습니다.

  • 그 밖의 모든 것은 허용됩니다. 가드는 다른 제한을 추가하지 않습니다. 사용자의 mod는 여전히 해당 사용자의 권한으로 파일을 읽고 쓰고, 프로세스를 시작하고, 네트워크 요청을 보내고, 도구 호출과 프롬프트를 다시 작성하고, 도구 호출을 거부하고, 원래라면 확인을 요청했을 호출을 승인하고, 인터페이스에 그릴 수 있습니다.

  • deny 규칙과 관리형 훅이 우선합니다. 가드가 로드된 환경에서는 규칙이 어느 설정 파일에 있든 사용자의 mod가 deny 규칙이 거부하는 호출을 승인할 수 없습니다. 관리형 설정의 PreToolUse 훅에 의한 차단도 최종적입니다. 두 가지 모두 Claude의 도구 호출에 적용됩니다. 어느 것도 mod 자체의 $.fs 및 $.process 호출에는 적용되지 않습니다. Read(.env)가 거부되어 있어도 mod는 여전히 $.fs.read로 해당 파일을 읽거나 파일을 읽는 프로그램을 시작할 수 있습니다. 이러한 호출을 제한하려면 mod가 로드되지 않도록 하거나 정책 mod에서 호출을 처리하십시오.

  • 다른 권한 검사는 재정의될 수 있습니다. 도구 호출을 승인하는 사용자의 mod는 ask 규칙이 확인을 요청할 호출이나 관리형 설정 외부의 PreToolUse 훅이 차단한 호출을 승인할 수 있습니다. 자동 모드에서는 mod가 승인한 호출이 분류기 검사 없이 실행됩니다.

가드의 소스는 Claude Code 저장소의 mods/sec-default 디렉터리에 공개되어 있습니다.

계속 적용되는 제어 알아보기

mod는 기존 제어를 대체하지 않습니다.

  • 설정 훅은 계속 작동합니다. 설정 파일과 플러그인의 hooks/hooks.json에 있는 command, HTTP, prompt, agent 훅은 mod와 함께 이전과 같이 실행됩니다. 이들 중 deprecated된 것은 없습니다.
  • 가드가 로드된 환경에서는 deny 규칙이 우선합니다. allowModsToOverrideDenyRules를 설정하지 않는 한, 사용자의 mod는 deny 규칙이 거부하는 호출을 승인할 수 없습니다.
  • 관리형 훅이 먼저 실행됩니다. 관리형 설정의 PreToolUse 훅은 어떤 mod보다도 먼저 도구 호출을 확인하며, 그 차단은 최종적입니다. 이후 mod가 호출을 다시 작성하면 관리형 훅이 다시 작성된 호출에 대해 다시 실행되므로 차단은 여전히 적용됩니다. 다른 설정 파일과 플러그인의 PreToolUse 훅은 마지막 mod 이후에 실행되므로, 도구를 실행하는 대신 자체 결과를 반환하는 mod는 해당 훅이 실행되지 않도록 합니다. mod 실행 순서를 참조하십시오.
  • 네트워크 정책은 $.http.fetch에 적용됩니다. 조직에서 웹 가져오기를 끄거나 세션에서 필수적이지 않은 네트워크 트래픽이 꺼져 있으면, Claude Code는 mod가 $.http.fetch로 보내는 네트워크 요청을 거부합니다. 이 정책은 mod가 $.process.run으로 시작하는 프로그램에는 적용되지 않습니다. 해당 프로그램은 사용자 자신의 액세스 권한으로 네트워크에 접근합니다.
  • 플러그인 제어는 mod에도 적용됩니다. mod는 플러그인이므로 strictKnownMarketplaces와 같은 사용자가 설치할 수 있는 항목을 제한하는 설정에 따라 설치 가능 여부가 결정됩니다.
  • mod는 권한 프롬프트를 변경할 수 없습니다. mod는 Claude Code 인터페이스의 상당 부분의 스타일을 바꿀 수 있지만 권한 프롬프트는 바꿀 수 없으므로, 프롬프트에 표시되는 내용을 변경할 수 없습니다. 다만 기본 동작 알아보기에서 설명한 것처럼, mod는 프롬프트가 나타나기 전에 도구 호출을 승인하거나 거부할 수 있습니다.
  • 신뢰 프롬프트가 먼저 나타납니다. 사용자가 아직 신뢰하지 않은 디렉터리의 대화형 세션에서는 사용자가 신뢰 프롬프트에 응답할 때까지 어떤 mod도 로드되지 않습니다.
  • --safe-mode는 관리자의 mod를 포함하여 설치된 mod를 끕니다. mod가 문제를 일으켰는지 확인하려면 claude --safe-mode로 세션을 시작하십시오.

이러한 제어 중 어느 것도 mod를 샌드박스에 격리하지 않습니다. 허용된 mod는 사용자로서 실행되며, 파일, 프로세스, 네트워크에 대한 사용자의 액세스 권한을 가집니다.

mod를 켜 둘지 결정하기

mod는 Claude Code 내부에서 실행되므로 플러그인의 다른 구성 요소보다 더 많은 작업을 할 수 있습니다. mod는 모든 프롬프트와 도구 호출을 확인하고 변경할 수 있으며, 권한 프롬프트가 표시되기 전에 도구 호출을 허용하거나 거부할 수 있습니다.

사용자가 mod로 로드할 수 있는 항목은 이미 적용된 플러그인 제어 방식에 따라 달라집니다.

현재 플러그인 제어 방식 사용자가 mod로 로드할 수 있는 항목
없음 모든 마켓플레이스의 mod, --plugin-dir로 지정한 모든 디렉터리의 mod, 또는 세션 중에 Claude가 작성한 mod
마켓플레이스 허용 목록 허용한 마켓플레이스의 mod 또는 --plugin-dir로 지정한 모든 디렉터리의 mod. 세션 중에 Claude가 작성한 mod는 허용 목록에 skills-dir이 포함된 경우에만 로드됩니다.
마켓플레이스 허용 목록 및 disableSideloadFlags 허용한 마켓플레이스의 mod

조직의 플러그인 관리에서 플러그인이 로드되는 방식과 각 방식을 제어하는 설정을 확인할 수 있습니다.

사용자가 설치하기 전에 마켓플레이스의 mod를 검토하려면 mod가 할 수 있는 작업 검토하기를 참조하십시오. 검토를 마칠 때까지 사용자의 mod를 차단하려면 사용자가 설치한 mod의 로드 중지하기를 참조하십시오.

mod가 할 수 있는 작업 검토하기

mod를 실행하지 않고도 mod가 할 수 있는 작업을 확인할 수 있습니다. 셸에서 플러그인 디렉터리를 대상으로 claude plugin validate를 실행합니다.

claude plugin validate ./some-mod

출력 중 두 줄이 mod의 코드를 설명합니다.

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

hooks: 줄은 mod가 수신하는 이벤트를 나열합니다. calls: 줄은 mod 코드가 호출하는 mods API 메서드를 나열합니다. mod 코드에서 $로 표기되는 mods API는 mod가 파일, 프로세스, 네트워크에 접근하는 수단입니다. Claude Code는 이 명령으로 읽을 수 없는 방식으로 mods API를 사용하는 mod의 로드를 거부합니다.

calls: 줄에서 다음 항목을 확인하십시오.

호출 의미
$.fs.read, $.fs.write 사용자가 접근할 수 있는 모든 위치의 파일을 읽거나 씁니다
$.process.run, $.process.spawn 사용자 권한으로 프로그램을 시작합니다
$.http.fetch 네트워크 요청을 보냅니다
$.env.get, $.settings.read API 키가 포함될 수 있는 환경 변수와 설정을 읽습니다. 출력의 env reads: 줄에 각 변수의 이름이 표시됩니다.
$.env.set Claude Code와 이후 Claude Code가 시작하는 모든 명령 및 MCP 서버에 환경 변수를 설정하며, 이로 인해 해당 프로그램이 실행하는 내용이 바뀔 수 있습니다. env writes: 줄에 각 변수의 이름이 표시됩니다.
$.mcp.call 세션의 권한 규칙에 따라 연결된 MCP 서버의 도구를 호출합니다
$.model.complete 모델 호출에 사용자의 플랜 또는 API 키를 사용합니다
$.prompt.submit 프롬프트를 제출하며, 사용자가 직접 작성한 것처럼 보낼 수 있습니다
$.session.send 다른 세션 또는 서브에이전트의 Claude가 읽는 메시지를 보냅니다

hooks: 줄에서 tool.call과 prompt.submit은 mod가 모든 도구 호출과 모든 프롬프트를 확인하고 변경할 수 있음을 의미합니다. session.append는 mod가 대화의 각 행이 저장되기 전에 이를 다시 작성할 수 있음을 의미합니다. ui.render{component=AskUserQuestion}는 Claude가 사용자에게 질문할 때 사용하는 대화 상자를 mod가 다시 그릴 수 있음을 의미합니다. tool.check는 권한 프롬프트가 표시되기 전에 mod가 도구 호출을 승인하거나 거부할 수 있음을 의미합니다. 기본 동작 알아보기에서 mod의 응답보다 우선 적용되는 규칙과 훅을 확인할 수 있습니다.

허용 범위 선택하기

mod 정책은 설치된 mod를 전혀 허용하지 않는 것부터 사용자가 선택한 모든 mod를 허용하되 조직의 자체 mod가 다른 mod를 검사하는 것까지 다양하며, 각 정책은 몇 가지 관리형 설정으로 구성됩니다. 첫 번째 열에서 원하는 정책을 찾고 두 번째 열에 명시된 항목을 설정하십시오. 관리형 설정의 위치는 관리형 설정 배포하기에서 다룹니다.

원하는 결과 설정
설치된 mod는 허용하지 않고 훅은 그대로 유지 allowManagedModsOnly를 설정하고 조직 자체의 mod는 배포하지 않음
설치된 mod와 훅을 모두 허용하지 않음(관리형 훅 포함) disableAllHooks를 true로 설정
조직의 mod만 허용 가드의 allowManagedModsOnly 옵션을 설정하고, 조직의 mod로 인정되도록 mod를 설치
승인한 마켓플레이스의 모든 mod 허용 마켓플레이스 제한을 유지하고 disableSideloadFlags를 true로 설정
모든 mod를 허용하되 조직의 자체 mod가 다른 mod를 검사 mod를 설치하고 prependPlugins에 sec-default@builtin과 함께 나열

각 설정의 역할은 다음과 같습니다.

  • allowManagedModsOnly: 기본 제공 가드의 옵션입니다. 사용자가 직접 설치한 mod는 로드되지 않으며, 사용자의 설정 훅, 상태줄, /goal은 계속 작동합니다. 적용 범위는 사용자가 설치한 mod의 로드 차단하기에 나와 있습니다.
  • allowManagedHooksOnly: 더 넓은 범위의 설정입니다. 조직의 mod와 Claude Code에 기본 제공되는 mod만 로드됩니다. 사용자가 직접 설치한 mod는 로드되지 않습니다. 이 설정은 사용자 자체 설정 파일의 훅도 차단합니다. 설정하기 전에 allowManagedHooksOnly에서 실행되는 항목을 확인하십시오.
  • disableAllHooks: 가장 넓은 범위의 설정입니다. 관리형 설정에서 사용하면 조직의 플러그인을 포함해 설치된 모든 플러그인의 mod를 중지하고 설정 파일의 모든 훅을 끄므로, 관리형 설정의 PreToolUse 훅도 더 이상 아무것도 차단하지 않습니다. 사용자 지정 상태줄과 /goal도 작동하지 않습니다. 설정하기 전에 disableAllHooks를 확인하십시오.
  • disableSideloadFlags: 시작 시 --plugin-dir와 --plugin-url을 거부하고, 세션 중에 Claude가 작성한 mod가 로드되지 않도록 합니다. 이 설정은 --agents와 --mcp-config도 거부합니다. 설정하기 전에 disableSideloadFlags를 확인하십시오.

AGENTS.md 지원과 같이 Claude Code에 기본 제공되는 mod는 이러한 설정의 영향을 받지 않습니다. 각 mod에는 자체 스위치가 있습니다.

mod가 로드되지 않은 사용자는 디버그 로그에서 그 이유를 확인할 수 있습니다. 거부 메시지에는 allowManagedHooksOnly와 disableAllHooks에 해당하는 줄이 나와 있으며, 기본 제공 가드의 메시지에는 allowManagedModsOnly에 해당하는 줄이 나와 있습니다.

조직의 mod만 허용하기

조직의 mod를 실행하고 사용자가 가져온 mod를 차단하려면 정책 표의 조직의 mod만 허용 행에 있는 설정과 함께 disableSideloadFlags를 배포하십시오. 다음의 완전한 managed-settings.json을 사용하면 Claude Code가 사용자 자체 mod를 거부하므로 사용자의 훅은 하나도 실행되지 않으며, 조직의 정책 mod가 다른 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
}

각 키 그룹은 다음과 같은 역할을 합니다.

  • extraKnownMarketplaces, enabledPlugins, prependPlugins: 조직의 mod로 인정되도록 mod를 설치하고, 해당 mod를 가장 먼저 실행한 뒤 가드를 실행합니다. 이 키들이 가리키는 디렉터리는 조직의 mod 설치 및 순서 설정하기에서 다룹니다.
  • pluginConfigs: 가드의 allowManagedModsOnly 옵션을 설정하여 Claude Code가 사용자 자체 mod를 거부하도록 합니다. 사용자의 설정 훅, 상태줄, /goal은 계속 작동합니다.
  • disableSideloadFlags: 시작 시 거부되는 플래그는 disableSideloadFlags를 참조하십시오.

테스트 머신에서 정책을 확인하려면 셸에서 claude --debug로 세션을 시작하고 디버그 로그를 확인하십시오.

  • 조직의 mod: 해당 mod의 hooks module 줄에 tier prepend가 있습니다.
  • 사용자가 설치한 mod: refused by cc-plugin-sec-default: mods are limited to your organization's by policy (allowManagedModsOnly)라는 줄이 표시됩니다. 그보다 앞선 줄에 해당 mod의 훅 모듈이 loaded되었다고 표시되므로 거부 메시지를 찾아보십시오.
  • 플러그인 디렉터리: claude --plugin-dir ./any-mod가 --plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)로 시작하는 메시지와 함께 종료됩니다.

사용자가 추가할 수 있는 마켓플레이스도 제한하려면 이 파일을 마켓플레이스 제한과 함께 사용하십시오.

mod에 플러그인 제어 적용하기

mod는 플러그인이므로 조직의 플러그인을 관리하는 방법은 mod를 포함하는 플러그인에도 적용됩니다.

기본 제공 가드의 옵션 설정하기

기본 제공 가드는 옵션을 받습니다. 사용자가 설치한 mod의 로드 차단하기의 예시처럼, 관리형 설정의 pluginConfigs 아래에 cc-plugin-sec-default@builtin을 키로 하여 옵션을 설정하십시오.

다음 표는 각 옵션을 설정하지 않았을 때와 true로 설정했을 때 사용자에게 적용되는 결과를 보여 줍니다.

옵션 미설정 true
allowManagedModsOnly 사용자 자체 mod가 로드됨 조직의 mod와 Claude Code에 기본 제공되는 mod만 로드됩니다. 사용자가 설치했거나 --plugin-dir로 지정한 mod를 포함해 그 밖의 모든 mod는 Claude Code가 거부합니다.
allowModsToOverrideDenyRules 거부 규칙이 사용자 mod보다 우선함 도구 호출을 승인하는 사용자 mod가 deny 규칙이 거부한 호출을 승인할 수 있음

옵션의 적용 여부는 다음 규칙에 따라 결정됩니다.

  • 여기서는 ID 형식이 하나뿐입니다: Claude Code는 cc-plugin-sec-default@builtin 아래의 옵션만 읽습니다. prependPlugins는 sec-default@builtin도 허용하지만 pluginConfigs는 허용하지 않습니다.
  • 관리형 설정만 적용됩니다: 사용자, 프로젝트 또는 로컬 설정 파일이나 --settings로 전달된 파일에 동일한 항목이 있어도 옵션을 설정하거나 완화하지 않습니다.
  • 가드가 로드되어야 합니다: prependPlugins를 설정하는 경우 목록에 가드를 포함하십시오. 가드가 로드되지 않으면 두 옵션 모두 적용되지 않습니다.
  • 가드는 실패 시 차단합니다: 가드가 관리형 설정을 읽을 수 없으면 로드 시점에 모든 사용자 mod를 거부합니다. 사용자 mod가 승인한 호출에 대해 거부 규칙을 확인할 수 없으면 해당 호출을 거부합니다.

두 옵션 중 하나가 적용될 때 사용자에게 표시되는 내용은 기본 제공 가드의 메시지에 나와 있습니다.

조직 자체 mod 실행하기

자체 mod를 모든 사용자에게 배포하고, 사용자 mod를 기준으로 실행 위치를 정하고, mod를 사용해 정책을 적용할 수 있습니다.

조직의 mod 설치 및 순서 설정하기

조직의 mod는 사용자 mod가 로드되지 않는 곳에서도 로드되며 사용자 mod보다 먼저 실행될 수 있으므로, Claude Code는 mod가 조직에서 온 것인지 구분할 수 있어야 합니다. Claude Code는 다음 조건이 모두 충족될 때만 mod를 조직의 mod로 취급합니다.

  • 관리형 enabledPlugins가 mod의 플러그인을 true로 설정합니다
  • 관리형 설정이 플러그인의 마켓플레이스를 사용자 컴퓨터의 디렉터리로, 절대 경로를 통해 지정합니다. extraKnownMarketplaces 항목이 이를 수행하며 사용자에게 마켓플레이스도 등록합니다.
  • 마켓플레이스가 플러그인을 상대 경로로 나열하므로, Claude Code가 해당 디렉터리에서 플러그인을 제자리에서 로드합니다

이 조건을 충족하려면 디바이스 관리 도구가 마켓플레이스 디렉터리를 모든 컴퓨터의 동일한 경로에 복사하도록 하십시오. 관리형 설정 파일과 마찬가지로 해당 디렉터리와 그 상위의 모든 디렉터리는 관리자만 쓸 수 있도록 설정하십시오. 그곳에 쓸 수 있는 사람은 누구나 mod를 다시 작성할 수 있습니다. claude.ai 관리 콘솔에서 제공하는 관리형 설정에는 해당 키를 포함할 수 있지만, 디렉터리를 컴퓨터에 배치할 수는 없습니다.

디렉터리에는 마켓플레이스의 매니페스트와 플러그인이 들어 있습니다.

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

매니페스트는 해당 디렉터리를 기준으로 한 상대 경로로 플러그인을 나열합니다.

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

Claude Code가 캐시에 복사하는 플러그인은 관리형 enabledPlugins가 활성화하더라도 사용자의 플러그인으로 간주됩니다. GitHub, git, URL 또는 npm 소스의 모든 플러그인이 이에 해당합니다. 해당 플러그인의 mod는 사용자 mod와 함께 실행되고, prependPlugins와 appendPlugins는 이를 건너뛰며, allowManagedModsOnly 또는 allowManagedHooksOnly에서는 로드되지 않습니다. 사용자의 디버그 로그에는 플러그인 ID와 is enabled by managed settings, but으로 시작하는 줄이 기록됩니다.

Claude Code는 도구 실행과 같은 작업을 수행하려 할 때마다 이벤트를 발생시키고 이를 각 mod에 차례로 전달합니다. 조직의 것으로 간주되는 mod는 어디에도 나열하지 않더라도 사용자 mod보다 먼저 실행됩니다. 실행 위치를 지정하려면 두 설정 중 하나에 해당 ID를 나열하십시오. ID는 플러그인 이름, @, 마켓플레이스 이름으로 구성되며, 예를 들어 acme-guard@acme-tools와 같습니다.

  • prependPlugins: mod가 모든 이벤트를 어떤 사용자 mod보다 먼저 보고 모든 결과를 마지막에 봅니다. 이벤트를 변경하거나, 거부하거나, 사용자 mod를 건너뛸 수 있습니다.
  • appendPlugins: mod가 모든 사용자 mod 이후에 실행되므로, 해당 mod들이 전달하는 이벤트만 전달된 형태 그대로 봅니다

다음 예시는 /opt/acme/claude-plugins에 acme-tools 마켓플레이스를 선언하고, 여기서 acme-guard를 활성화한 뒤, 해당 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"]
}

각 키는 한 가지 역할을 합니다.

  • extraKnownMarketplaces: acme-tools 마켓플레이스가 있는 디렉터리를 지정합니다. path는 .claude-plugin/marketplace.json이 포함된 디렉터리의 절대 경로입니다.
  • enabledPlugins: 이 관리형 설정을 받는 모든 사용자에 대해 acme-guard를 켭니다
  • prependPlugins: acme-guard를 첫 번째로, 기본 제공 가드를 두 번째로 배치하며, 둘 다 사용자가 설치한 모든 mod보다 앞에 둡니다. Claude Code는 나열된 순서를 따릅니다.

사용자 컴퓨터가 설정을 받았는지 확인하려면 정책이 적용되었는지 확인하기를 참조하십시오.

mod가 실행되는 위치를 확인하려면 해당 컴퓨터에서 claude --debug로 세션을 시작하고 디버그 로그에서 mod의 ID를 검색하십시오.

  • tier prepend가 포함된 hooks module acme-guard@acme-tools loaded: 해당 mod가 조직의 mod로 간주되며 가장 먼저 실행됩니다
  • tier user가 포함된 같은 줄: Claude Code가 이를 사용자의 mod로 취급합니다. 두 번째 줄인 prependPlugins names acme-guard@acme-tools, which is not an enabled managed plugin with a hooks module; skipped는 목록이 해당 mod를 건너뛰었음을 나타냅니다.

다음 규칙에 따라 두 목록의 ID 중 어떤 것이 적용되는지 결정됩니다.

  • 목록이 기본값을 대체합니다: 관리형 설정에서 prependPlugins를 설정하는 경우, 기본 제공 가드를 유지하려면 목록에 sec-default@builtin을 지정하십시오. 이 가드는 기본 제공되므로 enabledPlugins 항목이 필요하지 않습니다.
  • 자체 ID는 조직의 것으로 간주되어야 합니다: 관리형 설정에서 Claude Code는 플러그인이 조직 mod의 조건을 충족하지 않는 ID를 건너뜁니다
  • 저장소에서는 설정할 수 없습니다: Claude Code는 두 설정을 관리형 설정에서 읽으며 저장소의 설정 파일에서는 절대 읽지 않습니다. 사용자는 관리형 설정이 없는 컴퓨터에서, 그리고 Team 또는 Enterprise 플랜으로 로그인하지 않은 경우에만 ~/.claude/settings.json에서 이를 설정하여 자신의 mod 순서를 정할 수 있습니다. 그 외의 경우 Claude Code는 사용자 설정의 두 키를 모두 무시합니다. 그곳의 목록은 기본 제공 가드를 추가하지도 제거하지도 않습니다.

자체 mod로 정책 적용하기

모든 사용자 mod를 차단하는 데는 자체 mod가 필요하지 않습니다. allowManagedModsOnly를 설정하십시오. 일부 사용자 mod는 허용하고 다른 mod는 거부하려는 경우, 또는 mod가 수행하는 작업을 기록하려는 경우에 정책 mod를 작성하십시오.

다른 mod가 로드되려 할 때마다 mod는 plugin.register라는 이벤트를 통해 claude plugin validate가 출력하는 목록을 받습니다. prependPlugins에 있는 mod는 해당 목록을 읽고 mod를 거부할 수 있습니다. 또한 모든 mods API 호출을 이름으로 처리하여 다른 모든 mod에 대해 해당 호출을 기록하거나 거부할 수 있습니다. 이름은 $.를 제외한 메서드이므로, fs.write에 대한 훅은 모든 $.fs.write 호출을 봅니다.

이 정책 mod는 자체 코드에서 $.process.run 또는 $.process.spawn을 호출하는 모든 사용자 mod를 거부합니다. 또한 각 도구 호출과 mod가 쓰는 각 파일을 디버그 로그에 기록하여 감사 로그를 유지합니다. 가장 먼저 실행되므로, 로그에는 사용자 mod가 변경하기 전에 요청된 내용이 기록됩니다. 이를 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)
  })
}

이 파일은 세 개의 훅을 등록합니다.

  • plugin.register: 다른 mod의 로드 여부를 결정합니다. 차단된 메서드를 호출하는 사용자 mod를 거부하고 다른 모든 mod는 통과시킵니다.
  • tool.call: 각 도구 호출에 대해 audit tool.call Bash와 같은 줄을 디버그 로그에 쓰며, 아무것도 변경하지 않습니다
  • fs.write: 다른 mod가 수행하는 각 $.fs.write 호출에 대해 audit fs.write by reader "/tmp/notes.md"와 같은 줄을 쓰며, 아무것도 변경하지 않습니다. mod의 이름이 먼저 오고 경로는 따옴표로 묶이므로, mod가 선택한 경로가 줄의 다른 필드로 위장할 수 없습니다.

plugin.register 훅은 이벤트의 두 필드를 읽습니다.

  • e.tier: mod가 실행될 위치로, prepend, user, append, builtin 중 하나입니다. 사용자가 설치하는 모든 mod는 user입니다.
  • e.uses.calls: mod가 호출하는 mods API 메서드로, 각각 process.run과 같이 namespace.method 형식으로 작성되며 claude plugin validate가 출력하는 $.는 포함하지 않습니다

사용자가 $.process.run을 호출하는 mod를 설치하면 해당 mod는 로드되지 않으며, 사용자의 디버그 로그에는 refused by acme-guard:와 지정한 사유로 끝나는 줄이 기록됩니다. 거부 내용은 플러그인 디렉터리를 핫 리로드하는 세션의 트랜스크립트에도 표시됩니다. mod 전체를 거부하지 않고 특정 호출만 차단하려면 해당 호출 이름에 대한 훅에서 { deny: 'your reason' }을 반환하십시오.

감사 로그 줄을 디버그 로그가 아닌 다른 곳으로 보내려면 같은 훅에서 $.http.fetch를 호출하십시오.

세션은 조직의 mod 없이 실행될 수 있습니다. 설치된 mod를 실행하는 워커 스레드가 세 번 충돌하면, Claude Code는 사용자가 /reload-plugins를 실행하거나 새 세션을 시작할 때까지 조직의 mod를 포함하여 기본 제공되지 않는 모든 mod를 언로드합니다. 또한 --safe-mode로 Claude Code를 시작한 사용자는 조직의 mod를 포함하여 설치된 mod 없이 실행합니다.

mod 만들기에서 mod에 필요한 파일을 다룹니다. 정책 mod 테스트하기에는 이 정책 mod를 위한 테스트 파일이 있습니다.

검사가 실패할 때 mod 거부하기

plugin.register 훅이 예외를 발생시키거나 시간 제한을 초과하면 Claude Code는 해당 훅을 건너뛰므로, 검사가 개방 상태로 실패하여 검사 중이던 mod가 로드됩니다. 폐쇄 상태로 실패하여 사용자 mod를 거부하려면 검사를 이름이 지정된 함수로 옮기고 거부를 반환하는 .catch 핸들러를 추가하십시오. 이 버전의 파일은 plugin.register 훅만 보여 주므로, 첫 번째 버전의 두 감사 훅은 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' }
  })
}

핸들러가 있으면 검사가 예외를 발생시키거나 시간 초과되었을 때 검사 중이던 mod는 로드되지 않으며, 거부 줄에는 refused by acme-guard: Acme policy check failed, so this mod was not loaded와 같이 두 번째 사유가 표시됩니다. 핸들러는 user 티어 외의 모든 mod를 next(e)로 전달하므로, 검사가 실패해도 조직이 나열한 mod는 중단되지 않습니다. 다른 이벤트에 대한 .catch는 실패한 훅 처리하기에서 다룹니다.

다음 단계

  • 플러그인 보안: 플러그인이 사용자의 컴퓨터에서 할 수 있는 작업과 설치 전에 플러그인을 검토하는 방법
  • Mod 개요: mod의 정의와 훅, 스킬, MCP 서버와의 비교
  • mod 실행 순서: prependPlugins와 appendPlugins가 사용자의 mod와 어떻게 맞물리는지
  • 설정 및 환경 변수: 이 페이지에서 언급된 모든 설정을 하나의 표로 정리