Skip to main content

Security & Compliance

5 min read

GDPR/CCPA Compliance

Handle data export requests, right-to-erasure, consent management, and retention enforcement with a single API.


Basic Setup

import { createCompliance, createInMemoryComplianceStorage } from '@directive-run/ai';

const compliance = createCompliance({
  // In-memory storage for development (use a database adapter in production)
  storage: createInMemoryComplianceStorage(),

  // Define how long each category of data is kept
  retention: {
    name: 'default',
    defaultRetentionMs: 365 * 24 * 60 * 60 * 1000, // 1 year
    categoryRetention: {
      audit: 7 * 365 * 24 * 60 * 60 * 1000, // 7 years for audit logs (regulatory)
      sessions: 30 * 24 * 60 * 60 * 1000,    // 30 days for sessions
    },
  },
});

Data Export (GDPR Article 20)

Export all data for a subject:

// Export all data associated with a user (GDPR data portability)
const result = await compliance.exportData({
  subjectId: 'user-123',
  format: 'json',          // or 'csv'
  includeAudit: true,      // include audit trail entries
  includeDerived: false,   // exclude computed data
  categories: ['profile', 'orders'], // limit to specific categories
});

console.log(result.success);      // true
console.log(result.recordCount);  // 47
console.log(result.checksum);     // SHA-256 for integrity verification
console.log(result.data);         // JSON string of all records

Data Deletion (GDPR Article 17)

Delete or anonymize data for a subject:

// Erase a user's data (GDPR right to erasure)
const result = await compliance.deleteData({
  subjectId: 'user-123',
  scope: 'all',          // 'all' | 'facts' | 'audit' | 'specific'
  anonymize: false,       // set true to anonymize instead of hard delete
  reason: 'User requested account deletion',
});

console.log(result.success);          // true
console.log(result.recordsAffected);  // 47
console.log(result.certificate);      // DeletionCertificate (proof of deletion)

Every deletion produces a DeletionCertificate with a SHA-256 hash for compliance records:

// The certificate serves as auditable proof that deletion occurred
const cert = result.certificate;

console.log(cert.id);          // unique certificate ID
console.log(cert.type);        // 'hard' | 'soft' | 'anonymization'
console.log(cert.scope);       // what was deleted
console.log(cert.recordCount); // how many records were affected
console.log(cert.hash);        // SHA-256 hash for tamper detection

Track and enforce user consent:

// Record that a user opted in to marketing emails
await compliance.consent.grant('user-123', 'marketing', {
  source: 'signup_form',
  version: 'v2.1',
  expiresAt: Date.now() + 365 * 24 * 60 * 60 * 1000,
});

// Verify consent before processing (returns boolean)
const hasConsent = await compliance.consent.check('user-123', 'marketing');

// Honor a user's withdrawal of consent
await compliance.consent.revoke('user-123', 'marketing');

// Audit: see everything a user has consented to
const consents = await compliance.consent.getForSubject('user-123');

// Audit: find all users who opted in to a specific purpose
const marketingUsers = await compliance.consent.getForPurpose('marketing');

Retention Enforcement

Automatically delete data that exceeds retention periods:

const compliance = createCompliance({
  storage: myStorage,

  retention: {
    name: 'production',
    defaultRetentionMs: 365 * 24 * 60 * 60 * 1000,

    // Override retention for specific data categories
    categoryRetention: {
      sessions: 30 * 24 * 60 * 60 * 1000,
      logs: 90 * 24 * 60 * 60 * 1000,
    },

    // Hooks for logging or backup before data is purged
    onBeforeDelete: async ({ category, count }) => {
      console.log(`About to delete ${count} records from ${category}`);
    },
    onAfterDelete: ({ category, count }) => {
      console.log(`Deleted ${count} records from ${category}`);
    },
  },
});

// Delete all records that have exceeded their retention period
const deletedCount = await compliance.enforceRetention();

Custom Storage

Implement the ComplianceStorage interface to back compliance with any database:

// Implement this interface to connect compliance to your database
const storage: ComplianceStorage = {
  // Data export: fetch all records for a subject
  getSubjectData: async (subjectId, categories) => {
    return db.query('SELECT * FROM data WHERE subject_id = ?', [subjectId]);
  },

  // Hard deletion: permanently remove a subject's data
  deleteSubjectData: async (subjectId, categories) => {
    return db.delete('data', { subject_id: subjectId });
  },

  // Soft deletion: strip PII while keeping anonymized records
  anonymizeSubjectData: async (subjectId, categories) => {
    return db.update('data', { pii: null }, { subject_id: subjectId });
  },

  // Retention: find records older than the cutoff date
  getExpiredData: async (category, olderThan) => {
    return db.query('SELECT id, created_at FROM data WHERE category = ? AND created_at < ?', [category, olderThan]);
  },
  deleteByIds: async (ids) => {
    return db.delete('data', { id: ids });
  },

  // Consent management
  storeConsent: async (record) => {
    await db.insert('consents', record);
  },
  getConsent: async (subjectId, purpose) => {
    return db.findOne('consents', { subject_id: subjectId, purpose });
  },
  getConsentsBySubject: async (subjectId) => {
    return db.find('consents', { subject_id: subjectId });
  },
  getConsentsByPurpose: async (purpose) => {
    return db.find('consents', { purpose });
  },

  // Store proof of deletion for regulatory audits
  storeDeletionCertificate: async (cert) => {
    await db.insert('deletion_certificates', cert);
  },
};

Configuration

OptionTypeDefaultDescription
storageComplianceStorage– (required)Storage adapter for compliance data
retentionRetentionPolicyRetention policy configuration
consentPurposesstring[]Consent purposes to track
exportExpirationMsnumber24 hoursExpiration for export download links
auditOperationsbooleanAudit all compliance operations
eventsobjectCallbacks for export, delete, consent, and retention events

AI Integration

Block AI processing when consent is missing by wiring the consent guardrail into an orchestrator:

import { createAgentOrchestrator, createOpenAIRunner } from '@directive-run/ai';

// Block AI processing unless the user has granted the 'ai_processing' consent
const consentGuardrail = compliance.createConsentGuardrail('ai_processing');

const runner = createOpenAIRunner({ apiKey: process.env.OPENAI_API_KEY! });

// Consent is checked before every agent invocation
const orchestrator = createAgentOrchestrator({
  runner,
  guardrails: {
    input: [{ name: 'consent', fn: consentGuardrail }],
  },
});

See Guardrails for error handling, streaming guardrails, and the builder pattern.


Next Steps

Previous
Audit Trail

We care about your data. We'll never share your email.

Powered by Directive. This signup uses a Directive module with facts, derivations, constraints, and resolvers – zero useState, zero useEffect. Read how it works

Directive - Constraint-Driven State Management for TypeScript