Attestation-Based Log Integrity
One of the most powerful TEE capabilities is cryptographic proof of log integrity. Logs emitted inside a TEE can be signed with a key that only the TEE hardware can access — creating tamper-evident log records that prove the log came from a specific, attested code version. This is the foundation of regulatory-grade audit trails in TEE deployments.
How TEE Log Signing Works
1. TEE-Bound Signing Key
At attestation time, the TEE platform generates a signing key pair bound to the measured code. The private key never leaves the TEE hardware — it cannot be extracted by the host OS, hypervisor, or cloud provider.
2. Log Batch Signing
Before a batch of log records crosses the TEE boundary, the in-TEE log shipper computes a SHA-256 hash of the batch and signs it with the TEE-bound private key. The signature travels with the batch.
3. External Verification
Any party with the TEE attestation certificate (containing the public key) can verify that the log batch was produced by the specific attested code, and that the batch has not been tampered with in transit.
4. Tamper Evidence
If a log record is modified, inserted, or deleted after it leaves the TEE, the batch signature verification fails — proving tampering. The log chain can detect gaps in signed batch sequence numbers.
Log Signing Implementation Pattern
// TEE Log Signing — in-TEE component before OTel exporter
// This runs INSIDE the TEE; the signing key is TEE-hardware-bound
public class TeeLogBatchSigner
{
private readonly ECDsa _teeSigningKey; // Loaded from TEE key sealing
private readonly AttestationReport _attestationReport;
private long _batchSequence = 0;
public SignedLogBatch SignBatch(IReadOnlyList<LogRecord> records)
{
var sequence = Interlocked.Increment(ref _batchSequence);
// Canonical JSON serialization of the batch
var batchPayload = new
{
sequence = sequence,
timestamp_utc = DateTimeOffset.UtcNow.ToString("O"),
tee_measurement = _attestationReport.CodeMeasurement, // PCR values
record_count = records.Count,
records = records.Select(r => new {
timestamp = r.Timestamp,
level = r.LogLevel.ToString(),
message = r.Message, // Already sanitized before reaching this layer
attributes = r.Attributes
})
};
var payloadBytes = JsonSerializer.SerializeToUtf8Bytes(batchPayload);
var payloadHash = SHA256.HashData(payloadBytes);
var signature = _teeSigningKey.SignHash(payloadHash);
return new SignedLogBatch
{
Sequence = sequence,
PayloadBase64 = Convert.ToBase64String(payloadBytes),
SignatureBase64 = Convert.ToBase64String(signature),
AttestationCertThumbprint = _attestationReport.CertThumbprint
};
}
}
// The SignedLogBatch is what crosses the TEE boundary to the OTel Collector
// The OTel Collector stores it in Loki as a structured log entry
Log Integrity Verification Pattern
// Verification — runs OUTSIDE the TEE (auditor, compliance system)
// Uses the TEE attestation public key (from attestation certificate)
public class TeeLogVerifier
{
private readonly ECDsa _teePublicKey; // From TEE attestation certificate
public VerificationResult Verify(SignedLogBatch batch)
{
// 1. Decode payload
var payloadBytes = Convert.FromBase64String(batch.PayloadBase64);
var signature = Convert.FromBase64String(batch.SignatureBase64);
// 2. Verify signature against payload hash
var payloadHash = SHA256.HashData(payloadBytes);
var signatureValid = _teePublicKey.VerifyHash(payloadHash, signature);
if (!signatureValid)
return VerificationResult.TamperedOrInvalidSignature(batch.Sequence);
// 3. Deserialize and check TEE measurement
var batchPayload = JsonSerializer.Deserialize<LogBatchPayload>(payloadBytes);
if (batchPayload.TeeMeasurement != ExpectedCodeMeasurement)
return VerificationResult.UnexpectedCodeVersion(batchPayload.TeeMeasurement);
// 4. Check sequence continuity (detect dropped batches)
if (batchPayload.Sequence != _lastVerifiedSequence + 1)
return VerificationResult.SequenceGap(_lastVerifiedSequence, batchPayload.Sequence);
_lastVerifiedSequence = batchPayload.Sequence;
return VerificationResult.Valid(batchPayload.RecordCount);
}
}
Storing Signed Batches in Loki
# OTel Collector transforms signed batch into Loki log entries
# The signature is stored as a structured label for later audit queries
# Example Loki log entry for a signed TEE batch:
{
"stream": {
"job": "tee-processengine",
"tee_batch_seq": "42",
"tee_cert_thumbprint": "sha256:a1b2c3...",
"signature_valid": "true" # OTel Collector verifies before storing
},
"values": [
["1716825600000000000", "{\"level\":\"Information\",\"executionId\":\"abc-123\",\"nodeType\":\"calculation\",\"outcome\":\"completed\"}"],
["1716825601000000000", "{\"level\":\"Information\",\"executionId\":\"abc-123\",\"stepCount\":5,\"durationMs\":342}"]
]
}
# LogQL query to find log batches with invalid signatures (tampering alert):
{job="tee-processengine", signature_valid="false"}
# LogQL query to audit log continuity (detect sequence gaps):
{job="tee-processengine"} | json | tee_batch_seq > 0 | sort by (tee_batch_seq)
Attestation Report Structure
# AWS Nitro Enclave attestation document (simplified)
# This is what proves the log signing key belongs to a specific code version
{
"module_id": "nitro-enclave-prod-us-east-1-001",
"timestamp": 1716825600,
"digest": "SHA384",
"pcrs": {
"0": "sha384:a1b2c3...f9", # PCR[0]: enclave image file measurement
"1": "sha384:b2c3d4...fa", # PCR[1]: Linux kernel + bootstrap
"2": "sha384:c3d4e5...fb", # PCR[2]: application code measurement
"4": "sha384:d4e5f6...fc" # PCR[4]: IAM role of parent instance
},
"public_key": "base64:MFkwEwYH...", # TEE-bound signing key public key
"certificate": "base64:MIICpD...", # Certificate chain for verification
"user_data": "sha256:deploy-v1.2.3" # Optional: deployment version tag
}
# Compliance use:
# - Store attestation report alongside log batches
# - PCR[2] value = "which version of BizFirstGO produced these logs"
# - If PCR[2] changes, a new code version was deployed (expected after upgrade)
# - If PCR[2] changes unexpectedly, potential unauthorized code modification
For financial institutions using BizFirstGO in a TEE for regulated computations (credit scoring, fraud detection), attestation-signed logs provide court-admissible evidence that a specific, unmodified version of the computation software produced a specific audit record at a specific time. No other observability pattern provides this level of proof. Plan for this capability from the first TEE design review.