> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenable.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Pre-commit Hook

> Automatically enforce policies before code is committed

## Overview

The Zenable pre-commit hook automatically checks your code against organizational policies before each commit, preventing policy violations from entering your codebase. This ensures consistent code quality and compliance across your entire development team.

## Quick Start

<Note>
  **Looking for better performance?** Try [prek](https://github.com/j178/prek), a drop-in replacement for pre-commit with faster execution. All commands in this guide work with prek by replacing `pre-commit` with `prek`.
</Note>

<Steps>
  <Step title="Install UV">
    Don't have UV? [Install UV here](https://docs.astral.sh/uv/getting-started/installation/)

    Then install pre-commit using UV:

    ```bash theme={null}
    uv tool install pre-commit
    ```
  </Step>

  <Step title="Configure pre-commit">
    Add to your `.pre-commit-config.yaml`:

    ```yaml theme={null}
    ---
    repos:
     - repo: https://github.com/Zenable-io/ai-native-python
       rev: v0.2.0 # Use `pre-commit autoupdate --freeze` to safely maintain this
       hooks:
         - id: zenable-check
    ```
  </Step>

  <Step title="Install the hook">
    Run this one-time setup in your repository:

    ```bash theme={null}
    pre-commit install
    ```

    This installs the pre-commit hook into your local git repository.
  </Step>
</Steps>

<Note>
  **All-in-one setup:** After installing UV, you can run everything with:

  ```bash theme={null}
  uv tool install pre-commit && pre-commit install
  ```
</Note>

## How It Works

When you commit code, the pre-commit hook:

1. **Intercepts the commit** before it's finalized
2. **Checks changed files** against your configured policies
3. **Reports violations** with specific line numbers and fix suggestions
4. **Blocks the commit** if violations are found (configurable)
5. **Allows the commit** once all issues are resolved

### Example Workflow

When issues are found, the commit is blocked:

```bash expandable theme={null}
$ git commit -m "Add new feature"
Run a Zenable check on all changed files.................................Failed
- hook id: zenable-check
- exit code: 2


================================================
               Welcome to Zenable
        Production-Grade AI Coding Tools
================================================

Detecting files...

==========================================
        CONFORMANCE CHECK COMPLETE
==========================================

Overall Result: FAIL
Checks Run: 3

File: `/Users/jonzeolla/src/test-repo/feature.py`
- Check `og_requests_no_timeout_autofix`: `fail`
  - Finding: The 'requests' call doesn't have a 'timeout'. Will automatically add 'timeout=60'.
    - Location: `/Users/jonzeolla/src/test-repo/feature.py:70:16-70:33`
    - Suggested fix: `requests.get(url, timeout=60)`
- Check `og_python_catch_generic_exception`: `fail`
  - Finding: Avoid catching generic exceptions like 'Exception' or using a bare 'except:'. This can hide unexpected bugs and make debugging difficult. Be explicit about the exceptions you intend to handle (e.g., 'except ValueError:').
    - Location: `/Users/jonzeolla/src/test-repo/feature.py:37:5-41:13`
- Check `AIRecommendation-with-rag`: `fail`
  - Finding: The file contains hardcoded secrets (API_KEY, DATABASE_PASSWORD, SECRET_TOKEN) in plain text. Even though this is marked as an example file, these should be replaced with placeholder text or environment variable references to prevent accidental exposure.
  - Finding: The eval() function is used with user input in dangerous_calculator(), creating a critical code injection vulnerability. This should be removed or replaced with ast.literal_eval() for safe evaluation of literals only.
  - Finding: The pickle.loads() usage in load_user_data() creates a critical deserialization vulnerability that can lead to arbitrary code execution. This should be replaced with safer serialization methods like json.
  - Finding: The SQL injection vulnerability in get_user_unsafe() demonstrates dangerous string concatenation. Replace with parameterized queries using placeholders.
  - Finding: The infinite_recursion() function will cause a stack overflow and crash the program. Add a base case or remove this function entirely.
  - Finding: The bare except clause in process_data() silently swallows all exceptions including system exits and keyboard interrupts, making debugging impossible. Replace with specific exception types.
  - Finding: The unsafe_critical_section() function can cause deadlocks if an exception occurs between lock.acquire() and lock.release(). Use 'with lock:' instead.
  - Finding: The file modifies sys.path at module level which can cause import issues and unpredictable behavior across the application. Remove this
    modification.
```

After fixing the issues, the commit succeeds:

```
$ git commit -m "Add new feature"
Run a Zenable check on all changed files.................................Passed
```

## Common Use Cases

### Security Policies

Prevent security vulnerabilities:

```python theme={null}
# ❌ Blocked by pre-commit
query = f"SELECT * FROM users WHERE id = {user_input}"  # SQL injection vulnerability
cursor.execute(query)

# ✅ Passes pre-commit
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_input,))
```

### Code Quality

Enforce quality standards:

```javascript theme={null}
// ❌ Blocked by pre-commit
console.log(userData);  // Debug logging in production code

// ✅ Passes pre-commit
logger.debug(userData);  // Proper logging
```

### Compliance Requirements

Ensure regulatory compliance:

```python theme={null}
# ❌ Blocked by pre-commit
def process_payment(card_number):
    log(f"Processing payment for {card_number}")  # PCI violation

# ✅ Passes pre-commit
def process_payment(card_number):
    log(f"Processing payment for {mask_card(card_number)}")
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Hook not running?">
    Ensure the hook is installed:

    ```bash theme={null}
    # Check if hooks are installed
    ls .git/hooks/pre-commit

    # Reinstall if missing
    pre-commit install
    ```
  </Accordion>

  <Accordion title="Bypassing the hook temporarily?">
    In emergencies, you can bypass:

    ```bash theme={null}
    git commit --no-verify -m "Emergency fix"
    ```

    ⚠️ Use sparingly - this defeats the purpose of policy enforcement

    <Note>
      **Important:** You should expect that developer-local configurations can be worked around, either intentionally or unintentionally. For defense in
      depth, combine pre-commit hooks with server-side enforcement through our [GitHub](/integrations/vcs-reviewers/github) and [GitLab](/integrations/vcs-reviewers/gitlab) reviewers to ensure
      comprehensive policy coverage.
    </Note>
  </Accordion>
</AccordionGroup>

## Updating the Hook

Keep your policies current:

```bash theme={null}
# Update to latest version
pre-commit autoupdate --freeze

# Commit the updated config
git add .pre-commit-config.yaml
git commit -m "Update Zenable pre-commit hook"
```

## Best Practices

1. **Start gradually** - Begin with warnings before enforcing. Review our [deployment guide](/deployment-adoption) for proven adoption strategies
2. **Run manually first** - Test with `pre-commit run --all-files`
3. **Keep hooks fast** - Use file filters to check only relevant files
4. **Update regularly** - Run `pre-commit autoupdate` monthly via scheduled pipelines
5. **Document exceptions** - Make policy exceptions visible and temporary
6. **Provide context** - Help developers understand why policies exist
7. **Be Automation-first** - See [starting new projects](/use-cases/starting-new-project) to see how you can have pre-commit hooks automatically
   configured from the first commit

## Comparison with Other Tools

| Feature              | Zenable Pre-commit | Traditional Linters | SAST Tools    |
| -------------------- | ------------------ | ------------------- | ------------- |
| Policy customization | ✅ Natural language | ❌ Code rules only   | ❌ Fixed rules |
| Setup complexity     | Simple             | Moderate            | Complex       |
| Speed                | Fast               | Fast                | Slow          |
| AI-powered fixes     | ✅                  | ❌                   | ❌             |
| Cross-language       | ✅                  | ❌ Per-language      | ✅             |
| Policy-as-code       | ✅                  | ❌                   | Partial       |

## Next Steps

* Configure the [IDE integration](/integrations/mcp/getting-started) for real-time feedback
* Set up [GitHub](/integrations/vcs-reviewers/github) or [GitLab](/integrations/vcs-reviewers/gitlab) integrations for pull request checks
* Define [custom policies](/use-cases/policy-as-code) for your organization
* Explore [advanced use cases](/use-cases)
