Core concepts
Understand actions, policy decisions, attribution, approvals, and evidence.
Tool Wrapping
A governed wrapper checks an action before calling the original tool. If the decision permits execution, it runs the callback and returns its result. If refused, the callback does not run. Wrap the execution path, including async calls and framework dispatch; wrapping a model client alone is insufficient.
Approved Scope
approved_scope lists the tools your application intends an agent to use.
It is request context, not a policy installation or an authorization grant.
The server evaluates its configured policy and the supplied context. Agree on
tool names and policy with your administrator before connecting a real agent.
Enforcement Modes
Observe
Collect telemetry without enforcing actions. Python bypasses the enforcer in this mode.
Step-up auth
Request approval according to server policy. Keep the tool paused until the hold resolves.
Progressive
Evaluate actions with progressive policy. Outcomes depend on server policy and context.
Block
Use blocking enforcement. Server policy decides which actions are permitted or refused.
Use the mode specified for your environment. The trial demo uses progressive
with a configured policy that allows demo.read and blocks shell.exec.
Mode names alone do not promise a particular decision for every tool or risk level.
Observe does not verify enforcement
Python observe mode bypasses the enforcer. It can help collect telemetry, but an observed call does not demonstrate that policy permitted it. Use an enforcing mode to verify the first-agent guide.
The SDKs default to fail-closed behavior for retryable transport and service
failures in enforcing modes. Keep THOTH_FAIL_OPEN=false for the Python
first-agent example and failOpen: false / FailOpen: false for TypeScript / Go.
Enabling fail-open can permit execution when a decision cannot be obtained.
Sessions
A session groups one unit of work, such as a user request or background job. Use distinct session identifiers to correlate its actions and decisions. See your SDK reference for explicit session lifecycle and cleanup. Avoid sharing one process-wide session across unrelated users.
Attribution
Carry the initiating user's identity into user_id / userId / UserID,
using an identity established by your application. Do not accept it directly
from model output. Keep tenant and agent identity bound to authenticated
application context. For unattended jobs, record the service actor and the
responsible owner through your configured policy and audit workflow.
An actor label does not prove consent. Important actions need an authorization workflow that records the responsible approver and the decision.
Step-Up Auth
STEP_UP pauses a proposed action while an authorized approver decides whether
it may proceed. The enforcer returns a hold token, and the SDK polls its status.
Approval permits execution; denial or expiry refuses it. Do not run the original
callback while a hold is pending or when an error interrupts the approval flow.
Configure the supported approval channel before testing it. Notifications, timeouts, and integrations depend on the deployment; the developer demo does not require Slack writes. The enforcement API documents the hold endpoint.
Behavioral Events
SDKs can emit tool and model events for investigation. Event delivery and retention depend on the environment. Background telemetry may fail independently of enforcement; a successfully returned callback is not proof that its events were retained. Close or flush clients according to your SDK's lifecycle API.
A server decision, an SDK event, and a signed decision receipt are different artifacts. Correlate them and verify available signatures/exports when collecting evidence. Do not put unnecessary secrets or personal data in tool arguments, results, or metadata.
Policy Violations
| SDK | Refusal type |
|---|---|
| Python | ThothPolicyViolation |
| TypeScript | ThothPolicyViolation |
| Go | *thoth.PolicyViolationError |
A refusal can also represent a fail-closed authentication, transport, or service error. Inspect the reason and corresponding server decision before reporting it as a successful policy block. Never catch a refusal and retry the original, ungoverned tool. Return a safe explanation or escalate to your configured approval workflow.
Run your first governed agent to verify an
ALLOW and BLOCK, then instrument your own agent.