Provenance
Every cintegrity execution tracks where data came from and where it went. This enables security monitoring, compliance reporting, and incident investigation.
Audit Log
Each execution produces a log like this:
{
"session": "cd94fb6da87edd03",
"status": "completed",
"calls": [
{
"id": "read_inbox#uz9d",
"tool": "read_inbox",
"output": {
"emails": [
{ "id": "1", "sender": "cfo@company.com", "subject": "Q4 Results" }
]
}
},
{
"id": "send_email#39rt",
"tool": "send_email",
"input": { "to": "boss@company.com", "body": "From CFO: Q4 Results..." },
"inputLineage": {
"body": [
"read_inbox#uz9d.emails[id=1].sender",
"read_inbox#uz9d.emails[id=1].subject"
]
}
}
]
}The inputLineage field shows exactly where each input came from.
Reading Lineage
The format is {tool_call_id}.{path}:
read_inbox#uz9d.emails[id=1].sender
│ │ │ └── field
│ │ └──────── record
│ └─────────────── path
└────────────────────────────── tool callSingle source:
{ "inputLineage": { "user_id": ["get_user#abc1.id"] } }Multiple sources:
{
"inputLineage": {
"body": [
"read_inbox#uz9d.emails[id=1].subject",
"read_inbox#uz9d.emails[id=2].subject"
]
}
}Literal value (no lineage):
{ "input": { "to": "boss@company.com" }, "inputLineage": {} }Detecting Exfiltration
Check if sensitive data reached an output:
def detect_exfiltration(audit_log, sensitive_tools, output_tools):
alerts = []
for call in audit_log["calls"]:
if call["tool"] not in output_tools:
continue
for field, origins in call.get("inputLineage", {}).items():
for origin in origins:
if origin.split("#")[0] in sensitive_tools:
alerts.append({"call": call["id"], "source": origin})
return alerts
# Usage
alerts = detect_exfiltration(
audit_log,
sensitive_tools={"read_secrets", "get_credentials"},
output_tools={"send_email", "upload_file"}
)Storage
Logs are saved automatically:
logs/
├── audit_cd94fb6da87edd03_20251215_055025.json
└── ...They can be forwarded to SIEM systems (Splunk, Elastic), data lakes, or compliance platforms.