n8n-nodes-signatrust and sign every workflow decision.
View on npm
A Signatrust receipt is only as valuable as the moment it captures. This guide answers the single most important design question when adopting Signatrust: which AI decisions deserve a cryptographic receipt — and which don't.
“I'd split it by external effect. Tool-call receipts are useful, but the receipt I'd really inspect is the moment an agent can change a business object: actor, account/credential, approval, payload hash, target record, and final outcome. That's where audit stops being just model provenance.”— Ahmad Shakir, n8n Top Supporter · community feedback
Both approaches are supported by Signatrust today. Picking the right one depends on why you are sealing.
Prove how an agent reasoned: which tool it invoked, which data it retrieved, which model produced the final answer. Rich but verbose.
str.trace({ mode: 'every_tool_call' })
.step({ tool_name: 'search', … })
.step({ tool_name: 'db_lookup', … })
.step({ step_type: 'final_response', … })
Prove what changed in the real world: money moved, record modified, consent recorded, credit issued. Fewer receipts, higher signal, insurable.
business_event.str.sign({
decision: {
business_event: 'PAYMENT_EXECUTED',
type: 'wire_transfer',
output: transferResult,
risk_level: 'high',
},
})
Not every AI step is worth sealing. The moment worth sealing is the moment the agent stops being a "language model" and becomes an actor with external effect.
Agent receives task
│
▼
[Search Tool] ← internal reasoning
│
▼
[Database Lookup] ← internal reasoning
│
▼
[LLM says: "I will transfer $500"] ← NOT a business event yet
│
▼
[Bank API responds: Transfer completed · TXN-482913 · Status: Success]
│
▼
▲ SEAL RECEIPT HERE — business_event: PAYMENT_EXECUTED ▲
│
▼
Notify user · Update CRM · Log to accounting
Sealing after the external effect is what turns a Signatrust receipt into evidence an auditor, insurer, or regulator will actually accept. Anything before that point is intent, not action.
business_event taxonomy
Set decision.business_event to one of these values whenever a receipt
captures a real-world side-effect. This makes receipts filterable and reportable at scale
without constraining the free-form decision.type label.
| Category | Event | Typical use |
|---|---|---|
| Financial | PAYMENT_EXECUTED | Bank transfer, card charge, payout completed |
| Financial | REFUND_ISSUED | Money returned to a customer |
| Financial | CREDIT_DECISION | Loan approved / rejected / limit changed |
| Identity | USER_CREATED | New account provisioned by the agent |
| Identity | USER_MODIFIED | Role change, deactivation, permission grant |
| Identity | PII_ACCESSED | Agent read personally-identifiable data |
| Records | DOCUMENT_SIGNED | Contract, invoice, deliverable signed off |
| Records | RECORD_MODIFIED | Business object mutated in a system of record |
| Records | CONSENT_RECORDED | GDPR / HIPAA consent captured or updated |
| Governance | HUMAN_OVERRIDE | Human reviewer accepted or reversed an AI decision |
| High-risk (EU AI Act) | CLINICAL_DECISION | Triage, diagnosis, or treatment recommendation |
| High-risk (EU AI Act) | BENEFIT_DECISION | Government benefit or eligibility decision |
| High-risk (EU AI Act) | EMPLOYMENT_DECISION | Hiring, promotion, termination decision |
| Escape | CUSTOM | Anything else — describe in decision.type |
The taxonomy is intentionally small and stable. It mirrors EU AI Act Annex III high-risk categories plus the most common enterprise external effects. New values are added conservatively — existing ones will never be removed or renamed.
business_event.risk_level: 'high' and the relevant business_event.str.trace({ mode: 'every_tool_call' }) instead — cheaper storage tier, marked as provenance.import { Signatrust } from 'signatrust';
const str = new Signatrust({ apiKey: process.env.SIGNATRUST_API_KEY! });
await str.sign({
model: { provider: 'openai', name: 'gpt-4o' },
decision: {
business_event: 'PAYMENT_EXECUTED',
type: 'wire_transfer',
input: applicationJson,
output: transferResult, // hashed locally
risk_level: 'high',
human_review: true,
policies: ['eu-ai-act-high-risk'],
},
metadata: {
target_record: { type: 'invoice', id: 'INV-2026-0099' },
outcome: { status: 'completed', reference: 'TXN-482913' },
},
});
from signatrust import Signatrust
client = Signatrust(api_key=os.environ["SIGNATRUST_API_KEY"])
client.sign(
model={"provider": "openai", "name": "gpt-4o"},
decision={
"business_event": "PAYMENT_EXECUTED",
"type": "wire_transfer",
"input": application_json,
"output": transfer_result,
"risk_level": "high",
"human_review": True,
"policies": ["eu-ai-act-high-risk"],
},
metadata={
"target_record": {"type": "invoice", "id": "INV-2026-0099"},
"outcome": {"status": "completed", "reference": "TXN-482913"},
},
)
Open the Additional Fields section of the Signatrust node and pick a value from the Business Event dropdown. Combine with Receipt Mode = Final Decision Only to seal exactly one receipt per external effect.
Business Event → PAYMENT_EXECUTED Risk Level → High Human Review → true Policies → eu-ai-act-high-risk Receipt Mode → Final Decision Only
Register in under a minute, pick your first business_event, and issue your first verifiable receipt.