Skip to main content

tealtiger-openhands

Deterministic governance hooks for OpenHands — file access control, command allowlisting, secret scanning, cost budgets, and structured audit evidence.

<2ms per evaluation. No LLM in the governance path. Apache 2.0.

What it does

tealtiger-openhands adds a governance layer to OpenHands agent sessions using the native PreToolUse hook system. Before any tool executes (terminal commands, file edits, browser actions), the hook evaluates your policy and returns ALLOW or DENY.

Capability What it protects
File access control Block reads of .env, SSH keys, credentials. Restrict writes to approved paths.
Command allowlisting Only approved commands execute. Block destructive/network commands.
Secret scanning Detect hardcoded API keys, passwords, tokens in file writes before commit.
Network blocking Prevent curl, wget, ssh and URL patterns in commands.
Cost budget Per-session USD limit + iteration cap. Hard stop when exceeded.
Kill switch Instantly freeze a runaway session.
Structured audit Every decision logged: correlation_id, action, reason_codes, risk_score, timing.

Quick Start

1. Install

pip install tealtiger-openhands

2. Create governance config

Create .openhands/governance.yml in your repository:

mode: ENFORCE

file_policy:
  read_denylist:
    - ".env*"
    - "**/*.pem"
    - ".ssh/**"
  write_allowlist:
    - "src/**"
    - "tests/**"

command_policy:
  allowlist:
    - python
    - pytest
    - pip
    - git
    - cat
    - ls
    - grep
  denylist:
    - "rm -rf"
  block_network_access: true

secret_scan:
  enabled: true
  action: block

budget:
  per_session_usd: 5.00
  max_iterations: 100

3. Register the hook

Create .openhands/hooks.json:

{
  "pre_tool_use": [
    {
      "matcher": "*",
      "hooks": [
        {
          "command": "tealtiger-openhands-hook --config .openhands/governance.yml",
          "timeout": 5
        }
      ]
    }
  ]
}

4. Done

Next time OpenHands works on your repository, every tool call will be evaluated against your governance policy before execution.

Governance Modes

Mode Behavior
ENFORCE Block violations. Agent receives denial reason and can adapt.
MONITOR Log violations but allow execution. For rollout testing.
OBSERVE Passthrough with full audit trail. Zero enforcement.

Start with OBSERVE to see what your agent does, then move to MONITOR, then ENFORCE.

How it works

Agent decides action → OpenHands PreToolUse hook fires
    → tealtiger-openhands-hook reads event from stdin (JSON)
    → Evaluates against governance.yml policy (<2ms)
    → Outputs decision JSON to stdout
    → Exit 0 (allow) or Exit 2 (block)
        → If blocked: agent gets denial reason, adapts behavior
        → If allowed: tool executes normally
    → Audit record appended to .openhands/.tealtiger-state/audit.jsonl

Programmatic Usage (SDK)

You can also use tealtiger-openhands as a Python library alongside the OpenHands SDK:

from openhands.sdk import LLM, Conversation
from openhands.sdk.hooks import HookConfig, HookDefinition, HookMatcher
from openhands.tools.preset.default import get_default_agent

# Register TealTiger as a PreToolUse hook
hook_config = HookConfig(
    pre_tool_use=[
        HookMatcher(
            matcher="*",
            hooks=[
                HookDefinition(
                    command="tealtiger-openhands-hook --config .openhands/governance.yml",
                    timeout=5,
                )
            ],
        )
    ],
)

agent = get_default_agent(llm=llm)
conversation = Conversation(
    agent=agent,
    workspace="/path/to/repo",
    hook_config=hook_config,
)

Decision Contract

Every evaluation produces a structured decision:

{
  "correlation_id": "uuid-v4",
  "timestamp_ms": 1719849600000,
  "action": "DENY",
  "reason": "Command denied: matches denylist pattern 'rm -rf'",
  "reason_codes": ["COMMAND_DENIED"],
  "risk_score": 0.9,
  "policy_version": "1",
  "findings": [],
  "evaluation_time_ms": 0.8,
  "tool_name": "terminal",
  "session_id": "abc-123"
}

Audit Trail

All decisions are logged to .openhands/.tealtiger-state/audit.jsonl (one JSON record per line). Use this for SOC2/HIPAA compliance evidence.

Configuration Reference

file_policy

Field Type Description
read_allowlist string[] Glob patterns for allowed reads. Empty = allow all.
read_denylist string[] Glob patterns for blocked reads. Checked first.
write_allowlist string[] Glob patterns for allowed writes. Empty = allow all.
write_denylist string[] Glob patterns for blocked writes. Checked first.

command_policy

Field Type Description
allowlist string[] Base commands allowed to execute. Empty = allow all.
denylist string[] Substring patterns to block. Checked first.
block_network_access bool Block curl, wget, ssh, and URL patterns.

secret_scan

Field Type Description
enabled bool Enable/disable scanning.
action string "block" or "warn".
categories string[] Which secret types to detect.

budget

Field Type Description
per_session_usd float Max cost per session.
max_iterations int Max tool calls per session. 0 = unlimited.

Related

License

Apache 2.0

Release files for tealtiger-openhands 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tealtiger-openhands 0.1.0
File Size Uploaded
tealtiger_openhands-0.1.0.tar.gz 21.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tealtiger-openhands 0.1.0
File Interpreter ABI Platform
tealtiger_openhands-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 39.8 kB

Release files / tealtiger_openhands-0.1.0.tar.gz

Download URL tealtiger_openhands-0.1.0.tar.gz
Size 21.7 kB
Tags Source
SHA-256 checksum
How to use checksums
215498902d464f9401c8549266675f3fb8a86f0d0b618c3d44e66c5de2f2c145
BLAKE2b-256 checksum
How to use checksums
ec2cb6c6a5ffe41b09345f043ab68913ddc7317b1076636809470937515d3fbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release files / tealtiger_openhands-0.1.0-py3-none-any.whl

Download URL tealtiger_openhands-0.1.0-py3-none-any.whl
Size 18.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
86e228fb5d73e512f9f65da34e1f7ba704c02c50d65875ff75cc3aaae4f54e87
BLAKE2b-256 checksum
How to use checksums
f6141c314a744a990c5316e277f32eb708de8050d09c0e9d34838ec62286f513
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.2

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page