Create your workspace
Create a Verdict account. New organizations start on the Developer free tier.
Create an accountVERDICT DEVELOPER DOCUMENTATION
Integrate Verdict into your agent or application. Evaluate tool calls before execution, route sensitive actions for human review, and keep a verifiable decision record.
YOUR FIRST GUARDED ACTION
Go from a new workspace to a protected tool call in a few steps.
Create a Verdict account. New organizations start on the Developer free tier.
Create an accountIn Organization, add a capability, team, and application. This hierarchy scopes credentials and policy.
Workspace setupUse Policies to configure tool patterns, limits, and allow, escrow, or kill CEL expressions.
Open policy controlsIn Settings, select the exact application and environment, then create and securely store its one-time credential bundle.
Credential setupInstall an SDK, configure its server-side credentials, and place the guard around the function that performs the real-world action.
See the Python exampleTry safely first. Use a development environment and a non-production tool implementation while validating policies and approval behavior.
RUNTIME & PACKAGING
Python is an editable local package. TypeScript is currently distributed as repository source, not a published npm package.
Python 3.10 or newer. Install from the repository root.
pip install -e ./sdks/pythonUse the SDK source in this repository from a server-side Node.js application.
import { VerdictTypeScriptSDK } from "./sdks/typescript/src";Server-side only. Both SDKs require client credentials and a private DPoP key. Never bundle them into a browser application or expose credentials to end users.
ORGANIZATION MODEL
Use the hierarchy to define ownership boundaries and scope machine credentials.
Credential bundles are scoped to one environment. The console supports DEV, STAGING, SHADOW, and PROD. Create a separate bundle per environment; do not reuse a development key in production.
New organizations receive Developer: 10,000 governed calls per calendar month, 1 capability, 2 teams, and 3 applications. Members are unlimited. Limits are displayed in plan comparison and workspace settings.
MACHINE IDENTITY
Each bundle binds an OAuth client to one application, environment, and registered DPoP key.
Choose the capability, team, application, and environment in the console workspace bar.
Settings shows the client secret and private keys only in the creation response. Copy the bundle into a secret manager; Verdict cannot retrieve it later.
Load the values into server-side environment variables or your deployment platform’s secret store.
Issue a replacement, update the application, verify it, then revoke the old key. Suspended credentials can be resumed; revocation is permanent.
VERDICT_BASE_URL=https://your-verdict-host
VERDICT_CLIENT_ID=your_client_id
VERDICT_CLIENT_SECRET=load_from_secret_manager
VERDICT_DPOP_PRIVATE_KEY=load_from_secret_managerToken lifetime: access tokens last 5 minutes. Suspending or revoking a client prevents new token exchanges; already-issued tokens may remain valid until they expire.
DETERMINISTIC RULES
Policies combine a scope, matching tool pattern, rate and session limits, and optional CEL decisions.
| Setting | Purpose | Example |
|---|---|---|
| Scope | Where the rule applies | ORG, CAPABILITY, TEAM, APP |
| Tool pattern | Tool name to match | * or payments.create_transfer |
| Environment | Deployment environment or all environments | DEV, PROD, ALL |
| Enforcement | Apply a decision or record a shadow result | ENFORCE / SHADOW |
| Velocity limits | Calls per minute and per-session spend ceiling | 30 calls/min; 5000 USD |
Expressions can read args (proposed tool arguments), before (pre-flight snapshot), env (credential environment), and user (end-user identifier). Set allow, escrow, and kill expressions in the policy editor.
// Allow a transfer only below the per-action threshold
args.amount_usd <= 100.0
// Hold larger transfers for review
args.amount_usd > 100.0
// Block a transfer to a restricted destination
args.recipient_id == "restricted_account"Rule ordering: matching policies are evaluated in ascending priority order. For each policy, kill is checked before escrow, then allow. Test overlapping scopes and rules in development before enforcing them in production.
PYTHON SDK
The decorator evaluates the request before calling your function and applies approved argument modifications.
import os
from verdict_sdk import (
VerdictClient,
VerdictEscrowRejectedError,
VerdictPolicyBlockedError,
)
verdict = VerdictClient(
base_url=os.environ["VERDICT_BASE_URL"],
client_id=os.environ["VERDICT_CLIENT_ID"],
client_secret=os.environ["VERDICT_CLIENT_SECRET"],
dpop_private_key_b64=os.environ["VERDICT_DPOP_PRIVATE_KEY"],
agent_id="payments-agent",
)
@verdict.guard(
tool_name="payments.create_transfer",
risk_category="FINANCIAL",
value_field="amount",
)
def create_transfer(amount: float, currency: str, recipient_id: str):
# This function is called only after the Verdict decision allows it.
return payment_provider.create_transfer(
amount=amount,
currency=currency,
recipient_id=recipient_id,
)
try:
transfer = create_transfer(
amount=125.00,
currency="USD",
recipient_id="vendor_4821",
)
except VerdictPolicyBlockedError as error:
logger.warning("Transfer blocked: %s", error.reason)
except VerdictEscrowRejectedError as error:
logger.info("Transfer rejected by %s", error.approver)tool_name — stable name matched by policiesrisk_category — classification recorded with the actionvalue_field — function argument used as monetary exposurepre_flight_fn — capture state for review and before/after diffsrollback_fn — register an application compensation callbackVerdictPolicyBlockedError — the kill switch or policy blocks executionVerdictEscrowRejectedError — a reviewer rejects the actionVerdictEscrowTimeoutError — approval does not resolve in timeThe Python client is synchronous. Its escrow helper retries the long-poll endpoint when it returns HTTP 408, up to its configured wait deadline. Keep the guarded operation idempotent where possible and make the surrounding job timeout longer than the expected approval window.
TYPESCRIPT SDK
The current TypeScript SDK source targets server-side Node.js and wraps promise-returning functions.
import { VerdictTypeScriptSDK } from "./sdks/typescript/src";
const verdict = new VerdictTypeScriptSDK({
baseUrl: process.env.VERDICT_BASE_URL,
clientId: process.env.VERDICT_CLIENT_ID!,
clientSecret: process.env.VERDICT_CLIENT_SECRET!,
dpopPrivateKeyB64: process.env.VERDICT_DPOP_PRIVATE_KEY!,
agentId: "payments-agent",
});
const createTransfer = verdict.guard(
{
toolName: "payments.create_transfer",
riskCategory: "FINANCIAL",
valueField: "amount",
},
async (args: {
amount: number;
currency: string;
recipientId: string;
}) => paymentProvider.createTransfer(args),
);
try {
const transfer = await createTransfer({
amount: 125,
currency: "USD",
recipientId: "vendor_4821",
});
} catch (error) {
// Evaluation, kill-switch, escrow, and downstream errors reject the promise.
logger.error({ error }, "Guarded transfer did not complete");
}Source distribution: the TypeScript SDK lives under sdks/typescript/src in this repository and is not published to npm. Vendor or build the source into your server-side application; keep Node’s crypto and fetch available.
The SDK caches its DPoP-bound access token until shortly before expiry. A blocked decision, rejected approval, API error, or failure in the wrapped function rejects the returned promise; handle failures at the caller boundary.
FROM REQUEST TO RECORD
Evaluation is a gate before your side effect, not a replacement for your application’s own authorization or validation.
The SDK invokes the wrapped tool function with the proposed arguments.
The decision is recorded without holding the action. The function proceeds; shadow mode is not a production safety barrier.
The SDK waits for an authorized reviewer. A rejection prevents the wrapped function from running.
If a reviewer edits the payload, the SDK passes the modified arguments to the wrapped function.
The SDK raises/rejects before calling the wrapped function.
After the side effect: the SDK submits the execution output as a snapshot. If the external system succeeds but the snapshot commit fails, handle that as an operational reconciliation case; do not assume the external action was rolled back.
MACHINE-TO-MACHINE API
SDKs handle token exchange and DPoP proofs. These endpoints describe the current guarded-action path.
/oauth2/tokenExchange scoped client credentials and a DPoP proof for a 5-minute access token./v1/guard/evaluateEvaluate proposed tool arguments against policies, velocity controls, and kill switches./v1/guard/escrow/{execId}/waitLong-poll for an escrow resolution. A 408 response means the wait interval ended without resolution./v1/guard/commit-snapshotRecord the downstream execution output after the guarded function succeeds.Send an OAuth access token as Authorization: DPoP <token> and a fresh DPoP proof for the request method and URL. The evaluation body includes action identity, original arguments, optional pre-flight state, and monetary exposure.
{
"correlation_id": "corr-8f91a203",
"agent_id": "payments-agent",
"session_id": "sess_92bc15a1",
"end_user_id": "user_4821",
"tool_name": "payments.create_transfer",
"risk_category": "FINANCIAL",
"monetary_value_usd": 125,
"original_args": {
"amount": 125,
"currency": "USD",
"recipient_id": "vendor_4821"
},
"pre_flight_snapshot": {
"available_balance": 840.25
}
}{
"execution_id": "8bb7e9f4-4d3e-4e8f-a227-94716e7a940f",
"verdict_status": "ESCROW_PENDING",
"matched_policy_id": "1ca02b3c-...",
"computed_diff": {
"available_balance": {
"before": 840.25,
"proposed": 125
}
},
"hot_path_latency_ms": 8.42,
"current_rpm": "1",
"session_spend_usd": "125.00",
"record_hash": "..."
}The API returns HTTP 200 for a successfully evaluated decision, including block and escrow statuses. Inspect verdict_status; do not treat HTTP success alone as permission to execute.
PRODUCTION READINESS
Verdict adds a policy decision point. Your service still owns its identity, validation, and operational safety.
Store the secret and Ed25519 private key in a secret manager. Never commit them, log them, or send them to a browser.
Use an HTTPS Core origin in deployed environments. The local Docker host may use an internally trusted TLS certificate.
Issue separate credentials for each application and environment. Rotate or revoke credentials when ownership changes.
Validate tool arguments and user authorization in your own service. Do not rely on a policy rule as the only input check.
Payload privacy: arguments, policy decisions, and execution outcomes contribute to Verdict’s audit trail. Minimize sensitive data in tool arguments and snapshots; never send credentials, payment-card data, or secrets as action fields.
COMMON SETUP ISSUES
Use these checks to narrow down configuration, authentication, and policy issues.
Check that the client ID, secret, and private key belong to the same generated bundle and that the credential is active. Verify the SDK is using the correct Core base URL and that its DPoP proof is signed by the registered private key.
Confirm the SDK sends Authorization: DPoP with a current access token and generates a new proof for the exact HTTP method and URL. Avoid URL rewrites between the client and Core that alter the proof-bound target.
Review the application’s environment, tool name, matching scope, policy priority, CEL expressions, velocity limits, and kill-switch state. Start with a development credential and inspect the execution trace.
Verify that an authorized reviewer can access the escrow queue and resolve the pending action. The wait endpoint uses bounded long-poll requests; application and worker timeouts must account for human response time.
Use the Core origin reachable from the SDK process, not the console’s browser proxy path. In the supplied local setup this is typically https://verdict.local; make sure the local TLS certificate is trusted by the runtime.
The SDK is source-only and not published as an npm dependency. Include or build sdks/typescript/src within your Node.js project and resolve the import to that source or its compiled output.