TRAILBASE|DOCUMENTATION

Automate Compliance Checks

Set up continuous compliance monitoring for SOC 2, HIPAA, and GDPR. Generate audit-ready reports and catch violations before your next security review.

Overview

Manual compliance audits are time-consuming and error-prone. Trailbase automates compliance validation by continuously checking your audit logs against framework requirements. This guide shows you how to set up automated checks, interpret results, and generate reports.

Supported Frameworks

SOC 2 Type II

Trust Service Criteria for security, availability, and confidentiality. Focus on audit controls and access logging.

HIPAA

Health Insurance Portability and Accountability Act requirements for protected health information (PHI) audit trails.

GDPR

European data protection regulation requirements for processing records and breach detection capabilities.

Running Compliance Checks

On-Demand Check

Run a compliance check manually to validate your current state:

import { TrailbaseClient } from '@trailbase/sdk';

const trailbase = new TrailbaseClient({
  apiKey: process.env.TRAILBASE_API_KEY!,
  tenantId: process.env.TRAILBASE_TENANT_ID!,
});

// Run SOC 2 compliance check
const results = await trailbase.runComplianceCheck('SOC2');

console.log(`Compliance Status: ${results.passed ? 'PASS' : 'FAIL'}`);
console.log(`Score: ${results.score}/100`);

// Check individual controls
results.checks.forEach((check) => {
  console.log(`${check.passed ? '✓' : '✗'} ${check.control}: ${check.message}`);
});

Example Response

{
  "framework": "SOC2",
  "passed": true,
  "score": 100,
  "timestamp": "2026-02-10T14:32:15Z",
  "checks": [
    {
      "control": "CC6.1",
      "name": "System Operations Monitoring",
      "passed": true,
      "message": "Event ingestion is active. Last event: 2 minutes ago",
      "details": {
        "last_event_at": "2026-02-10T14:30:00Z",
        "events_24h": 12847
      }
    },
    {
      "control": "CC6.2",
      "name": "Audit Log Retention",
      "passed": true,
      "message": "Retention policy: 730 days (exceeds 365 day requirement)",
      "details": {
        "retention_days": 730,
        "required_days": 365,
        "oldest_event": "2024-02-10T00:00:00Z"
      }
    },
    {
      "control": "CC6.3",
      "name": "Access Logging",
      "passed": true,
      "message": "All events include actor identification",
      "details": {
        "events_checked": 1000,
        "events_with_actor": 1000,
        "coverage": "100%"
      }
    },
    {
      "control": "CC7.2",
      "name": "Hash Chain Integrity",
      "passed": true,
      "message": "Hash chain is valid. No gaps detected.",
      "details": {
        "verified_events": 128503,
        "last_hash": "4f2a8c1d9b3e7a5f2c8d1e9b4a7c3f1d"
      }
    }
  ]
}

Scheduled Checks

Run compliance checks on a schedule using a cron job or serverless function:

// app/api/cron/compliance/route.ts
import { NextRequest } from 'next/server';
import { trailbase } from '@/lib/trailbase';
import { db } from '@/lib/db';

export async function GET(req: NextRequest) {
  // Verify cron secret
  const authHeader = req.headers.get('authorization');
  if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
    return new Response('Unauthorized', { status: 401 });
  }

  const frameworks = ['SOC2', 'HIPAA', 'GDPR'];

  for (const framework of frameworks) {
    try {
      const results = await trailbase.runComplianceCheck(framework);

      // Store results
      await db.complianceCheck.create({
        data: {
          framework,
          passed: results.passed,
          score: results.score,
          results: results.checks,
          timestamp: new Date(),
        },
      });

      // Alert if failed
      if (!results.passed) {
        await sendAlert({
          severity: 'high',
          title: `${framework} Compliance Check Failed`,
          message: `Score: ${results.score}/100. Review failed controls.`,
          details: results.checks.filter((c) => !c.passed),
        });
      }
    } catch (error) {
      console.error(`Failed to run ${framework} check:`, error);
    }
  }

  return new Response(JSON.stringify({ success: true }));
}

// Configure as a Vercel Cron or AWS EventBridge scheduled event:
// Schedule: 0 0 * * * (daily at midnight)

Framework-Specific Requirements

SOC 2 Type II

SOC 2 requires continuous monitoring and evidence of controls over a period of time:

ControlRequirementTrailbase Validation
CC6.1Monitor system operationsEvents ingested in last 24 hours
CC6.2Retain audit logs 365+ daysRetention policy check
CC6.3Log access to protected resourcesActor identification coverage
CC7.2Detect unauthorized changesHash chain integrity verification

HIPAA

HIPAA requires specific controls for Protected Health Information (PHI):

// Example: Ensure PHI access is logged
const results = await trailbase.runComplianceCheck('HIPAA');

// HIPAA-specific checks:
// - §164.312(b): Audit controls implemented
// - §164.308(a)(1)(ii)(D): Regular review of system activity
// - §164.312(c)(2): Actor identification in all events

if (!results.passed) {
  const failedControls = results.checks
    .filter((c) => !c.passed)
    .map((c) => c.control);

  console.error('HIPAA violations detected:', failedControls);

  // Generate remediation report
  await generateHIPAARemediationReport(failedControls);
}

GDPR

GDPR emphasizes data subject rights and breach detection:

// GDPR Article 30: Records of Processing Activities
const results = await trailbase.runComplianceCheck('GDPR');

// GDPR-specific checks:
// - Article 30: Audit trail of all data processing
// - Article 32: Technical measures for data security
// - Article 33: Breach detection capability

// Example: Generate GDPR Article 30 report
const processingRecords = await trailbase.searchEvents({
  action: 'data.*',
  start_time: '2025-01-01T00:00:00Z',
  end_time: '2026-01-01T00:00:00Z',
});

await exportProcessingRecordsReport(processingRecords);

Generating Reports

Compliance Report PDF

Generate a comprehensive PDF report for auditors:

import { TrailbaseClient } from '@trailbase/sdk';

async function generateComplianceReport(framework: string) {
  // Run compliance check
  const results = await trailbase.runComplianceCheck(framework);

  // Fetch supporting evidence
  const recentEvents = await trailbase.searchEvents({
    limit: 100,
    order: 'desc',
  });

  const integrityCheck = await trailbase.verifyChain();

  // Generate PDF (using a library like pdfkit or puppeteer)
  const pdf = await generatePDF({
    title: `${framework} Compliance Report`,
    date: new Date().toISOString(),
    summary: {
      passed: results.passed,
      score: results.score,
      framework: results.framework,
    },
    controls: results.checks,
    evidence: {
      total_events: recentEvents.total,
      sample_events: recentEvents.events.slice(0, 10),
      integrity: integrityCheck,
    },
  });

  return pdf;
}

// Usage in API route
export async function GET(req: Request) {
  const url = new URL(req.url);
  const framework = url.searchParams.get('framework') || 'SOC2';

  const pdfBuffer = await generateComplianceReport(framework);

  return new Response(pdfBuffer, {
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': `attachment; filename="${framework}-compliance-report.pdf"`,
    },
  });
}

CSV Export for Analysis

// Export compliance check history to CSV
async function exportComplianceHistory(framework: string) {
  const checks = await db.complianceCheck.findMany({
    where: { framework },
    orderBy: { timestamp: 'desc' },
    take: 90, // Last 90 days
  });

  const csv = [
    ['Date', 'Framework', 'Passed', 'Score', 'Failed Controls'].join(','),
    ...checks.map((check) => [
      check.timestamp.toISOString(),
      check.framework,
      check.passed ? 'YES' : 'NO',
      check.score,
      check.results
        .filter((r: any) => !r.passed)
        .map((r: any) => r.control)
        .join('; '),
    ].join(',')),
  ].join('\n');

  return csv;
}

Continuous Monitoring

Set Up Alerts for Violations

// Create alert rule for compliance failures
await trailbase.createAlertRule({
  name: 'Compliance Check Failed',
  type: 'compliance',
  condition: {
    framework: 'any', // Or specific: 'SOC2', 'HIPAA', 'GDPR'
    passed: false,
  },
  severity: 'critical',
  webhookIds: ['webhook_security_team'],
  cooldownMin: 60, // Don't spam if multiple checks fail
});

Dashboard Widget

Display compliance status in your admin dashboard:

// components/ComplianceStatusWidget.tsx
'use client';

import { useEffect, useState } from 'react';

export function ComplianceStatusWidget() {
  const [status, setStatus] = useState<Record<string, any>>({});

  useEffect(() => {
    async function fetchStatus() {
      const frameworks = ['SOC2', 'HIPAA', 'GDPR'];
      const results: Record<string, any> = {};

      for (const framework of frameworks) {
        const res = await fetch(`/api/compliance/status?framework=${framework}`);
        results[framework] = await res.json();
      }

      setStatus(results);
    }

    fetchStatus();
    const interval = setInterval(fetchStatus, 300000); // Refresh every 5 min
    return () => clearInterval(interval);
  }, []);

  return (
    <div style={{
      background: 'var(--color-primary)',
      border: '1px solid var(--color-border)',
      borderRadius: '12px',
      padding: '1.5rem',
    }}>
      <h3>Compliance Status</h3>
      {Object.entries(status).map(([framework, data]: [string, any]) => (
        <div key={framework} style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          padding: '1rem 0',
          borderBottom: '1px solid var(--color-border)',
        }}>
          <span style={{ fontWeight: 600 }}>{framework}</span>
          <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
            <span style={{ fontSize: '0.875rem', color: 'var(--color-muted)' }}>
              Score: {data.score}/100
            </span>
            <span style={{
              padding: '0.25rem 0.75rem',
              borderRadius: '12px',
              fontSize: '0.75rem',
              fontWeight: 700,
              background: data.passed ? '#22c55e' : '#ef4444',
              color: 'white',
            }}>
              {data.passed ? 'PASS' : 'FAIL'}
            </span>
          </div>
        </div>
      ))}
    </div>
  );
}

Remediation Workflow

Handle Failed Checks

async function handleFailedComplianceCheck(results: any) {
  const failedControls = results.checks.filter((c: any) => !c.passed);

  for (const control of failedControls) {
    // Create remediation task
    await db.remediationTask.create({
      data: {
        framework: results.framework,
        control: control.control,
        description: control.message,
        severity: getSeverity(control.control),
        status: 'open',
        assignedTo: 'security-team',
        dueDate: addDays(new Date(), 7), // Fix within 7 days
      },
    });

    // Notify responsible team
    await sendNotification({
      to: 'security-team@example.com',
      subject: `Action Required: ${results.framework} Control ${control.control} Failed`,
      body: `
        Control: ${control.name}
        Issue: ${control.message}
        Details: ${JSON.stringify(control.details, null, 2)}

        Please review and remediate within 7 days.
      `,
    });
  }
}

function getSeverity(control: string): 'low' | 'medium' | 'high' | 'critical' {
  // Hash chain integrity is critical
  if (control === 'CC7.2') return 'critical';

  // Retention and access logging are high
  if (['CC6.2', 'CC6.3'].includes(control)) return 'high';

  return 'medium';
}

Best Practices

  • Run checks daily: Continuous monitoring catches issues early
  • Archive check results: Auditors need to see historical compliance evidence
  • Automate remediation: Create tasks automatically for failed controls
  • Test before audits: Run checks weekly leading up to your SOC 2 audit
  • Document exceptions: If a control fails for a known reason, document it

Audit Preparation

Generate a 90-day compliance report before your audit. This shows auditors that your controls have been operating effectively over the observation period.

Next Steps

Set up real-time alerts to catch compliance violations as they happen.

Edit this page on GitHub