Hash Chain Integrity
InTunnel uses a cryptographic hash chain to ensure audit log integrity. Each event is linked to its predecessor, creating an unbreakable chain of events.
How Hash Chains Work
Each audit event contains a hash of the previous event. The diagram below shows how a valid chain works and how tampering is detected:
Fig. 1 – Hash chain integrity - valid chain vs tampered chain showing broken links
Event Structure
Each audit event contains:
{
"event_id": "evt_abc123",
"event_type": "USER_LOGIN",
"timestamp": 1705312800,
"user_id": "user_456",
"ip_address": "192.168.1.1",
"details": {
"username": "john@example.com",
"success": true
},
"previous_hash": "a3f2b8c9d4e5...",
"event_hash": "b4c3d9e0f1a2..."
}Hash Computation
The event hash is computed from:
import hashlib
import json
def compute_event_hash(event):
data = (
event['event_id'] +
event['event_type'] +
str(event['timestamp']) +
event['user_id'] +
event['ip_address'] +
json.dumps(event['details'], sort_keys=True) +
event['previous_hash']
)
return hashlib.sha256(data.encode()).hexdigest()Tamper Detection
If Event 2 is Modified:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Event 1 │ │ Event 2* │ │ Event 3 │
├─────────────┤ ├─────────────┤ ├─────────────┤
│ prev: null │ X │ prev: H(E1) │ X │ prev: H(E2) │
│ data: {...} │◄─┬──│ data: FAKE │◄─┬──│ data: {...} │
│ hash: H(E1) │ │ │ hash: H(E2*)│ │ │ hash: H(E3) │
└─────────────┘ │ └─────────────┘ │ └─────────────┘
│ │
H(E2*) ≠ H(E2) H(E2) ≠ H(E2*)
▼ ▼
MISMATCH! CHAIN BROKEN!Detection:
- Recalculate H(E2) from Event 2* data
- Compare with stored hash - MISMATCH
- Event 3's
previous_hashdoesn't match - CHAIN BROKEN
Chain Verification
Full Chain Verification
Verifies every link in the chain:
curl -X POST https://intunnel.cloud/api/security/verify-chain \
-H "Cookie: session=YOUR_ADMIN_SESSION"Response (valid chain):
{
"valid": true,
"events_checked": 15432,
"verification_time_ms": 245
}Response (tampered chain):
{
"valid": false,
"events_checked": 8547,
"error": "Hash mismatch at event evt_abc789",
"expected_hash": "a3f2b8c9...",
"actual_hash": "d4e5f6a7..."
}Verification Algorithm
def verify_chain():
events = get_all_events_ordered_by_timestamp()
previous_hash = None
for event in events:
# Check link to previous
if event.previous_hash != previous_hash:
return False, f"Broken link at {event.event_id}"
# Verify event hash
computed_hash = compute_event_hash(event)
if computed_hash != event.event_hash:
return False, f"Hash mismatch at {event.event_id}"
previous_hash = event.event_hash
return True, f"Verified {len(events)} events"Benefits
| Benefit | Description |
|---|---|
| Sequential Integrity | Events must be in correct order |
| Tamper Evident | Any modification breaks the chain |
| Non-Repudiation | Events cannot be denied or removed |
| Simple Verification | Linear time verification O(n) |
| Append-Only | New events link to previous, old events are immutable |
Comparison: Hash Chain vs Merkle Tree
| Feature | Hash Chain | Merkle Tree |
|---|---|---|
| Verification | O(n) for full chain | O(log n) for single event |
| Use Case | Sequential integrity | Random access verification |
| Structure | Linear | Tree |
| InTunnel Use | Event linking | Snapshot integrity |
InTunnel uses both for comprehensive security:
- Hash chain ensures sequential integrity
- Merkle tree enables efficient single-event verification
Security Dashboard
Monitor chain integrity from the admin dashboard:
https://intunnel.cloud/admin/securityFeatures:
- One-click chain verification
- Visual integrity status
- Event count and latest hash
- Verification history
Important
Hash chain verification should be performed regularly. Any break in the chain indicates potential tampering and should be investigated immediately.