Fintech Agent Example
A complete example of a financial agent gated with ShadowAudit: the agent can read account data freely, requires approval for transfers over $1,000, and is hard-blocked from transfers over $50,000.
Policy
# policies/fintech_agent.yaml
deny:
- capability: payments.transfer
amount_gt: 50000
- capability: payments.transfer
environment: production
user_role: unverified
require_approval:
- capability: payments.transfer
amount_gt: 1000
- capability: payments.refund
amount_gt: 500
- capability: account.close
allow:
- capability: account.read
- capability: transaction.read
- capability: payments.transfer
amount_lte: 1000
- capability: payments.refund
amount_lte: 500
approval_timeout_seconds: 1800
Tools
from shadowaudit import ShadowAuditTool
class AccountReadTool:
name = "account_read"
def run(self, account_id: str) -> dict:
return db.get_account(account_id)
class TransferTool:
name = "transfer"
def run(self, from_account: str, to_account: str, amount: float) -> dict:
return payments_api.transfer(from_account, to_account, amount)
safe_read = ShadowAuditTool(
tool=AccountReadTool(),
agent_id="fintech-agent",
capability="account.read",
policy_path="policies/fintech_agent.yaml"
)
safe_transfer = ShadowAuditTool(
tool=TransferTool(),
agent_id="fintech-agent",
capability="payments.transfer",
policy_path="policies/fintech_agent.yaml"
)
Agent
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o")
tools = [safe_read, safe_transfer]
prompt = ChatPromptTemplate.from_messages([
("system", "You are a financial assistant. Help users manage their accounts."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_openai_tools_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
Invocation
# Small transfer — allowed immediately
executor.invoke({
"input": "Transfer $500 from account A to account B"
})
# Large transfer — paused for approval
executor.invoke({
"input": "Transfer $5,000 from account A to account B"
})
# Agent receives: "Action pending approval (request_id: a1b2c3d4)"
# Very large transfer — hard blocked
executor.invoke({
"input": "Transfer $100,000 from account A to account B"
})
# Agent receives: AgentActionBlocked: payments.transfer denied (amount_gt=50000)
Approve the pending transfer
shadowaudit pending-approvals
shadowaudit approve a1b2c3d4
Audit log
shadowaudit logs --audit-log audit.db --json