# About hooks for GitHub Copilot

Extend and customize GitHub Copilot agent behavior by executing custom shell commands at key points during agent execution.

## What are hooks?

Hooks are a way of executing custom shell commands at strategic points in an agent's workflow, such as when an agent session starts or ends, when you enter a prompt, or when a tool is called.

Hooks receive detailed information about agent actions via JSON input, enabling context-aware automation. For example, you can use hooks to:

* Programmatically approve or deny tool executions.
* Use built-in security features like secret scanning to prevent credential leaks.
* Implement custom validation rules and audit logging for compliance.

Hooks are available for use with:

* **Copilot cloud agent** on GitHub.
* **GitHub Copilot CLI** in your terminal.

You define hooks in JSON files, stored in your repository at `.github/hooks/*.json`. These apply whenever Copilot agents are used in the repository. Copilot CLI also supports personal hooks that you store in your home directory at `~/.copilot/hooks/*.json`. These apply whenever you use Copilot CLI.

## Types of hooks

The following types of hooks are available:

* **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.
* **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.
* **userPromptSubmitted**: Executed when the user submits a prompt to the agent. Can be used to log user requests for auditing and usage analysis.
* **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.
* **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.
* **agentStop**: Executed when the main agent has finished responding to your prompt.
* **subagentStop**: Executed when a subagent completes, before returning results to the parent agent.
* **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.

To see a complete reference of hook types with example use cases, best practices, and advanced patterns, see [GitHub Copilot hooks reference](/en/copilot/reference/hooks-reference).

## Hook configuration format

You 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.

```json copy
{
  "version": 1,
  "hooks": {
    "sessionStart": [
      {
        "type": "command",
        "bash": "string (optional)",
        "powershell": "string (optional)",
        "cwd": "string (optional)",
        "env": { "KEY": "value" },
        "timeoutSec": 30
      }
    ],
  }
}
```

The hook object can contain the following keys:

| Property     | Required              | Description                                                                    |
| ------------ | --------------------- | ------------------------------------------------------------------------------ |
| `type`       | Yes                   | Must be `"command"`                                                            |
| `bash`       | Yes (on Unix systems) | Path to the bash script to execute                                             |
| `powershell` | Yes (on Windows)      | Path to the PowerShell script to execute                                       |
| `cwd`        | No                    | Working directory for the script (relative to repository root)                 |
| `env`        | No                    | Additional environment variables that are merged with the existing environment |
| `timeoutSec` | No                    | Maximum execution time in seconds (default: 30)                                |

## Example hook configuration file

This is an example configuration file that lives in `~/.github/hooks/project-hooks.json` within a repository.

```json copy
{
  "version": 1,
  "hooks": {
    "sessionStart": [
      {
        "type": "command",
        "bash": "echo \"Session started: $(date)\" >> logs/session.log",
        "powershell": "Add-Content -Path logs/session.log -Value \"Session started: $(Get-Date)\"",
        "cwd": ".",
        "timeoutSec": 10
      }
    ],
    "userPromptSubmitted": [
      {
        "type": "command",
        "bash": "./scripts/log-prompt.sh",
        "powershell": "./scripts/log-prompt.ps1",
        "cwd": "scripts",
        "env": {
          "LOG_LEVEL": "INFO"
        }
      }
    ],
    "preToolUse": [
      {
        "type": "command",
        "bash": "./scripts/security-check.sh",
        "powershell": "./scripts/security-check.ps1",
        "cwd": "scripts",
        "timeoutSec": 15
      },
      {
        "type": "command",
        "bash": "./scripts/log-tool-use.sh",
        "powershell": "./scripts/log-tool-use.ps1",
        "cwd": "scripts"
      }
    ],
    "postToolUse": [
      {
        "type": "command",
        "bash": "cat >> logs/tool-results.jsonl",
        "powershell": "$input | Add-Content -Path logs/tool-results.jsonl"
      }
    ],
    "sessionEnd": [
      {
        "type": "command",
        "bash": "./scripts/cleanup.sh",
        "powershell": "./scripts/cleanup.ps1",
        "cwd": "scripts",
        "timeoutSec": 60
      }
    ]
  }
}
```

## Performance considerations

Hooks run synchronously and block agent execution. To ensure a responsive experience, keep the following considerations in mind:

* **Minimize execution time**: Keep hook execution time under 5 seconds when possible.
* **Optimize logging**: Use asynchronous logging, like appending to files, rather than synchronous I/O.
* **Use background processing**: For expensive operations, consider background processing.
* **Cache results**: Cache expensive computations when possible.

## Security considerations

To ensure security is maintained when using hooks, keep the following considerations in mind:

* **Always validate and sanitize the input processed by hooks**. Untrusted input could lead to unexpected behavior.
* **Use proper shell escaping when constructing commands**. This prevents command injection vulnerabilities.
* **Never log sensitive data, such as tokens or passwords**.
* **Ensure hook scripts and logs have the appropriate permissions**.
* **Be cautious with hooks that make external network calls**. These can introduce latency, failures, or expose data to third parties.
* **Set appropriate timeouts to prevent resource exhaustion**. Long-running hooks can block agent execution and degrade performance.

## Next steps

To start creating hooks, see:

* [Customize agent workflows with hooks](/en/copilot/how-tos/copilot-on-github/customize-copilot/customize-cloud-agent/use-hooks) for Copilot cloud agent
* [Using hooks with GitHub Copilot CLI](/en/copilot/how-tos/copilot-cli/customize-copilot/use-hooks) for GitHub Copilot CLI