Data Processing Agreements for ChatGPT Apps: GDPR Vendor Guide
Data Processing Agreements (DPAs) form the legal foundation of GDPR-compliant vendor relationships for ChatGPT applications. Under Article 28 of the GDPR, controllers must only engage processors that provide sufficient guarantees to implement appropriate technical and organizational measures. For ChatGPT apps processing personal data through third-party services—OpenAI APIs, cloud hosting, analytics platforms, CRM systems—DPAs establish contractual safeguards that protect data subjects' rights. This comprehensive guide demonstrates how to implement DPA workflows, manage controller-processor relationships, deploy Standard Contractual Clauses for international transfers, and automate vendor compliance tracking.
Whether you're building customer-facing ChatGPT assistants that integrate with Salesforce, deploying internal AI tools that process employee data, or creating multi-tenant SaaS platforms with dozens of sub-processors, understanding DPA requirements prevents regulatory penalties and builds customer trust. We'll cover GDPR Article 28 obligations, essential DPA components, international transfer mechanisms, vendor due diligence processes, and production-ready TypeScript implementations that automate contract generation, compliance monitoring, and audit trails. Learn how to establish ChatGPT app data governance frameworks while maintaining vendor accountability through enforceable contractual protections.
GDPR Article 28: Controller-Processor Relationships
Article 28 of the GDPR establishes mandatory requirements for controller-processor relationships, creating a hierarchical accountability framework where controllers remain ultimately responsible for compliance even when delegating processing activities. When your ChatGPT app (as controller) engages OpenAI, cloud providers, or third-party APIs (as processors), you must execute written DPAs that satisfy specific legal criteria. The controller determines "purposes and means" of processing—what data is collected, why, and how—while processors act solely on documented instructions without autonomous decision-making authority.
Core Processor Obligations Under Article 28
Processing Instructions (Art 28.3a): Processors must process personal data only on documented instructions from the controller, unless required by EU or Member State law. Your DPA must explicitly define permitted processing activities, data categories, retention periods, and security measures. For ChatGPT apps, this means specifying that OpenAI may only use conversation data for providing API services, not for model training without explicit consent.
Confidentiality (Art 28.3b): Processors must ensure that persons authorized to process personal data commit to confidentiality or are under appropriate statutory confidentiality obligations. Implement employee NDAs, security clearances, and role-based access controls that restrict data access to authorized personnel.
Security Measures (Art 28.3c): Processors must implement appropriate technical and organizational measures as required by Article 32, including pseudonymization, encryption, resilience, and regular testing. Reference your ChatGPT security compliance framework in the DPA to demonstrate concrete safeguards.
Sub-Processor Authorization (Art 28.2-4): Processors may only engage sub-processors with prior specific or general written authorization from the controller. Your DPA must grant approval mechanisms (pre-approved lists or case-by-case consent) and require equivalent contractual protections for sub-processors through "flow-down" clauses.
Data Subject Rights Assistance (Art 28.3e): Processors must assist controllers in fulfilling data subject access requests, rectification, erasure, portability, and objection rights. Define SLAs for response times (e.g., 72 hours for DSAR assistance) and technical interfaces for automated data retrieval.
Deletion/Return of Data (Art 28.3g): After termination of services, processors must delete or return all personal data and delete existing copies unless EU/Member State law requires storage. Implement ChatGPT data retention policies with automated deletion workflows and certification processes.
Audit Rights (Art 28.3h): Processors must make available to controllers all information necessary to demonstrate compliance and allow for audits/inspections conducted by the controller or authorized auditors. Establish annual audit schedules, SOC 2 Type II certification requirements, and penetration testing protocols.
Controller Responsibilities
While processors bear operational obligations, controllers remain accountable for:
Vendor Selection: Conducting due diligence to verify processors provide "sufficient guarantees" of GDPR compliance through certifications (ISO 27001, SOC 2), security audits, incident response capabilities, and track records.
Instruction Documentation: Maintaining comprehensive records of processing instructions, approved purposes, data categories, and authorized sub-processors in your data processing register.
Supervisory Authority Cooperation: Ensuring DPAs enable cooperation with supervisory authorities during investigations, including processor obligations to provide documentation, audit access, and breach notifications.
Liability Allocation: Understanding that controllers remain liable to data subjects for processor failures under Article 82, though controllers may seek indemnification from processors for processor-caused damages.
DPA Components: Essential Contractual Terms
Effective DPAs balance legal protection with operational clarity through standardized components that address GDPR requirements, commercial terms, and technical specifications. While Article 28 mandates minimum content, comprehensive DPAs extend beyond regulatory baselines to establish governance frameworks, escalation procedures, and performance metrics.
1. Scope and Subject Matter
Processing Purpose: Explicitly define why processing occurs: "Processor will process Customer Personal Data solely to provide the ChatGPT API Services described in the Master Service Agreement, including natural language understanding, response generation, and conversation history storage."
Data Categories: Enumerate specific personal data types: "Customer names, email addresses, job titles, conversation content, usage metadata, IP addresses, device identifiers, and such other personal data as Customer may submit through the ChatGPT App interface."
Data Subject Categories: Identify affected individuals: "End-users of Customer's ChatGPT application, including Customer's employees, contractors, customers, and website visitors."
Processing Activities: List technical operations: "Collection, recording, organization, structuring, storage, retrieval, use, disclosure by transmission, erasure, and automated decision-making using machine learning models."
2. Duration and Termination
Term: "This DPA commences on the Effective Date and continues until termination of the Master Service Agreement or until all Personal Data has been deleted or returned."
Data Return/Deletion: "Within 30 days of termination, Processor shall, at Controller's election, return all Personal Data to Controller in machine-readable CSV/JSON format or securely delete all Personal Data using cryptographic erasure methods. Processor shall certify deletion in writing within 45 days."
Survival Clauses: "Confidentiality, indemnification, liability limitations, and audit rights shall survive termination for three years."
3. Security Measures (Article 32 Reference)
Reference detailed technical and organizational measures in annexes:
Encryption: "All Personal Data shall be encrypted in transit using TLS 1.3+ and at rest using AES-256 encryption with customer-managed keys where feasible."
Access Controls: "Role-based access controls, multi-factor authentication for administrative access, least-privilege principles, and annual access reviews."
Incident Response: "Processor maintains a Security Incident Response Plan with 24-hour breach detection, 72-hour breach notification to Controller, and forensic investigation capabilities."
Business Continuity: "RTO 4 hours, RPO 1 hour, quarterly disaster recovery testing, geographically distributed backups."
4. Sub-Processor Management
General Authorization Model: "Controller grants Processor general authorization to engage sub-processors listed in Annex B, subject to 30-day advance written notice of additions or replacements. Controller may object to new sub-processors within 15 days, and if objections cannot be resolved, Controller may terminate affected services without penalty."
Flow-Down Requirements: "Processor shall impose data protection obligations on sub-processors that are at least as protective as those in this DPA, including written contracts meeting Article 28 requirements."
Liability Chain: "Processor remains fully liable to Controller for sub-processor performance. Controller is not required to pursue claims against sub-processors before seeking remedies from Processor."
5. Data Subject Rights Assistance
DSAR Support: "Processor shall, within 72 hours of Controller's request, provide technical assistance to fulfill data subject access requests, including providing copies of Personal Data in structured, commonly used, machine-readable formats."
Automated Interfaces: "Processor provides API endpoints for automated data retrieval, pseudonymization, and deletion to facilitate Controller's compliance with Articles 15-22."
Rectification/Erasure: "Controller may rectify or erase Personal Data through Processor's administrative interface. Processor shall implement changes within 24 hours and propagate to all sub-processors within 72 hours."
6. Audit and Inspection Rights
Annual Audits: "Controller may conduct on-site or remote audits annually with 30 days' notice during business hours, at Controller's expense."
Third-Party Certifications: "Processor shall maintain ISO 27001 and SOC 2 Type II certifications and provide reports annually."
Questionnaire Process: "Processor shall complete Controller's security questionnaires within 30 days and participate in vendor risk assessments."
Standard Contractual Clauses: International Transfer Mechanisms
When ChatGPT apps transfer personal data from the EEA to third countries lacking adequacy decisions (like the United States post-Schrems II), Standard Contractual Clauses (SCCs) provide legally recognized transfer mechanisms under Article 46 GDPR. The European Commission adopted modernized SCCs in June 2021 (Commission Implementing Decision 2021/914), replacing previous versions with enhanced protections following the Schrems II judgment.
SCC Module Selection
The 2021 SCCs comprise four modular configurations based on transfer direction:
Module One: Controller-to-Controller transfers (e.g., sharing customer lists with US-based marketing platform)
Module Two: Controller-to-Processor transfers (most common for ChatGPT apps engaging US cloud providers)
Module Three: Processor-to-Processor transfers (sub-processor relationships)
Module Four: Processor-to-Controller transfers (e.g., data analytics provider returning insights)
For ChatGPT applications using OpenAI's API (headquartered in US), you typically execute Module Two (Controller-to-Processor) SCCs where your organization (EEA controller) transfers user conversation data to OpenAI (US processor). These SCCs impose mandatory obligations including encryption, access controls, transparency about government access requests, and data subject rights support.
Transfer Impact Assessments (TIAs)
Schrems II requires controllers to assess whether third-country laws improperly interfere with SCC protections, particularly regarding government surveillance. Before executing SCCs:
1. Identify Applicable Laws: Research data access laws in the destination country (US: FISA 702, EO 12333, CLOUD Act).
2. Assess Interference Risk: Evaluate whether laws permit disproportionate surveillance without adequate redress mechanisms.
3. Implement Supplementary Measures: Where risks exist, deploy additional safeguards:
- End-to-end encryption with EU-controlled keys
- Pseudonymization before transfer
- Data minimization (transfer only necessary data)
- Contractual transparency about government requests
4. Document Assessment: Maintain written TIA records demonstrating due diligence and ongoing monitoring.
UK IDTA and Addendum
Post-Brexit, UK GDPR requires separate transfer mechanisms. Controllers have two options:
UK International Data Transfer Agreement (IDTA): Standalone UK contract approved March 2022, functionally equivalent to EU SCCs but tailored to UK law.
UK Addendum to EU SCCs: Supplement EU SCCs with UK-specific terms, allowing use of single contractual framework for EEA and UK transfers.
Most organizations choose the UK Addendum approach to minimize administrative overhead. The Addendum modifies EU SCCs by substituting references to GDPR with UK GDPR, replacing European Commission with UK ICO, and addressing post-Brexit jurisdictional complexities.
SCC Implementation Workflow
/**
* Standard Contractual Clauses Manager
* Automates SCC selection, TIA tracking, and UK Addendum management
* GDPR Article 46 compliance for international data transfers
*/
import { z } from 'zod';
// Transfer type enumeration
enum TransferType {
CONTROLLER_TO_CONTROLLER = 'C2C',
CONTROLLER_TO_PROCESSOR = 'C2P',
PROCESSOR_TO_PROCESSOR = 'P2P',
PROCESSOR_TO_CONTROLLER = 'P2C'
}
// Destination country risk levels
enum RiskLevel {
LOW = 'low', // Adequacy decision exists
MEDIUM = 'medium', // SCCs + basic measures sufficient
HIGH = 'high', // Requires supplementary measures
CRITICAL = 'critical' // Transfer not recommended
}
// SCC Configuration Schema
const SCCConfigSchema = z.object({
transferId: z.string().uuid(),
dataExporter: z.object({
name: z.string(),
country: z.string().length(2), // ISO 3166-1 alpha-2
role: z.enum(['controller', 'processor']),
contactEmail: z.string().email()
}),
dataImporter: z.object({
name: z.string(),
country: z.string().length(2),
role: z.enum(['controller', 'processor']),
contactEmail: z.string().email()
}),
transferType: z.nativeEnum(TransferType),
dataCategories: z.array(z.string()).min(1),
dataSubjects: z.array(z.string()).min(1),
processingPurpose: z.string().min(20),
retentionPeriod: z.string(),
requiresUKAddendum: z.boolean(),
signedDate: z.string().datetime().optional(),
expiryDate: z.string().datetime().optional()
});
// Transfer Impact Assessment Schema
const TIASchema = z.object({
tiaId: z.string().uuid(),
transferId: z.string().uuid(),
assessmentDate: z.string().datetime(),
assessor: z.string(),
destinationCountry: z.string().length(2),
riskLevel: z.nativeEnum(RiskLevel),
// Legal framework analysis
surveillanceLaws: z.array(z.object({
lawName: z.string(),
description: z.string(),
riskRating: z.number().min(1).max(10)
})),
// Supplementary measures
supplementaryMeasures: z.array(z.object({
measureType: z.enum([
'encryption_e2e',
'pseudonymization',
'data_minimization',
'key_management_eu',
'split_processing',
'multi_party_computation'
]),
description: z.string(),
implementationStatus: z.enum(['planned', 'in_progress', 'implemented'])
})),
// Risk mitigation assessment
residualRisk: z.enum(['acceptable', 'manageable', 'unacceptable']),
transferApproved: z.boolean(),
reviewDate: z.string().datetime(),
notes: z.string().optional()
});
type SCCConfig = z.infer<typeof SCCConfigSchema>;
type TransferImpactAssessment = z.infer<typeof TIASchema>;
class SCCManager {
private sccs: Map<string, SCCConfig> = new Map();
private tias: Map<string, TransferImpactAssessment> = new Map();
// Country adequacy decisions (as of 2026)
private adequacyDecisions: Set<string> = new Set([
'AD', 'AR', 'CA', 'CH', 'FO', 'GG', 'IL', 'IM', 'JP',
'JE', 'NZ', 'KR', 'GB', 'UY' // Andorra, Argentina, Canada, Switzerland, etc.
]);
// High-risk surveillance law countries
private highRiskCountries: Set<string> = new Set([
'US', 'CN', 'RU', 'IN'
]);
/**
* Determine required SCC module based on transfer direction
*/
determineSCCModule(exporterRole: string, importerRole: string): TransferType {
if (exporterRole === 'controller' && importerRole === 'controller') {
return TransferType.CONTROLLER_TO_CONTROLLER;
} else if (exporterRole === 'controller' && importerRole === 'processor') {
return TransferType.CONTROLLER_TO_PROCESSOR;
} else if (exporterRole === 'processor' && importerRole === 'processor') {
return TransferType.PROCESSOR_TO_PROCESSOR;
} else {
return TransferType.PROCESSOR_TO_CONTROLLER;
}
}
/**
* Assess whether SCCs are required for transfer
*/
requiresSCCs(
exporterCountry: string,
importerCountry: string
): { required: boolean; reason: string } {
// No SCCs needed for intra-EEA transfers
if (this.isEEA(exporterCountry) && this.isEEA(importerCountry)) {
return { required: false, reason: 'Intra-EEA transfer' };
}
// No SCCs needed if adequacy decision exists
if (this.isEEA(exporterCountry) && this.adequacyDecisions.has(importerCountry)) {
return {
required: false,
reason: `Adequacy decision for ${importerCountry}`
};
}
// SCCs required for EEA to non-adequate third country
if (this.isEEA(exporterCountry) && !this.adequacyDecisions.has(importerCountry)) {
return {
required: true,
reason: `No adequacy decision for ${importerCountry}`
};
}
return { required: false, reason: 'Non-EEA transfer' };
}
/**
* Create new SCC configuration
*/
async createSCC(config: Omit<SCCConfig, 'transferId'>): Promise<string> {
const transferId = crypto.randomUUID();
const sccConfig = SCCConfigSchema.parse({ ...config, transferId });
// Validate SCC requirement
const sccCheck = this.requiresSCCs(
sccConfig.dataExporter.country,
sccConfig.dataImporter.country
);
if (!sccCheck.required) {
throw new Error(`SCCs not required: ${sccCheck.reason}`);
}
// Auto-detect transfer type
sccConfig.transferType = this.determineSCCModule(
sccConfig.dataExporter.role,
sccConfig.dataImporter.role
);
this.sccs.set(transferId, sccConfig);
// Trigger TIA creation for high-risk countries
if (this.highRiskCountries.has(sccConfig.dataImporter.country)) {
await this.createTIA(transferId);
}
return transferId;
}
/**
* Create Transfer Impact Assessment
*/
async createTIA(transferId: string): Promise<string> {
const scc = this.sccs.get(transferId);
if (!scc) throw new Error('Transfer not found');
const tiaId = crypto.randomUUID();
const riskLevel = this.assessCountryRisk(scc.dataImporter.country);
const tia: TransferImpactAssessment = {
tiaId,
transferId,
assessmentDate: new Date().toISOString(),
assessor: 'DPO',
destinationCountry: scc.dataImporter.country,
riskLevel,
surveillanceLaws: this.getSurveillanceLaws(scc.dataImporter.country),
supplementaryMeasures: this.recommendSupplementaryMeasures(riskLevel),
residualRisk: this.calculateResidualRisk(riskLevel),
transferApproved: false,
reviewDate: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString()
};
this.tias.set(tiaId, tia);
return tiaId;
}
/**
* Assess country-specific privacy risks
*/
private assessCountryRisk(country: string): RiskLevel {
if (this.adequacyDecisions.has(country)) return RiskLevel.LOW;
if (this.highRiskCountries.has(country)) return RiskLevel.HIGH;
return RiskLevel.MEDIUM;
}
/**
* Get applicable surveillance laws for country
*/
private getSurveillanceLaws(country: string) {
const laws: { [key: string]: any[] } = {
US: [
{
lawName: 'FISA Section 702',
description: 'Permits NSA collection of non-US persons\' communications',
riskRating: 8
},
{
lawName: 'Executive Order 12333',
description: 'Authorizes intelligence collection outside US territory',
riskRating: 7
},
{
lawName: 'CLOUD Act',
description: 'Requires US providers to disclose data regardless of location',
riskRating: 6
}
],
CN: [
{
lawName: 'National Intelligence Law',
description: 'Requires all organizations to support intelligence work',
riskRating: 9
}
]
};
return laws[country] || [];
}
/**
* Recommend supplementary measures based on risk
*/
private recommendSupplementaryMeasures(risk: RiskLevel) {
const measures = [];
if (risk === RiskLevel.HIGH || risk === RiskLevel.CRITICAL) {
measures.push({
measureType: 'encryption_e2e' as const,
description: 'End-to-end encryption with EU-controlled keys',
implementationStatus: 'planned' as const
});
measures.push({
measureType: 'pseudonymization' as const,
description: 'Pseudonymize identifiers before transfer',
implementationStatus: 'planned' as const
});
}
measures.push({
measureType: 'data_minimization' as const,
description: 'Transfer only strictly necessary data',
implementationStatus: 'planned' as const
});
return measures;
}
/**
* Calculate residual risk after supplementary measures
*/
private calculateResidualRisk(baseRisk: RiskLevel): 'acceptable' | 'manageable' | 'unacceptable' {
if (baseRisk === RiskLevel.CRITICAL) return 'unacceptable';
if (baseRisk === RiskLevel.HIGH) return 'manageable';
return 'acceptable';
}
/**
* Generate SCC contract document
*/
generateSCCDocument(transferId: string): string {
const scc = this.sccs.get(transferId);
if (!scc) throw new Error('Transfer not found');
return `
# STANDARD CONTRACTUAL CLAUSES
## Commission Implementing Decision (EU) 2021/914
### MODULE ${scc.transferType === TransferType.CONTROLLER_TO_PROCESSOR ? 'TWO' : 'ONE'}
${scc.transferType === TransferType.CONTROLLER_TO_PROCESSOR ?
'Transfer controller to processor' : 'Transfer controller to controller'}
**Date:** ${new Date().toLocaleDateString('en-GB')}
**Data Exporter:** ${scc.dataExporter.name} (${scc.dataExporter.country})
**Data Importer:** ${scc.dataImporter.name} (${scc.dataImporter.country})
---
## SECTION I: PARTIES
**Data exporter:**
- Name: ${scc.dataExporter.name}
- Address: [INSERT ADDRESS]
- Contact: ${scc.dataExporter.contactEmail}
- Role: ${scc.dataExporter.role}
**Data importer:**
- Name: ${scc.dataImporter.name}
- Address: [INSERT ADDRESS]
- Contact: ${scc.dataImporter.contactEmail}
- Role: ${scc.dataImporter.role}
---
## SECTION II: DESCRIPTION OF TRANSFER
**Categories of data subjects:** ${scc.dataSubjects.join(', ')}
**Categories of personal data:** ${scc.dataCategories.join(', ')}
**Processing purpose:** ${scc.processingPurpose}
**Retention period:** ${scc.retentionPeriod}
---
## SECTION III: COMPETENT SUPERVISORY AUTHORITY
The competent supervisory authority is: [DATA EXPORTER'S SUPERVISORY AUTHORITY]
---
${scc.requiresUKAddendum ? this.generateUKAddendum(scc) : ''}
`.trim();
}
/**
* Generate UK IDTA Addendum
*/
private generateUKAddendum(scc: SCCConfig): string {
return `
## UK INTERNATIONAL DATA TRANSFER ADDENDUM
This Addendum supplements the EU Standard Contractual Clauses above.
**Addendum Version:** B.1.0 (March 2022)
The Parties agree that:
1. This Addendum incorporates the Approved EU SCCs
2. Part 1 Table definitions apply:
- UK GDPR replaces references to "Regulation (EU) 2016/679"
- ICO replaces "competent supervisory authority"
3. Part 2 Mandatory Clauses apply without modification
4. Annex 1A-1C contain details from Section II above
**Effective Date:** ${new Date().toLocaleDateString('en-GB')}
`.trim();
}
/**
* Check if country is in EEA
*/
private isEEA(country: string): boolean {
const eeaCountries = new Set([
'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'IS', 'LI', 'NO'
]);
return eeaCountries.has(country);
}
/**
* Get SCC statistics
*/
getStatistics() {
const byType = Array.from(this.sccs.values()).reduce((acc, scc) => {
acc[scc.transferType] = (acc[scc.transferType] || 0) + 1;
return acc;
}, {} as Record<string, number>);
const byRisk = Array.from(this.tias.values()).reduce((acc, tia) => {
acc[tia.riskLevel] = (acc[tia.riskLevel] || 0) + 1;
return acc;
}, {} as Record<string, number>);
return {
totalSCCs: this.sccs.size,
totalTIAs: this.tias.size,
byTransferType: byType,
byRiskLevel: byRisk,
pendingApprovals: Array.from(this.tias.values())
.filter(t => !t.transferApproved).length
};
}
}
// Usage Example
const sccManager = new SCCManager();
// Create SCC for OpenAI API transfer
const openAITransfer = await sccManager.createSCC({
dataExporter: {
name: 'ChatGPT App Controller Ltd',
country: 'DE',
role: 'controller',
contactEmail: 'dpo@example.com'
},
dataImporter: {
name: 'OpenAI LLC',
country: 'US',
role: 'processor',
contactEmail: 'privacy@openai.com'
},
dataCategories: ['Name', 'Email', 'Conversation content', 'Usage metadata'],
dataSubjects: ['End-users', 'Customers'],
processingPurpose: 'Provide AI-powered conversational interface using OpenAI GPT-4 API',
retentionPeriod: '12 months from last interaction',
requiresUKAddendum: true
});
console.log('SCC created:', openAITransfer);
console.log(sccManager.generateSCCDocument(openAITransfer));
This 170-line implementation automates SCC selection, TIA workflows, and UK Addendum generation, ensuring GDPR international transfer compliance for ChatGPT applications.
Vendor Due Diligence and Management
Selecting GDPR-compliant processors requires systematic due diligence that evaluates technical security, organizational governance, contractual commitments, and incident response capabilities. Effective vendor management extends beyond initial assessment to ongoing monitoring, periodic audits, and relationship termination protocols.
Pre-Engagement Due Diligence
1. Security Certifications: Verify third-party attestations demonstrating compliance with recognized security standards. Require ISO 27001 (information security management), SOC 2 Type II (operational controls), and industry-specific certifications like HITRUST (healthcare), PCI DSS (payments), or FedRAMP (government).
2. Data Processing Questionnaires: Distribute standardized questionnaires covering:
- Data residency and storage locations
- Encryption methods (transit and rest)
- Access control mechanisms
- Sub-processor lists and locations
- Breach notification procedures
- Data retention and deletion processes
- Employee background check policies
3. Contractual Review: Scrutinize vendor agreements for:
- GDPR Article 28 compliance language
- Limitation of liability caps (ensure sufficient coverage for GDPR fines)
- Data ownership provisions (customer retains ownership)
- Termination assistance commitments
- Audit rights without unreasonable restrictions
4. Financial Stability: Assess vendor viability to ensure continuity of service and long-term compliance support through credit ratings, funding rounds, and market position analysis.
5. Incident History: Research publicly disclosed breaches, regulatory actions, and litigation to identify patterns of non-compliance or security failures.
Vendor Registry Implementation
/**
* Vendor Registry and Due Diligence Tracker
* Centralizes processor management, certification tracking, and audit scheduling
* GDPR Article 28 vendor accountability framework
*/
import { z } from 'zod';
// Vendor risk rating
enum VendorRisk {
LOW = 'low', // ISO 27001 + SOC 2, no incidents, <5% data
MEDIUM = 'medium', // Partial certifications, minor incidents, 5-25% data
HIGH = 'high', // No certifications, major incidents, >25% data
CRITICAL = 'critical' // Direct processor of sensitive categories
}
// Processing scope
enum ProcessingScope {
MINIMAL = 'minimal', // <1,000 records, non-sensitive
MODERATE = 'moderate', // 1K-100K records, basic personal data
SUBSTANTIAL = 'substantial', // 100K-1M records, includes special categories
EXTENSIVE = 'extensive' // >1M records, core business process
}
const VendorSchema = z.object({
vendorId: z.string().uuid(),
name: z.string(),
website: z.string().url(),
primaryContact: z.object({
name: z.string(),
email: z.string().email(),
role: z.string()
}),
// Processing details
processingScope: z.nativeEnum(ProcessingScope),
dataCategories: z.array(z.string()),
processingPurpose: z.string(),
dataLocation: z.array(z.string()), // ISO country codes
// Compliance status
certifications: z.array(z.object({
type: z.enum(['ISO27001', 'SOC2_TYPE2', 'HITRUST', 'PCI_DSS', 'FedRAMP']),
issueDate: z.string().datetime(),
expiryDate: z.string().datetime(),
documentUrl: z.string().url().optional()
})),
// DPA status
dpaStatus: z.enum(['not_required', 'pending', 'executed', 'expired']),
dpaExecutionDate: z.string().datetime().optional(),
dpaReviewDate: z.string().datetime().optional(),
// SCC/TIA status
sccRequired: z.boolean(),
sccId: z.string().uuid().optional(),
tiaCompleted: z.boolean().default(false),
// Risk assessment
riskRating: z.nativeEnum(VendorRisk),
lastRiskAssessment: z.string().datetime(),
nextReviewDate: z.string().datetime(),
// Audit tracking
lastAuditDate: z.string().datetime().optional(),
nextAuditDate: z.string().datetime().optional(),
auditFindings: z.array(z.object({
date: z.string().datetime(),
severity: z.enum(['low', 'medium', 'high', 'critical']),
finding: z.string(),
remediation: z.string(),
status: z.enum(['open', 'in_progress', 'resolved'])
})).default([]),
// Sub-processors
subProcessors: z.array(z.object({
name: z.string(),
purpose: z.string(),
location: z.string()
})).default([]),
status: z.enum(['active', 'under_review', 'suspended', 'terminated']),
addedDate: z.string().datetime(),
lastModified: z.string().datetime()
});
type Vendor = z.infer<typeof VendorSchema>;
class VendorRegistry {
private vendors: Map<string, Vendor> = new Map();
/**
* Register new vendor
*/
async addVendor(
vendorData: Omit<Vendor, 'vendorId' | 'addedDate' | 'lastModified'>
): Promise<string> {
const vendorId = crypto.randomUUID();
const now = new Date().toISOString();
const vendor = VendorSchema.parse({
...vendorData,
vendorId,
addedDate: now,
lastModified: now
});
// Auto-calculate next review date based on risk
vendor.nextReviewDate = this.calculateReviewDate(vendor.riskRating);
// Check if international transfer requires SCC
if (this.requiresInternationalTransfer(vendor.dataLocation)) {
vendor.sccRequired = true;
}
this.vendors.set(vendorId, vendor);
return vendorId;
}
/**
* Update vendor information
*/
async updateVendor(
vendorId: string,
updates: Partial<Vendor>
): Promise<void> {
const vendor = this.vendors.get(vendorId);
if (!vendor) throw new Error('Vendor not found');
const updated = {
...vendor,
...updates,
lastModified: new Date().toISOString()
};
this.vendors.set(vendorId, VendorSchema.parse(updated));
}
/**
* Get vendors requiring action
*/
getActionRequired(): {
expiredDPAs: Vendor[];
expiredCertifications: Vendor[];
overdueAudits: Vendor[];
overdueReviews: Vendor[];
pendingSCCs: Vendor[];
} {
const now = new Date();
const vendors = Array.from(this.vendors.values());
return {
expiredDPAs: vendors.filter(v =>
v.dpaReviewDate && new Date(v.dpaReviewDate) < now
),
expiredCertifications: vendors.filter(v =>
v.certifications.some(c => new Date(c.expiryDate) < now)
),
overdueAudits: vendors.filter(v =>
v.nextAuditDate && new Date(v.nextAuditDate) < now
),
overdueReviews: vendors.filter(v =>
new Date(v.nextReviewDate) < now
),
pendingSCCs: vendors.filter(v =>
v.sccRequired && !v.sccId
)
};
}
/**
* Calculate next review date based on risk
*/
private calculateReviewDate(risk: VendorRisk): string {
const months = {
[VendorRisk.LOW]: 24,
[VendorRisk.MEDIUM]: 12,
[VendorRisk.HIGH]: 6,
[VendorRisk.CRITICAL]: 3
};
const reviewDate = new Date();
reviewDate.setMonth(reviewDate.getMonth() + months[risk]);
return reviewDate.toISOString();
}
/**
* Check if vendor requires international transfer mechanisms
*/
private requiresInternationalTransfer(locations: string[]): boolean {
const eeaCountries = new Set([
'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'IS', 'LI', 'NO'
]);
return locations.some(loc => !eeaCountries.has(loc));
}
/**
* Generate vendor risk report
*/
generateRiskReport(): {
totalVendors: number;
byRisk: Record<VendorRisk, number>;
byScope: Record<ProcessingScope, number>;
highRiskVendors: Array<{
name: string;
risk: VendorRisk;
issues: string[];
}>;
} {
const vendors = Array.from(this.vendors.values());
const byRisk = vendors.reduce((acc, v) => {
acc[v.riskRating] = (acc[v.riskRating] || 0) + 1;
return acc;
}, {} as Record<VendorRisk, number>);
const byScope = vendors.reduce((acc, v) => {
acc[v.processingScope] = (acc[v.processingScope] || 0) + 1;
return acc;
}, {} as Record<ProcessingScope, number>);
const highRiskVendors = vendors
.filter(v => v.riskRating === VendorRisk.HIGH || v.riskRating === VendorRisk.CRITICAL)
.map(v => ({
name: v.name,
risk: v.riskRating,
issues: this.identifyVendorIssues(v)
}));
return {
totalVendors: vendors.length,
byRisk,
byScope,
highRiskVendors
};
}
/**
* Identify compliance issues for vendor
*/
private identifyVendorIssues(vendor: Vendor): string[] {
const issues: string[] = [];
const now = new Date();
if (vendor.dpaStatus !== 'executed') {
issues.push('DPA not executed');
}
if (vendor.dpaReviewDate && new Date(vendor.dpaReviewDate) < now) {
issues.push('DPA expired');
}
if (vendor.certifications.some(c => new Date(c.expiryDate) < now)) {
issues.push('Expired certifications');
}
if (vendor.sccRequired && !vendor.sccId) {
issues.push('SCC not executed');
}
if (vendor.sccRequired && !vendor.tiaCompleted) {
issues.push('TIA not completed');
}
if (vendor.auditFindings.some(f => f.status === 'open' && f.severity === 'critical')) {
issues.push('Open critical audit findings');
}
return issues;
}
}
// Usage example
const registry = new VendorRegistry();
await registry.addVendor({
name: 'OpenAI',
website: 'https://openai.com',
primaryContact: {
name: 'Privacy Team',
email: 'privacy@openai.com',
role: 'Data Protection'
},
processingScope: ProcessingScope.EXTENSIVE,
dataCategories: ['Conversation content', 'User metadata', 'Usage analytics'],
processingPurpose: 'Provide GPT-4 API for conversational AI',
dataLocation: ['US'],
certifications: [
{
type: 'SOC2_TYPE2',
issueDate: '2024-06-01T00:00:00Z',
expiryDate: '2026-06-01T00:00:00Z'
}
],
dpaStatus: 'executed',
dpaExecutionDate: '2024-01-15T00:00:00Z',
dpaReviewDate: '2026-01-15T00:00:00Z',
sccRequired: true,
tiaCompleted: true,
riskRating: VendorRisk.MEDIUM,
lastRiskAssessment: new Date().toISOString(),
nextReviewDate: new Date().toISOString(),
status: 'active'
});
const actionItems = registry.getActionRequired();
console.log('Vendors requiring action:', actionItems);
This vendor registry provides centralized processor oversight with automated compliance tracking across 160+ lines.
DPA Automation: Templates and E-Signature Integration
Manual DPA execution creates operational bottlenecks when onboarding dozens of processors for ChatGPT apps with complex vendor ecosystems. Automation through template generation, workflow orchestration, and electronic signature integration accelerates contracting while maintaining legal validity and audit trails.
DPA Template Generator
/**
* DPA Template Generator
* Generates customized Article 28 DPAs from structured inputs
* Supports multiple jurisdictions and industry-specific clauses
*/
interface DPATemplateConfig {
controller: {
legalName: string;
jurisdiction: string;
registrationNumber: string;
address: string;
dpoContact: string;
};
processor: {
legalName: string;
jurisdiction: string;
registrationNumber: string;
address: string;
dpoContact: string;
};
processingDetails: {
purpose: string;
dataCategories: string[];
dataSubjects: string[];
duration: string;
retentionPeriod: string;
};
securityMeasures: {
encryptionInTransit: string;
encryptionAtRest: string;
accessControls: string;
backupFrequency: string;
incidentNotificationSLA: string;
};
subProcessors: Array<{
name: string;
purpose: string;
location: string;
}>;
auditFrequency: string;
governingLaw: string;
internationalTransfer: {
required: boolean;
mechanism?: 'SCCs' | 'BCRs' | 'adequacy';
sccModule?: string;
};
}
class DPAGenerator {
/**
* Generate complete DPA document
*/
generateDPA(config: DPATemplateConfig): string {
return `
# DATA PROCESSING AGREEMENT
**This Data Processing Agreement** ("DPA") is entered into as of ${new Date().toLocaleDateString('en-GB')} between:
**CONTROLLER:**
${config.controller.legalName}
Registration Number: ${config.controller.registrationNumber}
Address: ${config.controller.address}
Data Protection Officer: ${config.controller.dpoContact}
**PROCESSOR:**
${config.processor.legalName}
Registration Number: ${config.processor.registrationNumber}
Address: ${config.processor.address}
Data Protection Officer: ${config.processor.dpoContact}
---
## 1. DEFINITIONS AND INTERPRETATION
1.1 **Capitalized terms** used in this DPA shall have the meanings set forth in this DPA or, if not defined herein, in the General Data Protection Regulation (EU) 2016/679 ("GDPR").
1.2 **References** to Articles are to articles of the GDPR unless otherwise specified.
---
## 2. SCOPE AND PURPOSE OF PROCESSING
2.1 **Subject Matter**: Processor shall process Personal Data on behalf of Controller solely for the following purpose: ${config.processingDetails.purpose}
2.2 **Duration**: This DPA shall commence on the Effective Date and continue for ${config.processingDetails.duration}, unless terminated earlier in accordance with Section 10.
2.3 **Nature of Processing**: The processing activities include collection, recording, organization, structuring, storage, retrieval, use, disclosure by transmission, erasure, and destruction.
2.4 **Categories of Data Subjects**: ${config.processingDetails.dataSubjects.join(', ')}
2.5 **Categories of Personal Data**: ${config.processingDetails.dataCategories.join(', ')}
---
## 3. PROCESSOR OBLIGATIONS (Article 28)
3.1 **Processing Instructions** (Art 28.3a): Processor shall process Personal Data only on documented instructions from Controller, unless required to do so by Union or Member State law. Processor shall immediately inform Controller if it becomes aware that Controller's instructions infringe the GDPR or other data protection provisions.
3.2 **Confidentiality** (Art 28.3b): Processor shall ensure that persons authorized to process Personal Data have committed themselves to confidentiality or are under an appropriate statutory obligation of confidentiality.
3.3 **Security Measures** (Art 28.3c): Processor shall implement appropriate technical and organizational measures as set forth in Annex A, including:
- **Encryption in Transit**: ${config.securityMeasures.encryptionInTransit}
- **Encryption at Rest**: ${config.securityMeasures.encryptionAtRest}
- **Access Controls**: ${config.securityMeasures.accessControls}
- **Backup Procedures**: ${config.securityMeasures.backupFrequency}
3.4 **Sub-Processing** (Art 28.2): Controller grants Processor general authorization to engage sub-processors listed in Annex B. Processor shall:
a) Provide Controller with at least 30 days' prior written notice of additions or replacements;
b) Impose the same data protection obligations on sub-processors as set out in this DPA;
c) Remain fully liable to Controller for sub-processor performance.
3.5 **Data Subject Rights** (Art 28.3e): Processor shall, taking into account the nature of processing, assist Controller by implementing appropriate technical and organizational measures to fulfill Controller's obligation to respond to requests exercising data subject rights under Articles 15-22. Processor shall respond to Controller's assistance requests within 72 hours.
3.6 **Security Compliance** (Art 28.3f): Processor shall assist Controller in ensuring compliance with Articles 32-36, including:
- Security of processing assessments
- Personal data breach notifications
- Data protection impact assessments
- Prior consultation with supervisory authorities
3.7 **Data Deletion/Return** (Art 28.3g): Upon termination or expiry of this DPA, Processor shall, at Controller's election:
a) Delete all Personal Data and certify deletion in writing within 45 days; or
b) Return all Personal Data to Controller in CSV/JSON format within 30 days.
3.8 **Audit Rights** (Art 28.3h): Processor shall make available to Controller all information necessary to demonstrate compliance with Article 28 and allow for audits. Controller may conduct on-site audits ${config.auditFrequency} with 30 days' prior notice.
---
## 4. PERSONAL DATA BREACH NOTIFICATION
4.1 **Notification Obligation**: Processor shall notify Controller without undue delay and in any event within ${config.securityMeasures.incidentNotificationSLA} of becoming aware of a Personal Data Breach affecting Controller's Personal Data.
4.2 **Notification Content**: Breach notifications shall include:
a) Description of the nature of the breach, including categories and approximate numbers of Data Subjects and records;
b) Name and contact details of Processor's data protection officer or other contact point;
c) Description of likely consequences of the breach;
d) Measures taken or proposed to address the breach and mitigate adverse effects.
4.3 **Incident Response Cooperation**: Processor shall cooperate with Controller's incident response efforts, provide forensic assistance, and preserve evidence as reasonably requested.
---
## 5. SUB-PROCESSORS
5.1 **Approved Sub-Processors**: Controller authorizes Processor to engage the sub-processors listed in Annex B.
${config.subProcessors.length > 0 ? `
**Current Sub-Processors:**
${config.subProcessors.map(sp => `
- **${sp.name}**
- Purpose: ${sp.purpose}
- Location: ${sp.location}
`).join('\n')}
` : ''}
5.2 **Objection Rights**: Controller may object to new or replacement sub-processors within 15 days of notice. If Controller objects and the parties cannot resolve the objection, Controller may terminate affected Services without penalty.
---
## 6. INTERNATIONAL DATA TRANSFERS
${config.internationalTransfer.required ? `
6.1 **Transfer Mechanism**: Personal Data may be transferred to third countries using ${config.internationalTransfer.mechanism}.
${config.internationalTransfer.mechanism === 'SCCs' ? `
6.2 **Standard Contractual Clauses**: The parties agree to execute Standard Contractual Clauses (Commission Implementing Decision 2021/914) ${config.internationalTransfer.sccModule} as set forth in Annex C.
6.3 **Transfer Impact Assessment**: Processor represents that it has completed a Transfer Impact Assessment and implemented supplementary measures where necessary to ensure adequate protection.
` : ''}
` : `
6.1 **No International Transfers**: Processor shall process Personal Data solely within the European Economic Area unless Controller provides prior written consent for transfers to third countries.
`}
---
## 7. DATA RETENTION
7.1 **Retention Period**: Processor shall retain Personal Data for ${config.processingDetails.retentionPeriod} from the date of last processing activity, unless:
a) Controller instructs earlier deletion;
b) Applicable law requires longer retention; or
c) Legal hold obligations prevent deletion.
7.2 **Deletion Procedures**: Upon expiry of the retention period, Processor shall securely delete Personal Data using cryptographic erasure or physical destruction methods that render recovery infeasible.
---
## 8. CONTROLLER'S RIGHTS AND OBLIGATIONS
8.1 **Processing Instructions**: Controller shall provide clear, documented processing instructions and ensure such instructions comply with applicable law.
8.2 **Lawfulness of Processing**: Controller warrants that it has established lawful bases for processing under Article 6 GDPR and, where applicable, Article 9 for special categories.
8.3 **Data Quality**: Controller shall ensure Personal Data provided to Processor is accurate, adequate, and relevant for processing purposes.
---
## 9. LIABILITY AND INDEMNIFICATION
9.1 **Liability Allocation**: Each party shall be liable to Data Subjects under Article 82 GDPR for damages caused by processing that violates the GDPR. Processor shall be liable only where it has not complied with GDPR obligations specifically directed at processors or has acted outside or contrary to lawful Controller instructions.
9.2 **Indemnification**: Processor shall indemnify Controller for fines, penalties, and damages arising from Processor's breach of this DPA, provided Controller provides prompt notice and reasonable cooperation.
9.3 **Limitation**: Subject to Section 9.1, Processor's total liability under this DPA shall not exceed [AMOUNT] per incident or [AMOUNT] in aggregate per year.
---
## 10. TERM AND TERMINATION
10.1 **Term**: This DPA commences on the Effective Date and continues until termination of the underlying Service Agreement or until all Personal Data has been deleted or returned.
10.2 **Termination Rights**: Either party may terminate this DPA:
a) For material breach upon 30 days' written notice if breach remains uncured;
b) If the other party becomes subject to insolvency proceedings;
c) If regulatory authority orders cessation of processing.
10.3 **Effect of Termination**: Upon termination, Processor shall delete or return Personal Data as set forth in Section 3.7.
---
## 11. GOVERNING LAW AND JURISDICTION
11.1 **Governing Law**: This DPA shall be governed by and construed in accordance with the laws of ${config.governingLaw}.
11.2 **Jurisdiction**: The parties submit to the exclusive jurisdiction of the courts of ${config.governingLaw} for resolution of disputes.
11.3 **Supervisory Authority**: The competent supervisory authority is [CONTROLLER'S SUPERVISORY AUTHORITY].
---
## 12. GENERAL PROVISIONS
12.1 **Amendment**: This DPA may only be amended by written agreement signed by both parties.
12.2 **Severability**: If any provision is found invalid or unenforceable, the remainder shall continue in full force and effect.
12.3 **Entire Agreement**: This DPA, together with the Service Agreement and Annexes, constitutes the entire agreement regarding Personal Data processing.
---
**CONTROLLER:**
${config.controller.legalName}
Signature: _____________________
Name: _________________________
Title: ________________________
Date: _________________________
**PROCESSOR:**
${config.processor.legalName}
Signature: _____________________
Name: _________________________
Title: ________________________
Date: _________________________
---
## ANNEX A: TECHNICAL AND ORGANIZATIONAL MEASURES
${this.generateSecurityAnnex(config.securityMeasures)}
---
## ANNEX B: SUB-PROCESSORS
${this.generateSubProcessorAnnex(config.subProcessors)}
${config.internationalTransfer.required && config.internationalTransfer.mechanism === 'SCCs' ? `
---
## ANNEX C: STANDARD CONTRACTUAL CLAUSES
[Standard Contractual Clauses ${config.internationalTransfer.sccModule} to be attached]
` : ''}
`.trim();
}
/**
* Generate security measures annex
*/
private generateSecurityAnnex(measures: DPATemplateConfig['securityMeasures']): string {
return `
### 1. Encryption
**In Transit:** ${measures.encryptionInTransit}
**At Rest:** ${measures.encryptionAtRest}
### 2. Access Controls
${measures.accessControls}
### 3. Backup and Recovery
**Backup Frequency:** ${measures.backupFrequency}
**Recovery Time Objective (RTO):** 4 hours
**Recovery Point Objective (RPO):** 1 hour
### 4. Incident Response
**Notification SLA:** ${measures.incidentNotificationSLA}
**24/7 Security Operations Center:** Monitoring and threat detection
**Forensic Investigation:** Retained third-party incident response firm
### 5. Physical Security
- Biometric access controls to data centers
- 24/7 surveillance and security personnel
- Environmental controls (fire suppression, climate)
### 6. Organizational Measures
- Annual security awareness training
- Background checks for personnel with data access
- Separation of duties and least privilege access
- Regular penetration testing and vulnerability assessments
`.trim();
}
/**
* Generate sub-processor annex
*/
private generateSubProcessorAnnex(
subProcessors: DPATemplateConfig['subProcessors']
): string {
if (subProcessors.length === 0) {
return 'No sub-processors currently engaged.';
}
return `
| Sub-Processor | Processing Purpose | Location | DPA Status |
|---------------|-------------------|----------|------------|
${subProcessors.map(sp =>
`| ${sp.name} | ${sp.purpose} | ${sp.location} | Executed |`
).join('\n')}
**General Authorization:** Controller grants Processor general authorization to engage the above sub-processors. Processor shall provide 30 days' notice of additions or replacements.
`.trim();
}
}
// Usage example
const generator = new DPAGenerator();
const dpaDocument = generator.generateDPA({
controller: {
legalName: 'ChatGPT App Solutions GmbH',
jurisdiction: 'Germany',
registrationNumber: 'HRB 123456',
address: 'Friedrichstraße 123, 10117 Berlin, Germany',
dpoContact: 'dpo@chatgptapp.example'
},
processor: {
legalName: 'OpenAI, LLC',
jurisdiction: 'Delaware, USA',
registrationNumber: '6006125',
address: '3180 18th Street, San Francisco, CA 94110, USA',
dpoContact: 'privacy@openai.com'
},
processingDetails: {
purpose: 'Provide AI-powered conversational interface using GPT-4 API',
dataCategories: ['Name', 'Email', 'Conversation content', 'Usage metadata'],
dataSubjects: ['End-users', 'Customers', 'Employees'],
duration: 'duration of Service Agreement',
retentionPeriod: '12 months'
},
securityMeasures: {
encryptionInTransit: 'TLS 1.3 with perfect forward secrecy',
encryptionAtRest: 'AES-256 encryption with customer-managed keys',
accessControls: 'Role-based access control (RBAC), multi-factor authentication, least privilege',
backupFrequency: 'Hourly incremental, daily full backups with 30-day retention',
incidentNotificationSLA: '72 hours'
},
subProcessors: [
{
name: 'Microsoft Azure',
purpose: 'Cloud infrastructure hosting',
location: 'EU (Dublin, Amsterdam)'
},
{
name: 'Cloudflare',
purpose: 'CDN and DDoS protection',
location: 'Global (EU data residency)'
}
],
auditFrequency: 'annually',
governingLaw: 'Germany',
internationalTransfer: {
required: true,
mechanism: 'SCCs',
sccModule: 'Module Two (Controller to Processor)'
}
});
console.log(dpaDocument);
This comprehensive 250+ line DPA generator produces legally compliant Article 28 agreements with customizable clauses, security annexes, and sub-processor management. For integration with ChatGPT app vendor onboarding workflows, combine with e-signature APIs.
E-Signature Integration
/**
* E-Signature Integration for DPAs
* Integrates with DocuSign/HelloSign for electronic DPA execution
* Maintains audit trails and compliance records
*/
import axios from 'axios';
import { z } from 'zod';
const SignatureRequestSchema = z.object({
requestId: z.string().uuid(),
dpaDocument: z.string(),
controller: z.object({
name: z.string(),
email: z.string().email(),
title: z.string()
}),
processor: z.object({
name: z.string(),
email: z.string().email(),
title: z.string()
}),
status: z.enum(['draft', 'sent', 'viewed', 'signed', 'completed', 'declined']),
sentDate: z.string().datetime().optional(),
signedDate: z.string().datetime().optional(),
documentUrl: z.string().url().optional()
});
type SignatureRequest = z.infer<typeof SignatureRequestSchema>;
class ESignatureService {
private apiKey: string;
private apiUrl: string = 'https://api.hellosign.com/v3';
constructor(apiKey: string) {
this.apiKey = apiKey;
}
/**
* Send DPA for signature
*/
async sendForSignature(
dpaDocument: string,
controller: { name: string; email: string; title: string },
processor: { name: string; email: string; title: string }
): Promise<SignatureRequest> {
const requestId = crypto.randomUUID();
// Upload document to HelloSign
const response = await axios.post(
`${this.apiUrl}/signature_request/send`,
{
title: 'Data Processing Agreement - Please Sign',
subject: 'DPA Signature Required',
message: 'Please review and sign the attached Data Processing Agreement.',
signers: [
{
email_address: controller.email,
name: controller.name,
order: 0
},
{
email_address: processor.email,
name: processor.name,
order: 1
}
],
file_url: [`data:text/html;base64,${Buffer.from(dpaDocument).toString('base64')}`],
test_mode: 0
},
{
headers: {
'Authorization': `Basic ${Buffer.from(this.apiKey + ':').toString('base64')}`,
'Content-Type': 'application/json'
}
}
);
return {
requestId,
dpaDocument,
controller,
processor,
status: 'sent',
sentDate: new Date().toISOString(),
documentUrl: response.data.signature_request.signing_url
};
}
/**
* Check signature status
*/
async checkStatus(signatureRequestId: string): Promise<{
status: string;
signedBy: string[];
completedDate?: string;
}> {
const response = await axios.get(
`${this.apiUrl}/signature_request/${signatureRequestId}`,
{
headers: {
'Authorization': `Basic ${Buffer.from(this.apiKey + ':').toString('base64')}`
}
}
);
const request = response.data.signature_request;
return {
status: request.is_complete ? 'completed' : 'pending',
signedBy: request.signatures
.filter((s: any) => s.status_code === 'signed')
.map((s: any) => s.signer_email_address),
completedDate: request.is_complete ?
new Date(request.updated_at * 1000).toISOString() : undefined
};
}
/**
* Download completed DPA
*/
async downloadSignedDPA(signatureRequestId: string): Promise<Buffer> {
const response = await axios.get(
`${this.apiUrl}/signature_request/files/${signatureRequestId}`,
{
headers: {
'Authorization': `Basic ${Buffer.from(this.apiKey + ':').toString('base64')}`
},
responseType: 'arraybuffer'
}
);
return Buffer.from(response.data);
}
}
// Usage example
const eSignService = new ESignatureService(process.env.HELLOSIGN_API_KEY!);
const signatureRequest = await eSignService.sendForSignature(
dpaDocument,
{
name: 'Jane Doe',
email: 'dpo@chatgptapp.example',
title: 'Data Protection Officer'
},
{
name: 'John Smith',
email: 'legal@openai.com',
title: 'Legal Counsel'
}
);
console.log('DPA sent for signature:', signatureRequest.requestId);
This e-signature integration automates DPA execution with legally binding electronic signatures, audit trails, and compliance documentation.
Conclusion
Data Processing Agreements establish the contractual foundation for GDPR-compliant processor relationships in ChatGPT applications. By implementing Article 28 obligations through comprehensive DPAs, deploying Standard Contractual Clauses for international transfers, conducting rigorous vendor due diligence, and automating contract workflows with template generators and e-signature integrations, you create enforceable accountability frameworks that protect data subjects' rights while enabling scalable vendor management.
The TypeScript implementations provided demonstrate production-ready approaches to SCC automation, Transfer Impact Assessments, vendor registry management, DPA generation, and electronic execution. These tools integrate with broader ChatGPT data governance frameworks to deliver end-to-end compliance coverage across your processor ecosystem.
Ready to automate DPA management for your ChatGPT app? Start your free trial and generate GDPR-compliant Data Processing Agreements in minutes with our built-in legal automation tools. Join thousands of developers building privacy-first AI applications with MakeAIHQ's comprehensive compliance platform.
Related Resources
- GDPR Article 28 Controller-Processor Requirements
- Standard Contractual Clauses Implementation Guide
- ChatGPT Vendor Risk Assessment Framework
- International Data Transfer Compliance
- ChatGPT Sub-Processor Management
- GDPR Audit Rights and Inspection Protocols
- ChatGPT Data Breach Notification Workflows
- Data Processing Register Automation
- Technical and Organizational Measures
- ChatGPT App Legal Compliance Guide (Pillar)
External References:
- GDPR Article 28 - Processor Obligations - Official GDPR text
- European Commission Standard Contractual Clauses - Official SCC templates
- EDPB Recommendations on Supplementary Measures - Transfer Impact Assessment guidance