Skip to main content

Verwenden von Hooks mit Copilot CLI für vorhersehbare, richtlinienkonforme Ausführung

Verwenden Sie Hooks, um Benutzeraufforderungen zu protokollieren und zu steuern, welche Tools Copilot-CLI in einem Repository ausgeführt werden können, damit Teams die Sicherheits- und Complianceanforderungen Ihrer Organisation sicher automatisieren können.

Dieses Lernprogramm richtet sich an DevOps-Ingenieure, Plattformteams und technische Führungskräfte, die Entwickler mit Copilot-CLI unterstützen.

Hooks sind benutzerdefinierte Skripte, die während einer Copilot-CLI Sitzung an bestimmten Stellen ausgeführt werden. Sie können Eingabeaufforderungen und Toolaufrufe prüfen, Informationen zur Überwachung protokollieren und sogar die Ausführung bestimmter Befehle blockieren.

Sie konfigurieren Repository-spezifische Hooks, die:

  • Bieten Sie Einblicke in Eingabeaufforderungen und die Verwendung von Tools.
  • Blockieren Von Befehlsmustern mit hohem Risiko vor der Ausführung.
  • Helfen Sie Entwicklern, Organisationsrichtlinien mit klaren Nachrichten zu verstehen.

Voraussetzungen

  • Vertrautheit mit Shellskripting (Bash oder PowerShell)
  • Grundlegendes Verständnis von JSON-Konfigurationsdateien
  • Zugriff auf ein Repository, in dem Copilot-CLI verwendet wird
  •         `jq` installiert (für die Bash-Beispiele)
    

1. Definieren einer Organisationsrichtlinie

Bevor Sie Hook-Skripts schreiben, entscheiden Sie, welche Aktionen automatisch zugelassen werden sollen und welche eine menschliche Überprüfung erfordern sollten.

Eine klare Richtlinie hilft Ihnen, die Übersperrung zu vermeiden und gleichzeitig das Risiko zu verringern.

Identifizieren von Befehlen, für die immer eine Überprüfung erforderlich ist

Beginnen Sie mit der Identifizierung von Mustern, die niemals von {data variables.copilot.copilot_cli_short} automatisch ausgeführt werden sollen. Häufige Beispiele sind:

  •         **Berechtigungseskalation**: `sudo`, `su``runas`
    
  •         **Destruktive Systemvorgänge**: `rm -rf /`, `mkfs`, `dd``format`
    
  •         **Download- und Ausführungsmuster**: `curl ... | bash`, `wget ... | sh`, PowerShell `iex (irm ...)`
    

Diese Befehle können unwiderrufliche Auswirkungen haben, wenn sie unbeabsichtigt ausgeführt werden.

Entscheiden, was protokolliert werden soll

Wenn Sie Hooks verwenden, können Sie Informationen darüber erfassen, wie Copilot-CLI in einem Repository verwendet wird, einschließlich Aufforderungen, die von Benutzern und Tools übermittelt werden, die Copilot-CLI versucht auszuführen.

Mindestens protokollieren die meisten Organisationen:

  • Der Zeitstempel und der Repository-Pfad
  • Der Text der Eingabeaufforderung (oder in redigierter Form)
  • Der Toolname und die Toolargumente
  • Jede Richtlinienentscheidung (z. B. ein verweigerter Befehl und sein Grund)

Vermeiden Sie die Protokollierung geheimer Schlüssel oder Anmeldeinformationen. Wenn Eingabeaufforderungen oder Befehle möglicherweise vertrauliche Daten enthalten, entfernen Sie diese Informationen, bevor Sie Protokolle schreiben.

In diesem Lernprogramm wird ein lokales .github/hooks/logs Verzeichnis als einfaches, illustratives Beispiel verwendet. Diese Protokolldateien sind nicht für das Repository vorgesehen und befinden sich in der Regel nur auf dem Computer eines Entwicklers.

In Produktionsumgebungen leiten viele Organisationen Hook-Ereignisse an ein zentralisiertes Protokollierungs- oder Observability-System weiter, anstatt Protokolle lokal zu schreiben. Auf diese Weise können Teams konsistente Redaction, Zugriffssteuerungen, Aufbewahrungsrichtlinien und Überwachungen für Repositorys und Benutzer anwenden.

Abstimmung mit Interessengruppen

Bevor Sie Richtlinien erzwingen, überprüfen Sie sie mit:

  • Sicherheits- oder Complianceteams, um Risikogrenzen zu bestätigen
  • Plattform- oder Infrastrukturteams, die möglicherweise umfassendere Berechtigungen benötigen
  • Entwicklungsteams, damit sie verstehen, was blockiert wird und warum

Klare Erwartungen machen die Durchsetzung von Richtlinien einfacher zu übernehmen und aufrechtzuerhalten.

2. Einrichten von Repository-Hookdateien

In diesem Lernprogramm verwenden Sie Repository-bezogene Hooks, die im Repository unter .github/hooks/ gespeichert sind. Diese Hooks gelten immer, wenn Copilot-CLI innerhalb dieses Repositories ausgeführt wird.

Hinweis

Copilot Agents laden Hook-Konfigurationsdateien aus dem .github/hooks/*.json Repository. Hooks werden synchron ausgeführt und können die Ausführung blockieren.

Erstellen der Verzeichnisstruktur

Erstellen Sie im Repositorystamm Verzeichnisse für Ihre Hook-Konfiguration, Skripts und Protokolle:

Bash
mkdir -p .github/hooks/scripts
mkdir -p .github/hooks/logs

Fügen Sie .github/hooks/logs/ zu gitignore hinzu, damit lokale Überwachungsprotokolle nicht zugesichert werden:

Bash
echo ".github/hooks/logs/" >> .gitignore

In diesem Lernprogramm wird die folgende Struktur verwendet:

.github/
└── hooks/
    ├── copilot-cli-policy.json
    ├── logs/
    │   └── audit.jsonl
    └── scripts/
        ├── session-banner.sh
        ├── session-banner.ps1
        ├── log-prompt.sh
        ├── log-prompt.ps1
        ├── pre-tool-policy.sh
        └── pre-tool-policy.ps1

Erstellen einer Hook-Konfigurationsdatei

Erstellen Sie eine Hook-Konfigurationsdatei unter .github/hooks/copilot-cli-policy.json.

Diese Datei definiert, welche Hooks ausgeführt werden, wann sie ausgeführt werden und welche Skripts ausgeführt werden.

JSON
{
  "version": 1,
  "hooks": {
    "sessionStart": [
      {
        "type": "command",
        "bash": "./scripts/session-banner.sh",
        "powershell": "./scripts/session-banner.ps1",
        "cwd": ".github/hooks",
        "timeoutSec": 10
      }
    ],
    "userPromptSubmitted": [
      {
        "type": "command",
        "bash": "./scripts/log-prompt.sh",
        "powershell": "./scripts/log-prompt.ps1",
        "cwd": ".github/hooks",
        "timeoutSec": 10
      }
    ],
    "preToolUse": [
      {
        "type": "command",
        "bash": "./scripts/pre-tool-policy.sh",
        "powershell": "./scripts/pre-tool-policy.ps1",
        "cwd": ".github/hooks",
        "timeoutSec": 15
      }
    ]
  }
}

Grundlegendes zur Funktionsweise dieser Konfiguration

Diese Konfiguration richtet drei Hooks ein:

  •         `sessionStart`: Zeigt eine Informationsmeldung an, wenn eine neue Agentsitzung gestartet oder fortgesetzt wird.
    
  •         `userPromptSubmitted`: Wird ausgeführt, wenn ein Benutzer eine Eingabeaufforderung sendet.
    
  •         `preToolUse`: Wird ausgeführt, bevor ein Tool ausgeführt wird und die Ausführung explizit zulassen oder verweigern kann.
    

Commit und Freigeben der Hook-Konfiguration

Wenn Sie bereit sind, die Hook-Konfiguration für Mitarbeiter freizugeben (z. B. über eine Pullanforderung oder in einem Test-Repository), übernehmen Sie die Hook-Konfiguration und Skripts. Übergeben Sie keine lokalen Audit-Logs.

Bash
git add .github/hooks/copilot-cli-policy.json .github/hooks/scripts
git commit -m "Add Copilot CLI hook configuration"
git push

Zu diesem Zeitpunkt können Copilot-CLI Ihre Hookkonfiguration ermitteln, obwohl Sie die Hook-Skripts noch nicht erstellt haben.

3. Hinzufügen eines Richtlinienbanners beim Start der Sitzung

Verwenden Sie einen sessionStart Hook, um ein Banner anzuzeigen, wann immer eine neue Copilot-CLI Sitzung gestartet oder fortgesetzt wird. Dadurch wird Entwicklern klar, dass Organisationsrichtlinien aktiv sind.

Der sessionStart Hook empfängt kontextbezogene Informationen wie das aktuelle Arbeitsverzeichnis und die erste Eingabeaufforderung. Jede Ausgabe dieses Hooks wird von Copilot-CLI ignoriert, wodurch sie für Informationsnachrichten geeignet ist.

Erstellen des Sitzungsbannerskripts (Bash)

Erstellen:.github/hooks/scripts/session-banner.sh

Bash
#!/bin/bash
set -euo pipefail

cat << 'EOF'
COPILOT CLI POLICY ACTIVE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Prompts and tool use may be logged for auditing
• High-risk commands may be blocked automatically
• If something is blocked, follow the guidance shown
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
EOF
exit 0

Erstellen des Sitzungsbannerskripts (PowerShell)

Erstellen:.github/hooks/scripts/session-banner.ps1

PowerShell
$ErrorActionPreference = "Stop"

Write-Host @"
COPILOT CLI POLICY ACTIVE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• Prompts and tool use may be logged for auditing
• High-risk commands may be blocked automatically
• If something is blocked, follow the guidance shown
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
"@
exit 0

Testen des Sitzungsbanners

Sie können die Bannerskripts direkt testen:

.github/hooks/scripts/session-banner.sh
# or, for PowerShell
.github/hooks/scripts/session-banner.ps1

Wenn Sie eines der Skripts ausführen, sollte das Richtlinienbanner in Ihrem Terminal angezeigt werden.

4. Protokollieren von Aufforderungen zur Prüfung

Verwenden Sie den userPromptSubmitted Hook, um aufzuzeichnen, wenn Benutzer Aufforderungen an Copilot-CLI senden. Dieser Hook wird immer ausgeführt, wenn eine Eingabeaufforderung gesendet wird, bevor tools aufgerufen werden.

Der Hook empfängt strukturierte JSON-Eingaben, die den Zeitstempel, das aktuelle Arbeitsverzeichnis und den vollständigen Eingabeaufforderungstext enthalten. Die Ausgabe dieses Hooks wird ignoriert.

Wichtig

Eingabeaufforderungen können vertrauliche Informationen enthalten. Wenden Sie Redaction an, und befolgen Sie die Datenverarbeitungs- und Aufbewahrungsrichtlinien Ihrer Organisation beim Protokollieren dieser Daten.

Skript zur Prompt-Protokollierung erstellen (Bash)

Erstellen:.github/hooks/scripts/log-prompt.sh

Bash
#!/bin/bash
set -euo pipefail

INPUT="$(cat)"

TIMESTAMP_MS="$(echo "$INPUT" | jq -r '.timestamp // empty')"
CWD="$(echo "$INPUT" | jq -r '.cwd // empty')"

# This example logs only metadata, not the full prompt, to avoid storing
# potentially sensitive data. Adjust to match your organization’s needs.
LOG_DIR=".github/hooks/logs"
mkdir -p "$LOG_DIR"
chmod 700 "$LOG_DIR"

jq -n \
  --arg ts "$TIMESTAMP_MS" \
  --arg cwd "$CWD" \
  '{event:"userPromptSubmitted", timestampMs:$ts, cwd:$cwd}' \
  >> "$LOG_DIR/audit.jsonl"

exit 0

Erstellen Sie das Skript zur Protokollierung der Eingabeaufforderung (PowerShell)

Erstellen:.github/hooks/scripts/log-prompt.ps1

PowerShell
$ErrorActionPreference = "Stop"

$inputObj = [Console]::In.ReadToEnd() | ConvertFrom-Json

$timestampMs = $inputObj.timestamp
$cwd = $inputObj.cwd
$prompt = $inputObj.prompt

# Optional example redaction. Adjust to match your organization’s needs.
$redactedPrompt = $prompt -replace 'ghp_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]'

$logDir = ".github/hooks/logs"
if (-not (Test-Path $logDir)) {
  New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}

$logEntry = @{
  event       = "userPromptSubmitted"
  timestampMs = $timestampMs
  cwd         = $cwd
  prompt      = $redactedPrompt
} | ConvertTo-Json -Compress

Add-Content -Path "$logDir/audit.jsonl" -Value $logEntry
exit 0

Das Skript zur Protokollierung von Prompts testen

Sie können die Skripte direkt testen, indem Sie Beispiel-Eingaben über eine Pipeline verwenden.

echo '{"timestamp":1704614500000,"cwd":"/repo","prompt":"List all branches"}' \
  | .github/hooks/scripts/log-prompt.sh
# or, for PowerShell
echo '{"timestamp":1704614500000,"cwd":"/repo","prompt":"List all branches"}' |
  .github/hooks/scripts/log-prompt.ps1

Überprüfen Sie .github/hooks/logs/audit.jsonl nach dem Ausführen des Skripts nach einem neuen Protokolleintrag.

Bash
cat .github/hooks/logs/audit.jsonl

An dieser Stelle werden Aufforderungen, die an Copilot-CLI in diesem Repository übermittelt werden, zur Überwachung aufgezeichnet.

5. Richtlinien erzwingen mit preToolUse

Verwenden Sie den preToolUse Hook, um einen Toolaufruf auszuwerten, bevor er ausgeführt wird. Dieser Hook kann die Ausführung erlauben (indem nichts unternommen wird) oder die Ausführung verweigern (durch Zurückgeben einer strukturierten Antwort).

Verstehen Sie die preToolUse Eingabe

Die preToolUse Hookeingabe umfasst:

  •         `toolName`: Das Tool, das Copilot-CLI ausführt (z. B `bash`. )
    
  •         `toolArgs`: Eine **JSON-Zeichenfolge** , die die Argumente dieses Tools enthält
    

Da toolArgs eine JSON-Zeichenfolge ist, muss Ihr Skript sie parsen, bevor es Felder wie command liest.

Wichtig

Toolargumente und -befehle können vertrauliche Informationen wie API-Token, Kennwörter oder andere Anmeldeinformationen enthalten. Wenden Sie Schwärzung an, bevor Sie diese Daten protokollieren, und befolgen Sie die Sicherheitsrichtlinien Ihrer Organisation. Erwägen Sie die Protokollierung nur nicht vertraulicher Metadaten (Toolname, Zeitstempel, Richtlinienentscheidung) und das Weiterleiten von Überwachungsereignissen an ein gesichertes, zentralisiertes Protokollierungssystem mit entsprechenden Zugriffssteuerungen und Aufbewahrungsrichtlinien.

Erstellen des Richtlinienskripts

Erstellen Sie als Nächstes ein Richtlinienskript. Dieses Beispiel:

  • Protokolliert alle versuchten Toolverwendungen.
  • Wendet Verweigerungsregeln nur auf Bash-Befehle an.
  • Blockiert Hochrisikomuster wie Berechtigungseskalation, destruktive Vorgänge und Download- und Ausführungsbefehle.

Damit Sie den Verweigerungsfluss sicher überprüfen können, enthält das Skript auch eine temporäre Demoregel, die einen harmlosen Testbefehl blockiert. Nachdem Sie bestätigt haben, dass Hooks wie erwartet funktionieren, entfernen Sie die Demoregel, und ersetzen Sie sie durch Muster, die die Richtlinien Ihrer Organisation widerspiegeln.

Beispielskript (Bash)

Erstellen:.github/hooks/scripts/pre-tool-policy.sh

Bash
#!/bin/bash
set -euo pipefail

INPUT="$(cat)"

TOOL_NAME="$(echo "$INPUT" | jq -r '.toolName // empty')"
TOOL_ARGS_RAW="$(echo "$INPUT" | jq -r '.toolArgs // empty')"  # JSON string

LOG_DIR=".github/hooks/logs"
mkdir -p "$LOG_DIR"

# Example redaction logic.
# GitHub does not currently provide built-in secret redaction for hooks.
# This example shows one possible approach; many organizations prefer to
# forward events to a centralized logging system that handles redaction.
# Redact sensitive patterns before logging.
# Adjust these patterns to match your organization's needs.
REDACTED_TOOL_ARGS="$(echo "$TOOL_ARGS_RAW" | \
  sed -E 's/ghp_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
  sed -E 's/gho_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
  sed -E 's/ghu_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
  sed -E 's/ghs_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
  sed -E 's/Bearer [A-Za-z0-9_\-\.]+/Bearer [REDACTED]/g' | \
  sed -E 's/--password[= ][^ ]+/--password=[REDACTED]/g' | \
  sed -E 's/--token[= ][^ ]+/--token=[REDACTED]/g')"

# Log attempted tool use with redacted toolArgs.
jq -n \
  --arg tool "$TOOL_NAME" \
  --arg toolArgs "$REDACTED_TOOL_ARGS" \
  '{event:"preToolUse", toolName:$tool, toolArgs:$toolArgs}' \
  >> "$LOG_DIR/audit.jsonl"

# Only enforce command rules for bash.
if [ "$TOOL_NAME" != "bash" ]; then
  exit 0
fi

# Parse toolArgs JSON string.
# If toolArgs isn't valid JSON for some reason, allow (and rely on logs).
if ! echo "$TOOL_ARGS_RAW" | jq -e . >/dev/null 2>&1; then
  exit 0
fi

COMMAND="$(echo "$TOOL_ARGS_RAW" | jq -r '.command // empty')"

# ---------------------------------------------------------------------------
# Demo-only deny rule for safe testing.
# This blocks a harmless test command so you can validate the deny flow.
# Remove this rule after confirming your hooks work as expected.
# ---------------------------------------------------------------------------
if echo "$COMMAND" | grep -q "COPILOT_HOOKS_DENY_DEMO"; then
  deny "Blocked demo command (test rule). Remove this rule after validating hooks."
fi

deny() {
  local reason="$1"

  # Redact sensitive patterns from command before logging.
  local redacted_cmd="$(echo "$COMMAND" | \
    sed -E 's/ghp_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
    sed -E 's/gho_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
    sed -E 's/ghu_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
    sed -E 's/ghs_[A-Za-z0-9]{20,}/[REDACTED_TOKEN]/g' | \
    sed -E 's/Bearer [A-Za-z0-9_\-\.]+/Bearer [REDACTED]/g' | \
    sed -E 's/--password[= ][^ ]+/--password=[REDACTED]/g' | \
    sed -E 's/--token[= ][^ ]+/--token=[REDACTED]/g')"

  # Log the denial decision with redacted command.
  jq -n \
    --arg cmd "$redacted_cmd" \
    --arg r "$reason" \
    '{event:"policyDeny", toolName:"bash", command:$cmd, reason:$r}' \
    >> "$LOG_DIR/audit.jsonl"

  # Return a denial response.
  jq -n \
    --arg r "$reason" \
    '{permissionDecision:"deny", permissionDecisionReason:$r}'

  exit 0
}

# Privilege escalation
if echo "$COMMAND" | grep -qE '\b(sudo|su|runas)\b'; then
  deny "Privilege escalation requires manual approval."
fi

# Destructive filesystem operations targeting root
if echo "$COMMAND" | grep -qE 'rm\s+-rf\s*/($|\s)|rm\s+.*-rf\s*/($|\s)'; then
  deny "Destructive operations targeting the filesystem root require manual approval."
fi

# System-level destructive operations
if echo "$COMMAND" | grep -qE '\b(mkfs|dd|format)\b'; then
  deny "System-level destructive operations are not allowed via automated execution."
fi

# Download-and-execute patterns
if echo "$COMMAND" | grep -qE 'curl.*\|\s*(bash|sh)|wget.*\|\s*(bash|sh)'; then
  deny "Download-and-execute patterns require manual approval."
fi

# Allow by default
exit 0

Erstellen des Richtlinienskripts (PowerShell)

Erstellen: .github/hooks/scripts/pre-tool-policy.ps1

PowerShell
$ErrorActionPreference = "Stop"

$inputObj = [Console]::In.ReadToEnd() | ConvertFrom-Json
$toolName = $inputObj.toolName
$toolArgsRaw = $inputObj.toolArgs  # JSON string

$logDir = ".github/hooks/logs"
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }

# Example redaction logic.
# GitHub does not currently provide built-in secret redaction for hooks.
# This example shows one possible approach; many organizations prefer to
# forward events to a centralized logging system that handles redaction.
# Redact sensitive patterns before logging.
# Adjust these patterns to match your organization's needs.
$redactedToolArgs = $toolArgsRaw `
  -replace 'ghp_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
  -replace 'gho_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
  -replace 'ghu_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
  -replace 'ghs_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
  -replace 'Bearer [A-Za-z0-9_\-\.]+', 'Bearer [REDACTED]' `
  -replace '--password[= ][^ ]+', '--password=[REDACTED]' `
  -replace '--token[= ][^ ]+', '--token=[REDACTED]'

# Log attempted tool use with redacted toolArgs.
(@{
  event    = "preToolUse"
  toolName = $toolName
  toolArgs = $redactedToolArgs
} | ConvertTo-Json -Compress) | Add-Content -Path "$logDir/audit.jsonl"

if ($toolName -ne "bash") { exit 0 }

# Parse toolArgs JSON string.
$toolArgs = $null
try { $toolArgs = $toolArgsRaw | ConvertFrom-Json } catch { exit 0 }

$command = $toolArgs.command

# ---------------------------------------------------------------------------
# Demo-only deny rule for safe testing.
# This blocks a harmless test command so you can validate the deny flow.
# Remove this rule after confirming your hooks work as expected.
# ---------------------------------------------------------------------------
if ($command -match 'COPILOT_HOOKS_DENY_DEMO') {
  Deny "Blocked demo command (test rule). Remove this rule after validating hooks."
}

function Deny([string]$reason) {
  # Redact sensitive patterns from command before logging.
  $redactedCommand = $command `
    -replace 'ghp_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
    -replace 'gho_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
    -replace 'ghu_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
    -replace 'ghs_[A-Za-z0-9]{20,}', '[REDACTED_TOKEN]' `
    -replace 'Bearer [A-Za-z0-9_\-\.]+', 'Bearer [REDACTED]' `
    -replace '--password[= ][^ ]+', '--password=[REDACTED]' `
    -replace '--token[= ][^ ]+', '--token=[REDACTED]'

  # Log the denial decision with redacted command.
  (@{
    event    = "policyDeny"
    toolName = "bash"
    command  = $redactedCommand
    reason   = $reason
  } | ConvertTo-Json -Compress) | Add-Content -Path "$logDir/audit.jsonl"

  (@{
    permissionDecision = "deny"
    permissionDecisionReason = $reason
  } | ConvertTo-Json -Compress)

  exit 0
}

if ($command -match '\b(sudo|su|runas)\b') { Deny "Privilege escalation requires manual approval." }
if ($command -match 'rm\s+-rf\s*/(\s|$)|rm\s+.*-rf\s*/(\s|$)') { Deny "Destructive operations targeting the filesystem root require manual approval." }
if ($command -match '\b(mkfs|dd|format)\b') { Deny "System-level destructive operations are not allowed via automated execution." }
if ($command -match 'curl.*\|\s*(bash|sh)|wget.*\|\s*(bash|sh)') { Deny "Download-and-execute patterns require manual approval." }

exit 0

Testen des Richtlinienskripts

Sie können die Skripts testen, indem Sie Beispiel-Eingaben über eine Pipe preToolUse eingeben.

Beispiel zulassen:

echo '{"toolName":"bash","toolArgs":"{\"command\":\"git status\"}"}' \
  | .github/hooks/scripts/pre-tool-policy.sh
# or, for PowerShell
echo '{"toolName":"bash","toolArgs":"{\"command\":\"git status\"}"}' |
  .github/hooks/scripts/pre-tool-policy.ps1

Beispiel für Ablehnung:

echo '{"toolName":"bash","toolArgs":"{\"command\":\"sudo rm -rf /\"}"}' \
  | .github/hooks/scripts/pre-tool-policy.sh
# or, for PowerShell
echo '{"toolName":"bash","toolArgs":"{\"command\":\"sudo rm -rf /\"}"}' |
  .github/hooks/scripts/pre-tool-policy.ps1

Überprüfen Sie .github/hooks/logs/audit.jsonl nach dem Ausführen des Ablehnungsbeispiels auf einen neuen Denialprotokolleintrag.

{"permissionDecision":"deny","permissionDecisionReason":"Privilege escalation requires manual approval."}

An diesem Punkt werden Hochrisikobefehle bash von der automatischen Ausführung in diesem Repository blockiert.

6. Durchführung eines End-to-End-Tests im gesamten Repository

Nachdem Sie die Konfigurationsdatei und Skripts erstellt haben, überprüfen Sie, ob Hooks wie erwartet ausgeführt werden, wenn Sie Copilot-CLI in diesem Repository verwenden.

Überprüfen der Hook-Konfigurationsdatei

Überprüfen Sie, ob die Hook-Konfigurationsdatei eine gültige JSON-Datei ist:

Bash
jq '.' < .github/hooks/copilot-cli-policy.json

Überprüfen von Skriptberechtigungen (Unix-basierte Systeme)

Vergewissern Sie sich unter macOS und Linux, dass Ihre Bash-Skripts ausführbar sind:

Bash
chmod +x .github/hooks/scripts/*.sh

Ausführen einer einfachen Sitzung

Starten Sie eine neue Copilot-CLI-Sitzung im Repository:

Bash
copilot -p "Show me the status of this repository"

Erwartete Ergebnisse:

  • Sie sehen das Richtlinienbanner (von sessionStart).
  • Ein neuer Eintrag wird zu .github/hooks/logs/audit.jsonl (von userPromptSubmitted) hinzugefügt.

Trigger-Tool verwenden und Protokollierung überprüfen

Führen Sie einen Prompt aus, der bewirkt, dass Copilot-CLI ein Tool verwendet (z. B. bash):

Bash
copilot -p "Show me the last 5 git commits"

Erwartete Ergebnisse:

  • Ein preToolUse Eintrag wird zu .github/hooks/logs/audit.jsonl hinzugefügt.
  • Wenn der Toolaufruf zulässig ist, wird die Ausführung normal fortgesetzt.

Testen eines verweigerten Befehls

Das Beispielrichtlinienskript enthält eine temporäre Demoregel, die Befehle blockiert, die die Zeichenfolge COPILOT_HOOKS_DENY_DEMOenthalten. Auf diese Weise können Sie den Verweigerungsfluss sicher überprüfen, ohne destruktive Befehle auszuführen.

Führen Sie eine Eingabeaufforderung aus, die einen verweigerten Befehl auslöst:

Bash
copilot -p "Run a test command: echo COPILOT_HOOKS_DENY_DEMO"

Erwartete Ergebnisse:

  • Copilot-CLI führt den Befehl nicht aus.
  • Ihr Hook liefert eine Ablehnungsantwort mit einer klaren Begründung zurück.
  • Ein policyDeny Eintrag wird geschrieben in .github/hooks/logs/audit.jsonl.

Nachdem Sie bestätigt haben, dass der Verweigerungsfluss ordnungsgemäß funktioniert, entfernen Sie die Demoregel aus Ihrem Skript, und ersetzen Sie sie durch Verweigerungsmuster, die die Richtlinien Ihrer Organisation widerspiegeln.

Überprüfen Sie Ihre Prüfprotokolle

Um neueste Einträge anzusehen:

Bash
tail -n 50 .github/hooks/logs/audit.jsonl

So filtern Sie nur verweigerte Entscheidungen:

Bash
jq 'select(.event=="policyDeny")' .github/hooks/logs/audit.jsonl

7. Sicheres Rollout über die Teams hinweg

Nachdem Sie Ihre Hooks in einem einzigen Repository überprüft haben, führen Sie sie schrittweise aus, um Unterbrechungen von Entwicklungsworkflows zu vermeiden.

Auswählen einer Rolloutstrategie

Zu den gängigen Rolloutansätzen gehören:

  •         **Protokollierungsorientiertes Rollout (empfohlen)**: Beginnen Sie mit der Protokollierung von Prompts und der Nutzung von Tools, ohne die Ausführung zu unterbrechen. Überprüfen Sie Protokolle für einen bestimmten Zeitraum, und führen Sie dann Verweigerungsregeln ein, sobald Sie allgemeine Verwendungsmuster verstehen.
    
  •         **Team-nach-Team-Rollout**: Stellen Sie Hooks an ein Team oder Repository nacheinander bereit, sammeln Sie Feedback, und erweitern Sie dann auf weitere Teams.
    
  •         **Risikobasiertes Rollout**: Beginnen Sie mit Repositorys, die sensible Systeme oder Produktionsinfrastruktur behandeln, und erweitern Sie dann auf Repositorys mit geringerem Risiko.
    

Kommunizieren von Erwartungen

Bevor Sie Verweigerungsregeln erzwingen, sollten Sie sicherstellen, dass Entwickler Folgendes verstehen:

  • Diese Hooks sind im Repository aktiv
  • Welche Arten von Befehlen blockiert werden können
  • Vorgehensweise, wenn ein Befehl verweigert wird

Klare Kommunikation reduziert Verwirrung und Supportanfragen.

Richtlinien wartbar halten

Während sich die Nutzung weiterentwickelt:

  • Store-Hook-Konfiguration und Skripts in der Versionssteuerung.
  • Überprüfen Sie Überwachungsprotokolle regelmäßig, um neue Risikomuster zu erkennen.
  • Aktualisieren Sie Ablehnungsregeln inkrementell, anstatt breite Übereinstimmungen hinzuzufügen.
  • Dokumentieren Sie, warum jede Verweigerungsregel vorhanden ist, insbesondere für Einschränkungen mit hohem Einfluss.

Ausnahmen sorgfältig behandeln

Einige Teams (z. B. Infrastruktur- oder Plattformteams) erfordern möglicherweise umfassendere Berechtigungen. So behandeln Sie dies sicher:

  • Verwalten Sie separate Hook-Konfigurationen für verschiedene Repositorys.
  • Halten Sie Ausnahmen eng und gut dokumentiert.
  • Vermeiden Sie ad-hoc lokale Umgehungen, die die Auditierbarkeit untergraben.

Weiterführende Lektüre

Zur Problembehandlung bei Hooks siehe Verwenden von Hooks mit GitHub Copilot-Agenten.