Blockchain Audit Trails¶
Kiket anchors audit logs to the Polygon blockchain for tamper-proof verification. This provides cryptographic proof that your audit records have not been modified since creation.
How It Works¶
- Content Hashing: Every audit record is SHA-256 hashed at creation time
- Merkle Trees: Hourly, hashes are collected into Merkle trees
- Blockchain Anchoring: Merkle roots are submitted to Polygon
- Verification: Anyone can verify a record's inclusion without accessing your data
┌─────────────────────────────────────────────────────────┐
│ Merkle Root │
│ (anchored to Polygon) │
├───────────────────────┬─────────────────────────────────┤
│ Hash AB │ Hash CD │
├───────────┬───────────┼───────────┬─────────────────────┤
│ Hash A │ Hash B │ Hash C │ Hash D │
│ Record 1 │ Record 2 │ Record 3 │ Record 4 │
└───────────┴───────────┴───────────┴─────────────────────┘
Benefits¶
- Tamper-Proof: Blockchain immutability prevents record modification
- Independent Verification: Auditors verify proofs without Kiket access
- Public Transparency: Transaction history viewable on PolygonScan
- Compliance Ready: SOC 2, ISO 27001, and GDPR compliant audit trails
Verification Methods¶
Public Verification Page¶
Visit kiket.dev/verify to verify any proof without logging in.
API Verification¶
curl -X POST https://api.kiket.dev/v1/audit/verify \
-H "Content-Type: application/json" \
-d '{
"content_hash": "0x7f83b165...",
"merkle_root": "0x3a4e8c2b...",
"proof": ["0x1234...", "0x5678..."],
"leaf_index": 127,
"tx_hash": "0x9a8b7c6d..."
}'
CLI Verification¶
# Verify a proof file
kiket audit verify proof.json
# Verify locally (offline)
kiket audit verify proof.json --local
# Get proof for an AuditLog record (default)
kiket audit proof 12345 --format=file --output=proof.json
# Get proof for an AIAuditLog record
kiket audit proof 12345 --type=AIAuditLog --format=file --output=proof.json
SDK Verification¶
from kiket_sdk.audit import AuditClient
audit = AuditClient(client)
# Get proof for an AuditLog record
proof = await audit.get_proof(record_id=12345)
# Get proof for an AIAuditLog record
ai_proof = await audit.get_proof(record_id=67890, record_type="AIAuditLog")
# Verify via API
result = await audit.verify(proof)
print(f"Verified: {result.verified}")
# Verify locally (offline)
valid = AuditClient.verify_proof_locally(
content_hash=proof.content_hash,
proof_path=proof.proof,
leaf_index=proof.leaf_index,
merkle_root=proof.merkle_root
)
import { AuditClient } from '@kiket/sdk';
const audit = new AuditClient(httpClient);
// Get proof for an AuditLog record
const proof = await audit.getProof(12345);
// Get proof for an AIAuditLog record
const aiProof = await audit.getProof(67890, 'AIAuditLog');
// Verify via API
const result = await audit.verify(proof);
console.log(`Verified: ${result.verified}`);
// Verify locally (offline)
const valid = AuditClient.verifyProofLocally(
proof.content_hash,
proof.proof,
proof.leaf_index,
proof.merkle_root
);
audit = KiketSdk::AuditClient.new(client)
# Get proof for an AuditLog record
proof = audit.get_proof(12345)
# Get proof for an AIAuditLog record
ai_proof = audit.get_proof(67890, record_type: "AIAuditLog")
# Verify via API
result = audit.verify(proof)
puts "Verified: #{result.verified}"
# Verify locally (offline)
valid = KiketSdk::AuditClient.verify_proof_locally(
content_hash: proof.content_hash,
proof_path: proof.proof,
leaf_index: proof.leaf_index,
merkle_root: proof.merkle_root
)
Viewing Anchors¶
List Anchors¶
# List recent anchors
kiket audit anchors
# Filter by status
kiket audit anchors --status=confirmed
# JSON output
kiket audit anchors --format=json
Check Audit Status¶
Output:
Blockchain Audit Status
========================================
Recent Anchors (last 5):
Confirmed: 5
Pending: 0
Submitted: 0
Failed: 0
Latest Anchor:
Merkle Root: 0x7f83b1657ff1fc53b92dc18...
Records: 847
Status: confirmed
Network: polygon_mainnet
Explorer: https://polygonscan.com/tx/0x...
Network Configuration¶
| Environment | Network | Chain ID | Explorer |
|---|---|---|---|
| Development | Polygon Amoy (testnet) | 80002 | amoy.polygonscan.com |
| Production | Polygon Mainnet | 137 | polygonscan.com |
Pricing¶
Blockchain anchoring is included in Starter and above plans:
| Plan | Monthly Anchors | Overage |
|---|---|---|
| Free | Not included | - |
| Starter | 100 | $0.10/anchor |
| Professional | 1,000 | $0.08/anchor |
| Enterprise | Unlimited | - |
Smart Contract¶
The AuditAnchor contract is deployed at:
- Polygon Amoy:
0x...(testnet) - Polygon Mainnet:
0x...(production)
Contract source is available in the kiket repository.
FAQ¶
How often are records anchored?¶
Records are batched and anchored every hour. Each anchor can contain up to 10,000 records.
Can I verify without Kiket access?¶
Yes. The proof contains all information needed for independent verification. Use the public verification page or verify locally with the SDK.
What happens if anchoring fails?¶
Failed anchors are retried automatically. If an anchor fails 3 times, it's marked as failed and an alert is sent.
Is my data visible on the blockchain?¶
No. Only cryptographic hashes (Merkle roots) are stored on-chain. The actual audit content remains private in Kiket.
Which audit events are included?¶
Three types of records are anchored to the blockchain:
AuditLog (general audit trail): - Role changes - User additions/removals - AI data scope updates - AI assignment actions - Secret operations
AIAuditLog (AI operation audit trail): - LLM invocations (task generation, code review, etc.) - Token usage and costs - Model responses and metadata - Developer Aide Suite operations
NotificationAuditLog (notification dispatch audit trail): - Email notification dispatches - Slack notification dispatches - Webhook notification dispatches - Links to source audit logs for transitive verification
All three models compute SHA-256 content hashes at creation time and are included in the hourly Merkle tree anchoring.
Notification Verification¶
Kiket includes blockchain verification links in notification emails, allowing recipients to independently verify that a notification was legitimately sent by the platform.
How It Works¶
- When an email notification is sent, a
NotificationAuditLogis created - The audit log includes a reference to the source action that triggered the notification
- A verification URL is included in the email footer
- Recipients can click the link to verify the notification's authenticity
Email Footer¶
All blockchain-verified emails include a footer:
Transitive Verification¶
Notification audit logs reference their source audit log, enabling transitive verification:
- Verify the notification was sent (NotificationAuditLog)
- Click through to verify the action that triggered it (AuditLog)
This proves not only that the notification was sent, but also that the underlying action actually occurred.
Verification Page¶
Visit the verification URL to see:
- Verified: Record is anchored to blockchain with block number and transaction hash
- Pending: Record exists but not yet anchored (anchoring happens hourly)
- Not Found: No record matches the provided hash
Extension Webhook Payloads¶
Extension webhooks automatically receive audit context when available:
{
"event": "workflow.after_transition",
"issue": { ... },
"audit_context": {
"audit_log_hash": "0x7f83b1657ff1fc53b92dc18...",
"verification_url": "https://kiket.dev/verify/0x7f83b165...",
"blockchain_status": "pending"
}
}
Extensions can include this verification URL in their own communications to provide end-to-end verification.