{"meta":{"title":"Использование крючков с Copilot CLI для предсказуемого, соответствующего политикам исполнения","intro":"Используйте крючки для регистрации пользовательских запросов и контроля, какие инструменты Второй пилот CLI могут работать в репозитории, чтобы команды могли безопасно автоматизировать работу в рамках требований безопасности и соответствия вашей организации.","product":"GitHub Copilot","breadcrumbs":[{"href":"/ru/copilot","title":"GitHub Copilot"},{"href":"/ru/copilot/tutorials","title":"Учебники"},{"href":"/ru/copilot/tutorials/copilot-cli-hooks","title":"Используйте крючки с помощью Copilot CLI"}],"documentType":"article"},"body":"# Использование крючков с Copilot CLI для предсказуемого, соответствующего политикам исполнения\n\nИспользуйте крючки для регистрации пользовательских запросов и контроля, какие инструменты Второй пилот CLI могут работать в репозитории, чтобы команды могли безопасно автоматизировать работу в рамках требований безопасности и соответствия вашей организации.\n\nЭтот туториал предназначен для инженеров DevOps, команд платформ и инженерных лидеров, которые поддерживают разработчиков с использованием Второй пилот CLI.\n\nХуки — это кастомные скрипты, которые выполняются в определённые моменты сессии Второй пилот CLI . Они могут проверять запросы и вызовы инструментов, вести лог для аудита и даже блокировать выполнение определённых команд.\n\nВы настроите крючки с репозиторием, которые:\n\n* Обеспечивайте видимость в подсказках и использовании инструментов.\n* Блокируйте опасные паттерны команд перед выполнением.\n* Помогите разработчикам понять организационные политики с помощью чётких сообщений.\n\n## Предпосылки\n\n* Знакомство с скриптингом shell (Bash или PowerShell).\n* Базовое понимание конфигурационных файлов JSON.\n* Доступ к репозиторию, где Второй пилот CLI используется функция.\n* Для примеров с Bash: `jq` нужно установить устройство.\n* Для примеров с PowerShell: необходимо установить PowerShell 7.0 или новее.\n\n## 1. Определить организационную политику\n\nПрежде чем писать скрипты с крючками, решите, какие действия должны быть разрешены автоматически, а какие требуют человеческого рассмотрения.\n\nЧёткая политика помогает избежать чрезмерной блокировки, одновременно снижая риски.\n\n### Определите команды, которые всегда требуют повторения\n\nНачните с определения закономерностей, которые никогда не должны выполняться автоматически .Второй пилот CLI Распространенные примеры:\n\n* **Повышение привилегий**: `sudo`, `su`, `runas`\n* **Деструктивные операции системы**: `rm -rf /`, `mkfs`, `dd`, `format`\n* **Шаблоны загрузки и выполнения**: `curl ... | bash`, `wget ... | sh`, PowerShell `iex (irm ...)`\n\nЭти команды могут иметь необратимые последствия, если выполняться непреднамеренно.\n\n### Решите, что именно записывать\n\nПри использовании крючков можно зафиксировать информацию о том, как Второй пилот CLI используется репозиторий, включая подсказки, присланные пользователями, и инструменты, которые Второй пилот CLI пытаются запустить.\n\nМинимум, большинство организаций ведут регистрацию:\n\n* Временная метка и путь репозитория\n* Текст запроса (или отредактированная форма)\n* Название инструмента и аргументы инструмента\n* Любое политическое решение (например, отклонённая команда и её причина)\n\nИзбегайте регистрации секретов или учетных данных. Если подсказки или команды могут содержать конфиденциальные данные, примените редактирование перед записыванием журналов.\n\nВ этом учебном пособии используется локальный каталог `.github/hooks/logs` в качестве простого и иллюстративного примера. Эти лог-файлы **не предназначены для фиксации в репозитории** и обычно находятся только на машине разработчика.\n\nВ производственных условиях многие организации пересылают события hook в централизованную систему логирования или наблюдаемости вместо локальной записи журналов. Это позволяет командам применять последовательные редактирования, контроли access, политики хранения и мониторинг между репозиториями и пользователями.\n\n### Согласование с заинтересованными сторонами\n\nПеред применением политики изучите их следующими:\n\n* Команды безопасности или комплаенса, чтобы подтвердить границы рисков\n* Команды платформы или инфраструктуры, которым могут понадобиться более широкие разрешения\n* Команды разработки, чтобы они понимали, что будет заблокировано и почему\n\nЧёткие ожидания облегчают принятие и поддержание исполнения политики.\n\n## 2. Настройте файлы с крючками репозитория\n\nВ течение этого урока вы будете использовать **repository-scoped hooks** хранящиеся в репозитории под `.github/hooks/`. Эти крючки применяются всякий раз, когда Второй пилот CLI сервер запускается из этого репозитория.\n\n> \\[!NOTE]\n> Copilot Агенты загружают конфигурации крюков из `.github/hooks/*.json` файлов в репозитории. Крючки работают синхронно и могут блокировать выполнение.\n\n### Создать структуру каталога\n\nИз корня репозитория создайте каталоги для конфигурации хуков, скриптов и логов:\n\n```bash copy\nmkdir -p .github/hooks/scripts\nmkdir -p .github/hooks/logs\n```\n\nДобавьте `.github/hooks/logs/` в .gitignore для того, чтобы локальные журналы аудита не фиксировались:\n\n```bash copy\necho \".github/hooks/logs/\" >> .gitignore\n```\n\nЭтот учебник использует следующую структуру:\n\n```text\n.github/\n└── hooks/\n    ├── copilot-cli-policy.json\n    ├── logs/\n    │   └── audit.jsonl\n    └── scripts/\n        ├── session-banner.sh\n        ├── session-banner.ps1\n        ├── log-prompt.sh\n        ├── log-prompt.ps1\n        ├── pre-tool-policy.sh\n        └── pre-tool-policy.ps1\n```\n\n> \\[!NOTE]\n> Этот учебник направлен на создание портативных конфигураций и скриптов, которые можно использовать на Windows, Linux и macOS. Таким образом, каталог `scripts` будет содержать скрипты Bash и PowerShell, а файлы конфигурации хуков будут включать `bash` и `powershell` записи. CLI использует соответствующую запись, основанную на вашей операционной системе.\n\n### Создайте конфигурационный файл крючка\n\nСоздайте конфигурационный файл с крючком по координатам `.github/hooks/copilot-cli-policy.json`.\n\nЭтот файл определяет, какие хуки запускаются, когда они запускаются и какие скрипты они выполняют.\n\n```json copy\n{\n  \"version\": 1,\n  \"hooks\": {\n    \"sessionStart\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"./scripts/session-banner.sh\",\n        \"powershell\": \"./scripts/session-banner.ps1\",\n        \"cwd\": \".github/hooks\",\n        \"timeoutSec\": 10\n      }\n    ],\n    \"userPromptSubmitted\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"./scripts/log-prompt.sh\",\n        \"powershell\": \"./scripts/log-prompt.ps1\",\n        \"cwd\": \".github/hooks\",\n        \"timeoutSec\": 10\n      }\n    ],\n    \"preToolUse\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"./scripts/pre-tool-policy.sh\",\n        \"powershell\": \"./scripts/pre-tool-policy.ps1\",\n        \"cwd\": \".github/hooks\",\n        \"timeoutSec\": 15\n      }\n    ]\n  }\n}\n```\n\n### Поймите, что делает эта конфигурация\n\nЭта конфигурация задаёт три крючка:\n\n* `sessionStart`: Показывает информационное сообщение при начале или возобновлении сессии нового агента.\n* `userPromptSubmitted`: Запускается всякий раз, когда пользователь отправляет запрос.\n* `preToolUse`: Запускается до запуска инструмента и может явно разрешать или отклонять выполнение.\n\n### Зафиксируйте и поделитесь конфигурацией хука\n\nКогда будете готовы поделиться конфигурацией крючка с соавторами (например, через pull-запрос или в тестовом репозитории), зафиксируйте конфигурацию хука и скрипты. Не фиксируйте локальные журналы аудита.\n\n```bash copy\ngit add .github/hooks/copilot-cli-policy.json .github/hooks/scripts\ngit commit -m \"Add Copilot CLI hook configuration\"\ngit push\n```\n\nНа этом этапе Второй пилот CLI можно найти конфигурацию крючка, даже если скрипты для хука вы ещё не создали.\n\n## 3. Добавить баннер политики при начале сессии\n\nИспользуйте `sessionStart` крючок, чтобы отображать баннер при каждом старте или возобновлении новой Второй пилот CLI сессии. Это ясно даёт разработчикам понять, что организационные политики активны.\n\n```\n          `sessionStart` Крючок получает контекстную информацию, такую как текущий рабочий каталог и начальный запрос. Любой вывод этого крючка игнорируется , Второй пилот CLIчто делает его подходящим для информационных сообщений.\n```\n\n### Создать скрипт сессионного баннера (Bash)\n\nСоздать `.github/hooks/scripts/session-banner.sh`:\n\n```bash copy\n#!/bin/bash\nset -euo pipefail\n\ncat << 'EOF'\nCOPILOT CLI POLICY ACTIVE\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n• Prompts and tool use may be logged for auditing\n• High-risk commands may be blocked automatically\n• If something is blocked, follow the guidance shown\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\nEOF\nexit 0\n```\n\n### Создать скрипт сессионного баннера (PowerShell)\n\nСоздать `.github/hooks/scripts/session-banner.ps1`:\n\n```powershell copy\n$ErrorActionPreference = \"Stop\"\n\nWrite-Host @\"\nCOPILOT CLI POLICY ACTIVE\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n• Prompts and tool use may be logged for auditing\n• High-risk commands may be blocked automatically\n• If something is blocked, follow the guidance shown\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\"@\nexit 0\n```\n\n### Протестируйте баннер сессии\n\nВы можете протестировать баннерные скрипты напрямую:\n\n```bash\n.github/hooks/scripts/session-banner.sh\n# or, for PowerShell\n.github/hooks/scripts/session-banner.ps1\n```\n\nКогда вы запускаете любой из этих скриптов, вы должны увидеть баннер политики в терминале.\n\n## 4. Журнал запросов для аудита\n\nИспользуйте `userPromptSubmitted` крючок для записи, когда пользователи отправляют запросы в Второй пилот CLI. Этот крюк запускается всякий раз, когда отправляется запрос, до запуска любых инструментов.\n\nКрючок получает структурированный JSON-ввод, включающий временную метку, текущий рабочий каталог и полный текст запроса. Вывод этого хука игнорируется.\n\n> \\[!IMPORTANT]\n> Подсказки могут содержать конфиденциальную информацию. Применяйте редактирование и следуйте политике обработки и хранения данных вашей организации при регистрации этих данных.\n\n### Создать скрипт логирования запросов (Bash)\n\nСоздать `.github/hooks/scripts/log-prompt.sh`:\n\n```bash copy\n#!/bin/bash\nset -euo pipefail\n\nINPUT=\"$(cat)\"\n\nTIMESTAMP_MS=\"$(echo \"$INPUT\" | jq -r '.timestamp // empty')\"\nCWD=\"$(echo \"$INPUT\" | jq -r '.cwd // empty')\"\n\n# This example logs only metadata, not the full prompt, to avoid storing\n# potentially sensitive data. Adjust to match your organization’s needs.\nLOG_DIR=\".github/hooks/logs\"\nmkdir -p \"$LOG_DIR\"\nchmod 700 \"$LOG_DIR\"\n\njq -n \\\n  --arg ts \"$TIMESTAMP_MS\" \\\n  --arg cwd \"$CWD\" \\\n  '{event:\"userPromptSubmitted\", timestampMs:$ts, cwd:$cwd}' \\\n  >> \"$LOG_DIR/audit.jsonl\"\n\nexit 0\n```\n\n### Создайте скрипт логирования запросов (PowerShell)\n\nСоздать `.github/hooks/scripts/log-prompt.ps1`:\n\n```powershell copy\n$ErrorActionPreference = \"Stop\"\n\n$inputObj = [Console]::In.ReadToEnd() | ConvertFrom-Json\n\n$timestampMs = $inputObj.timestamp\n$cwd = $inputObj.cwd\n$prompt = $inputObj.prompt\n\n# Optional example redaction. Adjust to match your organization’s needs.\n$redactedPrompt = $prompt -replace 'ghp_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]'\n\n$logDir = \".github/hooks/logs\"\nif (-not (Test-Path $logDir)) {\n  New-Item -ItemType Directory -Path $logDir -Force | Out-Null\n}\n\n$logEntry = @{\n  event       = \"userPromptSubmitted\"\n  timestampMs = $timestampMs\n  cwd         = $cwd\n  prompt      = $redactedPrompt\n} | ConvertTo-Json -Compress\n\nAdd-Content -Path \"$logDir/audit.jsonl\" -Value $logEntry\nexit 0\n```\n\n### Протестируйте скрипт логирования запросов\n\nВы можете тестировать скрипты напрямую, передавая пример ввода.\n\n```bash\necho '{\"timestamp\":1704614500000,\"cwd\":\"/repo\",\"prompt\":\"List all branches\"}' \\\n  | .github/hooks/scripts/log-prompt.sh\n# or, for PowerShell\necho '{\"timestamp\":1704614500000,\"cwd\":\"/repo\",\"prompt\":\"List all branches\"}' |\n  .github/hooks/scripts/log-prompt.ps1\n```\n\nПосле запуска скрипта проверьте `.github/hooks/logs/audit.jsonl` на наличие новой записи в журнале.\n\n```bash copy\ncat .github/hooks/logs/audit.jsonl\n```\n\nНа этом этапе запросы, поданные Второй пилот CLI в этом репозитории, записываются для аудита.\n\n## 5. Применять политики с помощью `preToolUse`\n\nИспользуйте крючок `preToolUse` , чтобы оценить вызов **инструмента перед его запуском**. Этот крючок может позволить выполнить (ничего не делая) или запретить выполнение (возвращая структурированный ответ).\n\n### Поймите вводные `preToolUse` данные\n\nВвод `preToolUse` с крюком включает:\n\n* `toolName`: Инструмент, который Второй пилот CLI вот-вот запустится (например, `bash`)\n* `toolArgs`: **JSON-строка** , содержащая аргументы этого инструмента\n\nПоскольку `toolArgs` это JSON-строка, ваш скрипт должен анализировать её перед чтением полей, таких как `command`.\n\n> \\[!IMPORTANT]\n> Аргументы и команды инструментов могут содержать конфиденциальную информацию, такую как токены API, пароли или другие учетные данные. Примените редактирование перед регистрацией этих данных и следуйте политикам безопасности вашей организации. Рассмотрите возможность логирования только нечувствительных метаданных (название инструмента, временная метка, решение по политике) и направлять аудитские события в защищённую централизованную систему логирования с соответствующими контролями access и политиками сохранения.\n\n### Создайте скрипт политики\n\nДалее создайте скрипт политики. В этом примере:\n\n* Записывает все попытки использования инструмента.\n* Применяет правила отказа только к командам удара.\n* Блокирует опасные паттерны, такие как повышение привилегий, разрушительные операции и команды на загрузку и выполнение.\n\nЧтобы безопасно проверить поток deny, скрипт также включает временное правило демонстрации, блокирующее безвредную команду тестирования. Убедившись, что крючки работают как следует, уберите правило демонстрации и замените его шаблонами, отражающими политику вашей организации.\n\n#### Пример сценария (Bash)\n\nСоздать `.github/hooks/scripts/pre-tool-policy.sh`:\n\n```bash copy\n#!/bin/bash\nset -euo pipefail\n\nINPUT=\"$(cat)\"\n\nTOOL_NAME=\"$(echo \"$INPUT\" | jq -r '.toolName // empty')\"\nTOOL_ARGS_RAW=\"$(echo \"$INPUT\" | jq -r '.toolArgs // empty')\"  # JSON string\n\nLOG_DIR=\".github/hooks/logs\"\nmkdir -p \"$LOG_DIR\"\n\n# Example redaction logic.\n# GitHub does not currently provide built-in secret redaction for hooks.\n# This example shows one possible approach; many organizations prefer to\n# forward events to a centralized logging system that handles redaction.\n# Redact sensitive patterns before logging.\n# Adjust these patterns to match your organization's needs.\nREDACTED_TOOL_ARGS=\"$(echo \"$TOOL_ARGS_RAW\" | \\\n  sed -E 's/ghp_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n  sed -E 's/gho_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n  sed -E 's/ghu_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n  sed -E 's/ghs_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n  sed -E 's/Bearer [A-Za-z0-9_\\-\\.]+/Bearer [REDACTED]/g' | \\\n  sed -E 's/--password[= ][^ ]+/--password=[REDACTED]/g' | \\\n  sed -E 's/--token[= ][^ ]+/--token=[REDACTED]/g')\"\n\n# Log attempted tool use with redacted toolArgs.\njq -n \\\n  --arg tool \"$TOOL_NAME\" \\\n  --arg toolArgs \"$REDACTED_TOOL_ARGS\" \\\n  '{event:\"preToolUse\", toolName:$tool, toolArgs:$toolArgs}' \\\n  >> \"$LOG_DIR/audit.jsonl\"\n\n# Only enforce command rules for bash.\nif [ \"$TOOL_NAME\" != \"bash\" ]; then\n  exit 0\nfi\n\n# Parse toolArgs JSON string.\n# If toolArgs isn't valid JSON for some reason, allow (and rely on logs).\nif ! echo \"$TOOL_ARGS_RAW\" | jq -e . >/dev/null 2>&1; then\n  exit 0\nfi\n\nCOMMAND=\"$(echo \"$TOOL_ARGS_RAW\" | jq -r '.command // empty')\"\n\n# ---------------------------------------------------------------------------\n# Demo-only deny rule for safe testing.\n# This blocks a harmless test command so you can validate the deny flow.\n# Remove this rule after confirming your hooks work as expected.\n# ---------------------------------------------------------------------------\nif echo \"$COMMAND\" | grep -q \"COPILOT_HOOKS_DENY_DEMO\"; then\n  deny \"Blocked demo command (test rule). Remove this rule after validating hooks.\"\nfi\n\ndeny() {\n  local reason=\"$1\"\n\n  # Redact sensitive patterns from command before logging.\n  local redacted_cmd=\"$(echo \"$COMMAND\" | \\\n    sed -E 's/ghp_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n    sed -E 's/gho_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n    sed -E 's/ghu_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n    sed -E 's/ghs_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \\\n    sed -E 's/Bearer [A-Za-z0-9_\\-\\.]+/Bearer [REDACTED]/g' | \\\n    sed -E 's/--password[= ][^ ]+/--password=[REDACTED]/g' | \\\n    sed -E 's/--token[= ][^ ]+/--token=[REDACTED]/g')\"\n\n  # Log the denial decision with redacted command.\n  jq -n \\\n    --arg cmd \"$redacted_cmd\" \\\n    --arg r \"$reason\" \\\n    '{event:\"policyDeny\", toolName:\"bash\", command:$cmd, reason:$r}' \\\n    >> \"$LOG_DIR/audit.jsonl\"\n\n  # Return a denial response.\n  jq -n \\\n    --arg r \"$reason\" \\\n    '{permissionDecision:\"deny\", permissionDecisionReason:$r}'\n\n  exit 0\n}\n\n# Privilege escalation\nif echo \"$COMMAND\" | grep -qE '\\b(sudo|su|runas)\\b'; then\n  deny \"Privilege escalation requires manual approval.\"\nfi\n\n# Destructive filesystem operations targeting root\nif echo \"$COMMAND\" | grep -qE 'rm\\s+-rf\\s*/($|\\s)|rm\\s+.*-rf\\s*/($|\\s)'; then\n  deny \"Destructive operations targeting the filesystem root require manual approval.\"\nfi\n\n# System-level destructive operations\nif echo \"$COMMAND\" | grep -qE '\\b(mkfs|dd|format)\\b'; then\n  deny \"System-level destructive operations are not allowed via automated execution.\"\nfi\n\n# Download-and-execute patterns\nif echo \"$COMMAND\" | grep -qE 'curl.*\\|\\s*(bash|sh)|wget.*\\|\\s*(bash|sh)'; then\n  deny \"Download-and-execute patterns require manual approval.\"\nfi\n\n# Allow by default\nexit 0\n```\n\n#### Создайте скрипт политики (PowerShell)\n\nСоздать `.github/hooks/scripts/pre-tool-policy.ps1`:\n\n```powershell copy\n$ErrorActionPreference = \"Stop\"\n\n$inputObj = [Console]::In.ReadToEnd() | ConvertFrom-Json\n$toolName = $inputObj.toolName\n$toolArgsRaw = $inputObj.toolArgs  # JSON string\n\n$logDir = \".github/hooks/logs\"\nif (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }\n\n# Example redaction logic.\n# GitHub does not currently provide built-in secret redaction for hooks.\n# This example shows one possible approach; many organizations prefer to\n# forward events to a centralized logging system that handles redaction.\n# Redact sensitive patterns before logging.\n# Adjust these patterns to match your organization's needs.\n$redactedToolArgs = $toolArgsRaw `\n  -replace 'ghp_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n  -replace 'gho_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n  -replace 'ghu_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n  -replace 'ghs_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n  -replace 'Bearer [A-Za-z0-9_\\-\\.]+', 'Bearer [REDACTED]' `\n  -replace '--password[= ][^ ]+', '--password=[REDACTED]' `\n  -replace '--token[= ][^ ]+', '--token=[REDACTED]'\n\n# Log attempted tool use with redacted toolArgs.\n(@{\n  event    = \"preToolUse\"\n  toolName = $toolName\n  toolArgs = $redactedToolArgs\n} | ConvertTo-Json -Compress) | Add-Content -Path \"$logDir/audit.jsonl\"\n\nif ($toolName -ne \"bash\") { exit 0 }\n\n# Parse toolArgs JSON string.\n$toolArgs = $null\ntry { $toolArgs = $toolArgsRaw | ConvertFrom-Json } catch { exit 0 }\n\n$command = $toolArgs.command\n\n# ---------------------------------------------------------------------------\n# Demo-only deny rule for safe testing.\n# This blocks a harmless test command so you can validate the deny flow.\n# Remove this rule after confirming your hooks work as expected.\n# ---------------------------------------------------------------------------\nif ($command -match 'COPILOT_HOOKS_DENY_DEMO') {\n  Deny \"Blocked demo command (test rule). Remove this rule after validating hooks.\"\n}\n\nfunction Deny([string]$reason) {\n  # Redact sensitive patterns from command before logging.\n  $redactedCommand = $command `\n    -replace 'ghp_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n    -replace 'gho_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n    -replace 'ghu_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n    -replace 'ghs_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `\n    -replace 'Bearer [A-Za-z0-9_\\-\\.]+', 'Bearer [REDACTED]' `\n    -replace '--password[= ][^ ]+', '--password=[REDACTED]' `\n    -replace '--token[= ][^ ]+', '--token=[REDACTED]'\n\n  # Log the denial decision with redacted command.\n  (@{\n    event    = \"policyDeny\"\n    toolName = \"bash\"\n    command  = $redactedCommand\n    reason   = $reason\n  } | ConvertTo-Json -Compress) | Add-Content -Path \"$logDir/audit.jsonl\"\n\n  (@{\n    permissionDecision = \"deny\"\n    permissionDecisionReason = $reason\n  } | ConvertTo-Json -Compress)\n\n  exit 0\n}\n\nif ($command -match '\\b(sudo|su|runas)\\b') { Deny \"Privilege escalation requires manual approval.\" }\nif ($command -match 'rm\\s+-rf\\s*/(\\s|$)|rm\\s+.*-rf\\s*/(\\s|$)') { Deny \"Destructive operations targeting the filesystem root require manual approval.\" }\nif ($command -match '\\b(mkfs|dd|format)\\b') { Deny \"System-level destructive operations are not allowed via automated execution.\" }\nif ($command -match 'curl.*\\|\\s*(bash|sh)|wget.*\\|\\s*(bash|sh)') { Deny \"Download-and-execute patterns require manual approval.\" }\n\nexit 0\n```\n\n### Протестируйте скрипт политики\n\nВы можете протестировать скрипты, передавая примерные `preToolUse` входы.\n\nДопустим пример:\n\n```bash\necho '{\"toolName\":\"bash\",\"toolArgs\":\"{\\\"command\\\":\\\"git status\\\"}\"}' \\\n  | .github/hooks/scripts/pre-tool-policy.sh\n# or, for PowerShell\necho '{\"toolName\":\"bash\",\"toolArgs\":\"{\\\"command\\\":\\\"git status\\\"}\"}' |\n  .github/hooks/scripts/pre-tool-policy.ps1\n```\n\nПример отклонения:\n\n```bash\necho '{\"toolName\":\"bash\",\"toolArgs\":\"{\\\"command\\\":\\\"sudo rm -rf /\\\"}\"}' \\\n  | .github/hooks/scripts/pre-tool-policy.sh\n# or, for PowerShell\necho '{\"toolName\":\"bash\",\"toolArgs\":\"{\\\"command\\\":\\\"sudo rm -rf /\\\"}\"}' |\n  .github/hooks/scripts/pre-tool-policy.ps1\n```\n\nПосле запуска примера с отказом проверьте `.github/hooks/logs/audit.jsonl` для новой записи в журнале отказа.\n\n```json\n{\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"Privilege escalation requires manual approval.\"}\n```\n\nНа этом этапе команды высокого риска `bash` блокируются от автоматического выполнения в этом репозитории.\n\n## 6. Тестирование сквозь конец в репозитории\n\nПосле создания конфигурационного файла и скриптов убедитесь, что хуки работают как ожидается при использовании Второй пилот CLI в этом репозитории.\n\n### Проверьте конфигурационный файл крючка\n\nПроверьте, что ваш файл конфигурации крюка является действительным JSON:\n\n```bash copy\njq '.' < .github/hooks/copilot-cli-policy.json\n```\n\n### Проверка разрешений скриптов (системы на базе Unix)\n\nНа macOS и Linux убедитесь, что ваши Bash-скрипты исполняемы:\n\n```bash copy\nchmod +x .github/hooks/scripts/*.sh\n```\n\n### Проведите базовую сессию\n\nНачните новую Второй пилот CLI сессию в репозитории:\n\n```bash copy\ncopilot -p \"Show me the status of this repository\"\n```\n\nОжидаемые результаты:\n\n* Вы видите баннер политики (от `sessionStart`).\n* Добавлена новая запись в `.github/hooks/logs/audit.jsonl` (с `userPromptSubmitted`).\n\n### Использование инструмента и проверка логирования\n\nЗапустите запрос, который заставляет Второй пилот CLI использовать инструмент (например, bash):\n\n```bash copy\ncopilot -p \"Show me the last 5 git commits\"\n```\n\nОжидаемые результаты:\n\n* В `preToolUse` добавляется запись `.github/hooks/logs/audit.jsonl`.\n* Если вызов инструмента разрешен, выполнение происходит нормально.\n\n### Проверьте отклонённую команду\n\nПримерный скрипт политики включает временное правило демонстрации, блокирующее команды, содержащие строку `COPILOT_HOOKS_DENY_DEMO`. Это позволяет безопасно проверить поток запрета без выполнения разрушительных команд.\n\nЗапустите подсказку, которая вызовет отклонённую команду:\n\n```bash copy\ncopilot -p \"Run a test command: echo COPILOT_HOOKS_DENY_DEMO\"\n```\n\nОжидаемые результаты:\n\n* Второй пилот CLI не выполняет команду.\n* Ваш крючок отвечает отказом с чёткой причиной.\n* Запись `policyDeny` записывается на `.github/hooks/logs/audit.jsonl`.\n\nУбедившись, что поток отказов работает корректно, удалите правило демонстрации из скрипта и замените его шаблонами отказа, отражающими политику вашей организации.\n\n### Проверьте свои журналы аудита\n\nЧтобы посмотреть последние записи:\n\n```bash copy\ntail -n 50 .github/hooks/logs/audit.jsonl\n```\n\nФильтровать только отклонённые решения:\n\n```bash copy\njq 'select(.event==\"policyDeny\")' .github/hooks/logs/audit.jsonl\n```\n\n## 7. Безопасно распределяйтесь между командами\n\nПосле проверки ваших крючков в одном репозитории внедряйте их постепенно, чтобы не мешать рабочим процессам разработки.\n\n### Выберите стратегию внедрения\n\nРаспространённые подходы к внедрению включают:\n\n* **Внедрение с первым входом (рекомендуется**): начните с регистрации запросов и использования инструмента, не запрещая выполнение. Просмотрите журналы в течение определённого времени, а затем введите правила отказа, когда поймёте распространённые шаблоны использования.\n* **Развертывание по командам**: развертывайте крючки для одной команды или репозитория за раз, собирайте отзывы, а затем расширяйте на дополнительные команды.\n* **Внедрение, основанное на рисках**: Начните с репозиториев, работающих с чувствительными системами или производственной инфраструктурой, затем расширяйтесь на репозитории с низким риском.\n\n### Сообщайте о ожиданиях\n\nПрежде чем применять правила отказа, убедитесь, что разработчики понимают:\n\n* Что крючки активны в репозитории\n* Какие типы команд могут быть заблокированы\n* Как действовать, если приказ отклонён\n\nЧёткая коммуникация снижает путаницу и запросы в поддержку.\n\n### Поддерживайте политики\n\nПо мере развития использования:\n\n* Храните конфигурацию крючка и скрипты в контроле версий.\n* Периодически проверяйте журналы аудита для выявления новых закономерностей риска.\n* Обновляйте правила запрета постепенно, а не добавляйте широкие совпадения.\n* Задокументируйте, почему существует каждое правило отказа, особенно для ограничений с высоким воздействием.\n\n### Аккуратно обращайтесь с исключениями\n\nНекоторые команды (например, инфраструктурные или платформенные команды) могут требовать более широких разрешений. Чтобы справиться с этим безопасно:\n\n* Поддерживайте отдельные конфигурации крючков для разных репозиториев.\n* Держите исключения узкими и хорошо задокументированными.\n* Избегайте случайных локальных обходов, которые подрывают аудитируемость.\n\n## Дополнительные материалы\n\nДля устранения неисправностей см. [Настраивайте рабочие процессы агента с помощью крючков](/ru/copilot/how-tos/use-copilot-agents/cloud-agent/use-hooks#troubleshooting)."}