- Fetching a risk score from an internal service
- Checking temporary approvals or maintenance windows
- Adding business context from an existing API
- Normalizing an external response into a stable object for policies
Writing Hooks
Hooks are written in JavaScript or TypeScript. The source must provide a default exported function, which may be synchronous or asynchronous.
Only
input is required. Hooks that do not use environment variables or caching may omit the other arguments.
The return value must be representable as JSON. Objects, arrays, strings, numbers, booleans, and null are supported. The top-level value cannot be undefined, a function, or a symbol. Circular objects and bigint values are also unsupported.
Imports are not supported. All required logic must be included in the hook source.
Status
Use draft status while developing a hook. Activate it before creating or updating a policy that references it.
Policy Evaluation
Policies reference hook results throughinput.hooks.<name>. This policy blocks a request when the risk hook returns a score of 5 or greater:
input.hooks. It then completes the policy evaluation. Formal invokes a shared hook once when several applicable policies reference it.
Hook references must use a fixed name. Both input.hooks.risk and input.hooks["risk"] are valid. Dynamic references such as input.hooks[hook_name] are not supported.
A policy can only reference an active hook. Formal rejects references to
missing or draft hooks when validating the policy.
Complete Example
The following hook requests a risk score and caches the result for 60 seconds:Network Access
Network access is denied by default. A hook can usefetch only for destinations included in its allowed network hosts.
The allowlist accepts hostnames, IP addresses, and IP ranges in CIDR notation. Enter the destination without a scheme, path, or port. An allowed destination permits connections to all ports on that host or range.
For example, allow risk.example.com rather than https://risk.example.com/v1/score.
Environment Variables
Theenv argument contains only variables named in the hook’s allowed environment variables. Formal omits allowed variables that are not set on the evaluating endpoint.
No environment variables are available by default. Required variables must be configured on every Connector or Endpoint that may evaluate the hook.
Caching
Thecache argument stores JSON-compatible values between evaluations of the same hook. Each hook’s cache is isolated from other hooks.
cache.get(key) returns the stored value. It returns undefined when the key is missing or expired. cache.set(key, value, ttlSeconds) stores the value for the specified number of seconds. Writes are immediately visible to later reads during the same evaluation.
To share cached values across multiple instances of the same Connector, enable clustering. Replication between instances is eventually consistent: an evaluation sees its own writes, but other Connector instances may not see them immediately.
Cache availability and persistence failures do not fail an otherwise successful hook evaluations. Writes are applied after successful execution and failures are logged.
Caching is in-memory only and does not persist across Connector or Endpoint restarts. Cache entries may be unavailable or expire at any time. Treat the cache as an optimization rather than an authoritative data source.
Limits
Execution Limits
Cache Limits
Output and cache value limits use UTF-8 byte counts after JSON serialization. Cache key limits also use UTF-8 byte counts.
Errors
A hook evaluation fails when the hook:- Exceeds its configured timeout
- Throws an error or returns a rejected promise
- Attempts a network request to a destination that is not allowed
- Returns a value that cannot be represented as JSON
- Returns more than 1 MiB of serialized JSON
- Exceeds a cache limit
Next Steps
Policy Evaluation
Review the input available at each policy stage
Policy Examples
Explore common policy patterns