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

1

Install UV

UV is required to run the pre-commit tool. Install UV hereThen install pre-commit using UV:
uv tool install pre-commit
2

Configure pre-commit

Add to your .pre-commit-config.yaml:
---
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
3

Install the hook

Run this one-time setup in your repository:
pre-commit install
This installs the pre-commit hook into your local git repository.
All-in-one setup: After installing UV, you can run everything with:
uv tool install pre-commit && pre-commit install

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:
$ 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:
# ❌ 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:
// ❌ 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:
# ❌ 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

Updating the Hook

Keep your policies current:
# 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 rollout guide 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 to see how you can have pre-commit hooks automatically configured from the first commit

Comparison with Other Tools

FeatureZenable Pre-commitTraditional LintersSAST Tools
Policy customization✅ Natural language❌ Code rules only❌ Fixed rules
Setup complexitySimpleModerateComplex
SpeedFastFastSlow
AI-powered fixes
Cross-language❌ Per-language
Policy-as-codePartial

Next Steps