Skip to main content
TealEngine v1.2 introduces a module system that decomposes governance into independent, composable modules. Each module owns a single governance dimension (secrets, memory, reliability, registry) and runs in parallel with all other active modules.

How It Works

The v1.2 evaluation pipeline follows this sequence:
  1. Resolve — Determine which modules the policy references
  2. Validate — Confirm all required modules are registered
  3. Lazy-init — Initialize modules that haven’t been initialized yet
  4. Dispatch — Run all active modules in parallel (Promise.allSettled / asyncio.gather)
  5. Handle failures — Apply fail-closed defaults for any module that throws
  6. Merge — Combine results using “most restrictive action wins”
  7. Validate — Check the merged Decision against the TEEC registry

ModuleRegistry

The ModuleRegistry manages module lifecycle:

Registration

Modules are registered eagerly at engine construction time. Registration does not call init().

Lazy Initialization

Modules are initialized on the first evaluation that references them. If a policy doesn’t reference a module’s dimension, that module is never initialized — saving startup time and resources.

Dependency Resolution

The registry maps policy keys to module names using a well-known convention: If a policy references a module that isn’t registered, the engine throws a TealConfigError before evaluation begins.

Module Status

Query the status of all registered modules at any time:

“Most Restrictive Action Wins” Merge

When multiple modules return results, the engine merges them by selecting the most restrictive action. This ensures that if any module flags a concern, the overall decision reflects it.

Action Severity Ranking

Merge Example

If three modules return: The merged result is DENY_WRITE (severity 100). All reason codes from all modules are combined into the final decision.
The merge strategy is intentionally conservative. A single DENY from any module overrides ALLOW from all others. This is a security-first design choice.

Fail-Closed Defaults

If any module throws an exception during evaluation, the engine applies a fail-closed default:
  • The overall decision becomes DENY
  • The reason includes which module(s) failed
  • Failed module names appear in metadata.modules_failed
You can override this to FAIL_OPEN for non-critical environments:
FAIL_OPEN should only be used in development or monitoring environments. In production, always use FAIL_CLOSED.

Granular Failure Policies

You can configure failure behavior for specific scenarios:

Writing a Custom Module

Implement the TealModule interface to create your own governance module.

TealModule Interface

Example: Custom Rate Limiter

Register Your Module

Custom modules participate in the same parallel dispatch and merge pipeline as built-in modules. They receive the same ModuleContext and must return a valid ModuleResult.

ModuleContext

Every module receives a ModuleContext with request metadata:

ModuleResult

Every module must return a ModuleResult: