{"meta":{"title":"About hooks","intro":"Extend and customize GitHub Copilot agent behavior by executing custom shell commands at key points during agent execution.","product":"GitHub Copilot","breadcrumbs":[{"href":"/en/copilot","title":"GitHub Copilot"},{"href":"/en/copilot/concepts","title":"Concepts"},{"href":"/en/copilot/concepts/agents","title":"Agents"},{"href":"/en/copilot/concepts/agents/cloud-agent","title":"Cloud agent"},{"href":"/en/copilot/concepts/agents/cloud-agent/about-hooks","title":"Hooks"}],"documentType":"article"},"body":"# About hooks\n\nExtend and customize GitHub Copilot agent behavior by executing custom shell commands at key points during agent execution.\n\n## About hooks\n\nHooks enable you to execute custom shell commands at strategic points in an agent's workflow, such as when an agent session starts or ends, or before and after a prompt is entered or a tool is called.\n\nHooks receive detailed information about agent actions via JSON input, enabling context-aware automation. For example, you can use hooks to:\n\n* Programmatically approve or deny tool executions.\n* Utilize built-in security features like secret scanning to prevent credential leaks.\n* Implement custom validation rules and audit logging for compliance.\n\nCopilot agents support hooks stored in JSON files in your repository at `.github/hooks/*.json`.\n\nHooks are available for use with:\n\n* Copilot cloud agent on GitHub\n* GitHub Copilot CLI in the terminal\n\n## Types of hooks\n\nThe following types of hooks are available:\n\n* **sessionStart**: Executed when a new agent session begins or when resuming an existing session. Can be used to initialize environments, log session starts for auditing, validate project state, and set up temporary resources.\n* **sessionEnd**: Executed when the agent session completes or is terminated. Can be used to cleanup temporary resources, generate and archive session reports and logs, or send notifications about session completion.\n* **userPromptSubmitted**: Executed when the user submits a prompt to the agent. Can be used to log user requests for auditing and usage analysis.\n* **preToolUse**: Executed before the agent uses any tool (such as `bash`, `edit`, `view`). This is the most powerful hook as it can **approve or deny tool executions**. Use this hook to block dangerous commands, enforce security policies and coding standards, require approval for sensitive operations, or log tool usage for compliance.\n* **postToolUse**: Executed after a tool completes execution (whether successful or failed). Can be used to log execution results, track usage statistics, generate audit trails, monitor performance metrics, and send failure alerts.\n* **agentStop**: Executed when the main agent has finished responding to your prompt.\n* **subagentStop**: Executed when a subagent completes, before returning results to the parent agent.\n* **errorOccurred**: Executed when an error occurs during agent execution. Can be used to log errors for debugging, send notifications, track error patterns, and generate reports.\n\nTo see a complete reference of hook types with example use cases, best practices, and advanced patterns, see [Hooks configuration](/en/copilot/reference/hooks-configuration).\n\n## Hook configuration format\n\nYou configure hooks using a special JSON format. The JSON must contain a `version` field with a value of `1` and a `hooks` object containing arrays of hook definitions.\n\n```json copy\n{\n  \"version\": 1,\n  \"hooks\": {\n    \"sessionStart\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"string (optional)\",\n        \"powershell\": \"string (optional)\",\n        \"cwd\": \"string (optional)\",\n        \"env\": { \"KEY\": \"value\" },\n        \"timeoutSec\": 30\n      }\n    ],\n  }\n}\n```\n\nThe hook object can contain the following keys:\n\n| Property     | Required              | Description                                                                    |\n| ------------ | --------------------- | ------------------------------------------------------------------------------ |\n| `type`       | Yes                   | Must be `\"command\"`                                                            |\n| `bash`       | Yes (on Unix systems) | Path to the bash script to execute                                             |\n| `powershell` | Yes (on Windows)      | Path to the PowerShell script to execute                                       |\n| `cwd`        | No                    | Working directory for the script (relative to repository root)                 |\n| `env`        | No                    | Additional environment variables that are merged with the existing environment |\n| `timeoutSec` | No                    | Maximum execution time in seconds (default: 30)                                |\n\n## Example hook configuration file\n\nThis is an example configuration file that lives in `~/.github/hooks/project-hooks.json` within a repository.\n\n```json copy\n{\n  \"version\": 1,\n  \"hooks\": {\n    \"sessionStart\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"echo \\\"Session started: $(date)\\\" >> logs/session.log\",\n        \"powershell\": \"Add-Content -Path logs/session.log -Value \\\"Session started: $(Get-Date)\\\"\",\n        \"cwd\": \".\",\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\": \"scripts\",\n        \"env\": {\n          \"LOG_LEVEL\": \"INFO\"\n        }\n      }\n    ],\n    \"preToolUse\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"./scripts/security-check.sh\",\n        \"powershell\": \"./scripts/security-check.ps1\",\n        \"cwd\": \"scripts\",\n        \"timeoutSec\": 15\n      },\n      {\n        \"type\": \"command\",\n        \"bash\": \"./scripts/log-tool-use.sh\",\n        \"powershell\": \"./scripts/log-tool-use.ps1\",\n        \"cwd\": \"scripts\"\n      }\n    ],\n    \"postToolUse\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"cat >> logs/tool-results.jsonl\",\n        \"powershell\": \"$input | Add-Content -Path logs/tool-results.jsonl\"\n      }\n    ],\n    \"sessionEnd\": [\n      {\n        \"type\": \"command\",\n        \"bash\": \"./scripts/cleanup.sh\",\n        \"powershell\": \"./scripts/cleanup.ps1\",\n        \"cwd\": \"scripts\",\n        \"timeoutSec\": 60\n      }\n    ]\n  }\n}\n```\n\n## Performance considerations\n\nHooks run synchronously and block agent execution. To ensure a responsive experience, keep the following considerations in mind:\n\n* **Minimize execution time**: Keep hook execution time under 5 seconds when possible.\n* **Optimize logging**: Use asynchronous logging, like appending to files, rather than synchronous I/O.\n* **Use background processing**: For expensive operations, consider background processing.\n* **Cache results**: Cache expensive computations when possible.\n\n## Security considerations\n\nTo ensure security is maintained when using hooks, keep the following considerations in mind:\n\n* **Always validate and sanitize the input processed by hooks**. Untrusted input could lead to unexpected behavior.\n* **Use proper shell escaping when constructing commands**. This prevents command injection vulnerabilities.\n* **Never log sensitive data, such as tokens or passwords**.\n* **Ensure hook scripts and logs have the appropriate permissions**.\n* **Be cautious with hooks that make external network calls**. These can introduce latency, failures, or expose data to third parties.\n* **Set appropriate timeouts to prevent resource exhaustion**. Long-running hooks can block agent execution and degrade performance.\n\n## Next steps\n\nTo start creating hooks, see [Customize agent workflows with hooks](/en/copilot/how-tos/use-copilot-agents/cloud-agent/use-hooks)."}