Skip to Content
Task guidesTechnical: Execution Hooks

Execution Hooks

Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.

Hooks are operator-defined interceptors that fire at execution lifecycle points. They enable custom governance, validation, and observability without code changes.

Hooks are workload-scoped. Managing them requires hook.manage on the workspace that owns the workload. Runtime execution loads the enabled hook set with the workload context and evaluates matching hooks while steps and agent tools run.

A hook_definition can also ship as a package-local asset inside an official or community plugin package. Installing that package materializes the hook definition into the workspace, but it is not usable until explicitly bound to a release role — see Plugins & Connectors for the package install lifecycle and Resolving And Binding Installed Assets for the bind step. The event/matcher/evaluation mechanics below apply identically to hand-authored and package-installed hooks.

Hook events

EventWhenCan Block
PreStepUseBefore any step executesYes
PostStepUseAfter step completesNo
PreToolUseBefore agent tool callYes
PostToolUseAfter agent tool returnsNo

Hook types

TypeHow it runsUse case
functionCalls a registered hook function by namePrebuilt guards, validators

Only function hooks are part of the current public contract. Function hooks reference a runtime-registered function through definition.function_ref.

Hook Fields

FieldDescription
eventOne of PreStepUse, PostStepUse, PreToolUse, or PostToolUse.
matcherOptional regex matched against the tool name for tool events.
hook_typeCurrently function.
definitionHook-specific JSON. For prebuilt hooks, use {"function_ref": "<name>"}.
priorityHigher priority hooks are listed first. Matching hooks still evaluate in parallel.
enabledDisabled hooks are stored but not evaluated.
timeout_secondsPer-hook timeout. Timed-out hooks emit diagnostics and continue.

Each workload can have up to 50 enabled hooks. Hook definitions are capped at 32 KiB after canonical JSON serialization. Matcher regexes use the same operator-authored regex guard as custom guardrails: patterns over 512 characters, malformed regexes, and nested unbounded quantifier shapes such as (a+)+ are rejected at authoring time. Previously persisted unsafe matchers fail closed at runtime: tool-scoped events are blocked and emit a hook diagnostic. Residual backtracking shapes that pass the authoring heuristic are bounded by a per-match runtime deadline and also fail closed with a hook diagnostic instead of wedging the executor.

Creating a hook

curl -X POST http://localhost:8000/v1/workloads/{id}/hooks \ -H "Content-Type: application/json" \ -d '{ "event": "PreToolUse", "matcher": "postgres_query|mysql_query", "hook_type": "function", "definition": {"function_ref": "sql_injection_guard"}, "timeout_seconds": 5 }'

API Reference

# List hooks for a workload curl http://localhost:8000/v1/workloads/{workload_id}/hooks # Create a hook curl -X POST http://localhost:8000/v1/workloads/{workload_id}/hooks \ -H "Content-Type: application/json" \ -d '{"event":"PreToolUse","hook_type":"function","definition":{"function_ref":"ssrf_guard"}}' # Disable a hook without deleting it curl -X PATCH http://localhost:8000/v1/workloads/{workload_id}/hooks/{hook_id} \ -H "Content-Type: application/json" \ -d '{"enabled": false}' # Delete a hook curl -X DELETE http://localhost:8000/v1/workloads/{workload_id}/hooks/{hook_id}

SDK Usage

from orqestra_sdk import OrqestraClient async with OrqestraClient("http://localhost:8000") as client: hooks = await client.hooks.list_hooks(workload_id) created = await client.hooks.create_hook( workload_id, { "event": "PreToolUse", "matcher": "http_request|web_fetch", "hook_type": "function", "definition": {"function_ref": "ssrf_guard"}, "timeout_seconds": 5, }, ) await client.hooks.delete_hook(workload_id, created["hook_id"])

Prebuilt hooks

The runtime ships three injection guard hooks:

HookTargetsWhat it detects
command_injection_guardcode_executionSemicolons, pipes, $(), rm -rf, banned commands
sql_injection_guardpostgres_query, mysql_query, snowflake_query, …UNION SELECT, ; DROP, OR 1=1, SLEEP()
ssrf_guardhttp_request, web_fetchPrivate IPs, cloud metadata endpoints (169.254.169.254)

Enable them by creating hooks with hook_type: "function" and definition.function_ref set to the guard name.

SSRF Private Host Allowance

ssrf_guard blocks private, loopback, and link-local IP literals by default. If a private IP is intentional, pass allowed_private_hosts in the hook definition config:

{ "function_ref": "ssrf_guard", "allowed_private_hosts": ["10.10.0.15"] }

Use this only for known internal services. Cloud metadata endpoints remain blocked.

Evaluation

Matching hooks run in parallel. If any hook returns block, the tool call is rejected. The most restrictive decision wins:

block > modify > continue

Timed-out hooks fail open (return continue) to prevent hanging.

Hook failures and timeouts emit runtime warnings and a hook_evaluation evidence artifact. Blocking hooks preserve the hook ID and reason so the execution record can explain why the tool call was rejected.

Operator Workflow

  1. Identify the workload and tool surface you want to guard.
  2. Create a disabled hook with the intended event, matcher, and function_ref.
  3. Enable the hook in a non-production workspace and run a known-safe tool call.
  4. Run a known-bad tool call and confirm the execution is blocked with the hook reason.
  5. Inspect evidence for hook_evaluation warnings or advisories.
  6. Promote the same hook definition through the governed release or workspace operations path used by your environment.