Skip to main content
This guide provides instructions for System Administrators and Developers on how to use QWED’s compliance features for SOC 2 preparation, GDPR adherence, and audit trail management.

Audience

  • System Administrators: Use the API endpoints described below to manage compliance tasks.
  • Developers: Integrate these features into your applications using the QWED Python SDK.

1. SOC 2 preparation

QWED provides built-in tools to assist with SOC 2 Type II audits, specifically focusing on Security, Availability, and Processing Integrity.

SOC 2 report generator

Generate a JSON report containing security metrics, control statuses, and evidence summaries. API Endpoint:
GET /admin/compliance/report/soc2/{org_id}
Example Response:
{
  "report_type": "SOC 2 Type II - Security Controls",
  "period": {
    "start": "2023-01-01T00:00:00",
    "end": "2023-03-31T23:59:59"
  },
  "compliance_status": {
    "audit_trail_complete": "PASS",
    "access_logs_retained": "PASS"
  }
}

Audit trail verification

Verify the cryptographic integrity of your audit logs. This ensures that no logs have been tampered with since creation. Per-entry verification covers three checks:
  • hash_valid: the entry’s SHA-256 hash matches a recomputation of its canonical payload. For backwards compatibility, entries hashed before raw_llm_output was covered are also accepted against the legacy canonical form.
  • signature_valid: the entry’s HMAC-SHA256 signature is constant-time-equal to the expected signature.
  • chain_valid: the entry’s previous_hash correctly references the prior entry’s hash within the same organization. Genesis entries (the first entry for an organization) must have a null previous_hash; non-genesis entries must reference a non-empty prior hash.
Audit chains are isolated per organization. Hash linkage is verified only against prior entries belonging to the same organization_id, so cross-tenant activity cannot affect another organization’s chain validity.
If an entry’s stored result payload cannot be decoded as JSON, verify_log_entry fails closed with a SecurityError rather than reporting the entry as valid. Verify a Single Log Entry:
GET /admin/compliance/verify/{log_id}
Verify entire trail (Python SDK): The API verifies one entry at a time for performance. For complete log verification, use the Python SDK or a custom script that queries the database directly.
from qwed_new.core.audit_logger import AuditLogger, SecurityError

try:
    verifier = AuditLogger()
except SecurityError as exc:
    # Raised if QWED_AUDIT_SECRET_KEY is unset or persisted chain continuity
    # cannot be loaded. Do not silently fall back.
    raise

result = verifier.verify_audit_trail(organization_id=1)
if result["valid"]:
    print("Audit trail integrity confirmed.")
else:
    print(f"Integrity check failed: {result['errors']}")
AuditLogger() requires QWED_AUDIT_SECRET_KEY to be set in the environment, or the constructor must receive an explicit secret_key argument. Initialization fails closed otherwise.

Evidence collection

Export all verification logs and security events as a CSV file to provide to your auditor. API Endpoint:
GET /admin/compliance/export/csv?organization_id={org_id}

2. GDPR compliance

Data export (Article 15 - right of access)

QWED supports the Right of Access by allowing you to export all data associated with an organization or user. API Endpoint: Use the CSV export endpoint to retrieve all verification data.
GET /admin/compliance/export/csv?organization_id={org_id}

Data deletion (Article 17 - right to erasure)

Note: Currently, user deletion must be performed by an administrator directly in the database. A self-service deletion API is planned. To comply with a deletion request:
  1. Delete the User: Remove the user record from the database.
  2. Prune Logs: For full GDPR Article 17 compliance, ensure all verification logs associated with the user are also deleted or anonymized.
Manual Database Process (Example):
-- Delete User
DELETE FROM user WHERE id = {user_id};

-- Delete associated logs (if required by policy)
DELETE FROM verificationlog WHERE user_id = {user_id};
QWED does not have a built-in “Consent Management Platform” (CMP), but you can use the immutable audit log to track consent events. Implementing Consent Tracking: Log a specific “verification” event when a user grants consent. This creates a tamper-proof record.
# Example: Logging a consent event via the API
requests.post("/verify/fact", json={
    "claim": "User 123 granted consent for data processing",
    "context": "Consent Version 1.0, IP: 192.168.1.1",
    "provider": "system"
})
Note: This treats the consent record as a “fact” verification, securing it in the cryptographic ledger.

3. Audit trail setup

Enable cryptographic logging

Cryptographic logging is enabled by default, but you must configure the signing key before the audit logger will start. The audit logger fails closed when the signing key is missing or when chain continuity cannot be established.
  1. Set the signing key: Set QWED_AUDIT_SECRET_KEY to a secure, random string (at least 32 characters). The audit logger raises a SecurityError and refuses to initialize if this variable is not set.
    export QWED_AUDIT_SECRET_KEY="your-secure-production-key-here"
    
    There is no fallback or default key. If the variable is unset, the application will fail to start rather than silently writing audit entries with a predictable key.
  2. Secure storage: Store the key in a secrets manager (for example, AWS Secrets Manager or HashiCorp Vault) and inject it into the application environment.
  3. Rotation: Rotating the signing key invalidates the HMAC signatures on existing entries. Verify and archive the existing trail before rotating, then start a new trail with the new key.

Chain continuity across restarts

On startup, AuditLogger loads the most recent persisted entry hash and uses it as the new chain head. New entries are bound to the persisted hash rather than a fresh in-memory root, so restarts do not produce a discontinuous trail. If the in-memory chain head and the persisted chain head disagree at write time, log_verification raises a SecurityError instead of writing a misleading entry. Treat this as a tampering or replication-lag signal and investigate before restarting writes.

Per-organization chain isolation

Each organization has its own append-only hash chain. When verifying or appending entries, the logger:
  • Locks the chain head per organization to prevent concurrent appends from forking the chain.
  • Re-verifies the persisted chain head before appending a new entry and refuses to append if the head fails integrity checks.
  • Accepts both the current canonical payload (which covers raw_llm_output) and the legacy payload during verification, so historical entries written before that field was hashed remain verifiable.
  • Fails closed if a stored result payload is malformed JSON or if a chain entry is missing its entry_hash.

Verify log integrity

Regularly run the verification process (see “Audit trail verification” above) to detect database tampering. Verification now flags:
  • A genesis entry that references a non-null previous_hash.
  • A previous entry that is missing its hash.
  • A previous_hash that does not match the prior entry’s hash.
  • An entry whose recomputed hash or HMAC signature does not match the stored value.

Long-term storage

QWED uses the configured database (SQLite/PostgreSQL) for log storage. For high-volume compliance requirements:
  • Configure database backups to a WORM (Write Once, Read Many) compatible storage (e.g., AWS S3 Object Lock) for archival.

4. Compliance checklist

Use this checklist to prepare for an enterprise audit.
  • Audit Logs Verified: Run verify_audit_trail on all historical logs.
  • API Keys Rotated: Rotate any API keys older than 90 days.
  • SOC 2 Report Generated: Generate and review the latest SOC 2 report via API.
  • Secret Key Secured: Confirm QWED_AUDIT_SECRET_KEY is set to a production-grade value and stored in a secrets manager.
  • GDPR Export Tested: Verify that data export works for a sample organization.
  • Security Events Reviewed: Check the “Security Events” section of the SOC 2 report for any anomalies.
  • Rate Limiting Active: Confirm rate limits are enforced to prevent abuse (DoS protection).