Cohere runtime authorization
Wrap Cohere tool use with Veto. Each governed tool call, including calls produced from retrieved documents, is evaluated before dispatch: allow, review, or deny, with an exportable decision record per governed decision.
Why Cohere needs guardrails
Cohere supports tool-augmented enterprise workflows. Its tool_use API returns a tool_plan alongside the tool_calls. The model explains what it intends to do, then names the calls. The plan is reasoning. The calls are executable side effects. The API does not enforce a boundary between them; your code does.
Cohere's RAG mode combines retrieved documents and tools in a single turn. Retrieved content can carry adversarial instructions that steer the tool plan. Without guardrails at tool_results time, poisoned documents drive real side effects.
The Cohere tool_plan describes intent in natural language. It is not an approval. The tool_calls run regardless.
Retrieved documents fed via the documents= parameter can contain instructions the model may follow when planning tool use.
Cohere is deployed for contract review, customer ops, and finance. Tool calls touch high-value records.
Before and after Veto
The left tab shows standard Cohere tool use. The model returns tool_calls; your code executes them and feeds tool_results back. The right tab adds Veto between the model's decision and the dispatch. Same agent, same tools, each governed call evaluated against policy first.
import os
import cohere
co = cohere.ClientV2()
tools = [
{
"type": "function",
"function": {
"name": "lookup_contract",
"description": "Read a customer contract from the legal datastore",
"parameters": {
"type": "object",
"properties": {
"contract_id": {"type": "string"},
},
"required": ["contract_id"],
},
},
},
{
"type": "function",
"function": {
"name": "amend_contract",
"description": "Apply an amendment to a customer contract",
"parameters": {
"type": "object",
"properties": {
"contract_id": {"type": "string"},
"clause": {"type": "string"},
"new_text": {"type": "string"},
},
"required": ["contract_id", "clause", "new_text"],
},
},
},
]
response = co.chat(
model=os.environ["COHERE_MODEL"],
messages=[{"role": "user", "content": user_message}],
tools=tools,
)
# Cohere Chat V2 returns tool_plan + tool_calls. Your code runs them.
# An adversarial customer email can steer amend_contract.
tool_results = []
for tc in response.message.tool_calls or []:
args = json.loads(tc.function.arguments)
result = execute_tool(tc.function.name, args)
tool_results.append({
"tool_call_id": tc.id,
"output": result,
})
# Feed results back into Cohere for the final response
final = co.chat(
model=os.environ["COHERE_MODEL"],
messages=[
*previous_messages,
response.message,
*[{"role": "tool", "tool_call_id": r["tool_call_id"], "content": r["output"]} for r in tool_results],
],
)Tool use with RAG
Cohere's combined RAG + tool-use mode widens the prompt-injection surface. Pass the retrieved document IDs into Veto's context so policies can audit which document drove which call.
import os
import cohere
import json
from veto_sdk import Veto
co = cohere.ClientV2()
veto = Veto(api_key=os.environ["VETO_API_KEY"])
# Cohere's RAG + tool use: retrieved documents AND tools in one turn.
# A poisoned document can instruct the model to call a destructive tool.
# Veto guards the tool calls so retrieved instructions cannot drive side effects.
response = co.chat(
model=os.environ["COHERE_MODEL"],
messages=[{"role": "user", "content": user_message}],
tools=tools,
documents=retrieved_docs,
)
for tc in response.message.tool_calls or []:
args = json.loads(tc.function.arguments)
decision = veto.guard(
tool=tc.function.name,
arguments=args,
context={"source": "rag", "doc_ids": [d.get("id") for d in retrieved_docs]},
)
if decision.decision != "allow":
continue
execute_tool(tc.function.name, args)Policy configuration
Encode guardrails in declarative YAML. The same policies cover Cohere on the Cohere API, on Azure, and on Bedrock: Veto guards the tool dispatch, not the inference endpoint.
rules:
- name: block_external_contract_amend
description: Amendments require an internal user
tool: amend_contract
when: "!context.user_id.startsWith('internal-')"
action: deny
message: "Contract amendments restricted to internal staff"
- name: approve_material_clause_changes
description: Material clauses need legal sign-off
tool: amend_contract
when: args.clause in ["indemnification", "liability_cap", "termination", "data_processing"]
action: require_approval
approvers: [legal-ops]
timeout: 4h
- name: cap_clause_length
description: Refuse unreasonably long replacement text
tool: amend_contract
when: args.new_text.length > 4000
action: deny
message: "Replacement clause exceeds 4,000 characters: submit manually"
- name: contract_lookup_allowlist
description: Customers can only read their own contracts
tool: lookup_contract
when: "!context.user_contracts.includes(args.contract_id)"
action: deny
message: "Contract not assigned to this user"How Veto fits
Install the SDK
pip install veto-sdk cohereDefine policies
Create veto/policies.yaml. Use the same tool name you registered in the Cohere tools schema.
Guard between tool_calls and tool_results
For each governed tool_call returned by Cohere, call veto.guard() before dispatching. Feed the outcome (or denial) into the next chat call as a tool_result.
Use cases
Contract operations
A Cohere-backed agent reviews and amends customer contracts. Restrict amendments to internal users, require legal approval on material clauses, cap replacement length.
Enterprise search and act
Cohere runs RAG patterns across internal knowledge bases. Check tool calls so retrieved documents cannot steer destructive actions.
Multi-tenant data access
Allowlist customer record access by tenant. A user's agent is limited to the contracts and tickets assigned to them: enforced at the governed tool boundary, independent of the model response.
Tool plan transparency
Pass The Cohere tool_plan into Veto's context. Policies can log the plan alongside the call. Decision records capture what the model said it would do and what it tried to run.
Frequently asked questions
Does Veto work with Cohere models that emit tool calls?
What about Cohere's RAG mode with retrieved documents?
Can I use Cohere on Azure or Bedrock with Veto?
Does the tool_plan get included in decision records?
Related integrations
Wrap one Cohere tool path and inspect the decision record.