| name | deepgram-data-handling |
| description | Implement audio data handling best practices for Deepgram integrations.
Use when managing audio file storage, implementing data retention policies,
or ensuring GDPR/HIPAA compliance for transcription data.
Trigger with phrases like "deepgram data", "audio storage", "transcription data",
"deepgram GDPR", "deepgram HIPAA", "deepgram privacy".
|
| allowed-tools | Read, Write, Edit, Bash(kubectl:*), Bash(curl:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Deepgram Data Handling
Overview
Best practices for handling audio data and transcriptions with Deepgram, including storage, retention, and compliance.
Prerequisites
- Understanding of data protection regulations
- Cloud storage configured
- Encryption capabilities
- Data retention policies defined
Data Lifecycle
Upload → Process → Store → Retain → Archive → Delete
↓ ↓ ↓ ↓ ↓ ↓
Encrypt Transcribe Save Review Compress Secure
Delete
Compliance Considerations
| Regulation | Key Requirements |
|---|
| GDPR | Data minimization, right to deletion, consent |
| HIPAA | PHI protection, access controls, audit logs |
| SOC 2 | Security controls, availability, confidentiality |
| PCI DSS | Data encryption, access logging |
Instructions
Step 1: Implement Secure Upload
Handle audio uploads with encryption and validation.
Step 2: Configure Data Processing
Process transcriptions with privacy controls.
Step 3: Set Up Storage
Store data with appropriate encryption and access controls.
Step 4: Implement Retention
Automate data retention and deletion policies.
Examples
Secure Upload Handler
import crypto from 'crypto';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { KMSClient, GenerateDataKeyCommand } from '@aws-sdk/client-kms';
interface UploadOptions {
userId: string;
purpose: string;
retentionDays: number;
encrypted: boolean;
}
export class SecureAudioUpload {
private s3: S3Client;
private kms: KMSClient;
private bucket: string;
private kmsKeyId: string;
constructor() {
this.s3 = new S3Client({});
this.kms = new KMSClient({});
this.bucket = process.env.AUDIO_BUCKET!;
this. = process..!;
}
(
: ,
:
): <{ : ; : }> {
audioId = crypto.();
(!.(audioBuffer)) {
();
}
encryptedData = audioBuffer;
: | ;
(options.) {
{ encrypted, key } = .(audioBuffer);
encryptedData = encrypted;
dataKey = key;
}
hash = crypto.().(audioBuffer).();
key = ;
expirationDate = ();
expirationDate.(expirationDate.() + options.);
..( ({
: .,
: key,
: encryptedData,
: ,
: {
: options.,
: options.,
: hash,
: (options.),
: dataKey || ,
: expirationDate.(),
},
: ,
: .,
}));
{
audioId,
: ,
};
}
(: ): {
headers = {
: .([, , , ]),
: .([, ]),
: .([, , , ]),
};
.(headers).(
buffer.(, header.).(header)
);
}
(: ): <{
: ;
: ;
}> {
{ , } = ..(
({
: .,
: ,
})
);
iv = crypto.();
cipher = crypto.(, !, iv);
encrypted = .([
iv,
cipher.(data),
cipher.(),
cipher.(),
]);
{
encrypted,
: !.(),
};
}
}
PII Redaction
interface RedactionRule {
name: string;
pattern: RegExp;
replacement: string;
}
const redactionRules: RedactionRule[] = [
{
name: 'ssn',
pattern: /\b\d{3}[-\s]?\d{2}[-\s]?\d{4}\b/g,
replacement: '[SSN REDACTED]',
},
{
name: 'credit_card',
pattern: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,
replacement: '[CARD REDACTED]',
},
{
name: 'phone',
pattern: /\b(\+1[-\s]?)?\(?\d{3}\)?[-\s]?\d{3}[-\s]?\d{4}\b/g,
replacement: '[PHONE REDACTED]',
},
{
name: 'email',
pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
replacement: '[EMAIL REDACTED]',
},
{
name: 'date_of_birth',
pattern: /\b(0?[1-9]|1[0-2])[\/\-](0?[1-9]|[12]\d|3[01])[\/\-](19|20)\d{2}\b/g,
replacement: '[DOB REDACTED]',
},
];
export function redactPII(transcript: string): {
redacted: ;
: <{ : ; : }>;
} {
redacted = transcript;
: <{ : ; : }> = [];
( rule redactionRules) {
matches = redacted.(rule.);
(matches && matches. > ) {
redactions.({ : rule., : matches. });
redacted = redacted.(rule., rule.);
}
}
{ redacted, redactions };
}
(): <{ : ; : }> {
{ result, error } = client...(
{ : audioUrl },
{
: ,
: [, , ],
: ,
}
);
(error) error;
transcript = result..[].[].;
{ redacted } = (transcript);
{ transcript, : redacted };
}
Data Retention Policy
import { S3Client, ListObjectsV2Command, DeleteObjectsCommand } from '@aws-sdk/client-s3';
import { db } from './database';
import { logger } from './logger';
interface RetentionPolicy {
name: string;
retentionDays: number;
dataTypes: string[];
complianceReasons: string[];
}
const policies: RetentionPolicy[] = [
{
name: 'standard',
retentionDays: 30,
dataTypes: ['audio', 'transcript'],
complianceReasons: ['business'],
},
{
name: 'legal_hold',
retentionDays: 365 * 7,
dataTypes: ['audio', 'transcript', 'metadata'],
complianceReasons: ['legal', 'regulatory'],
},
{
name: 'hipaa',
retentionDays: 365 * 6,
: [, , ],
: [],
},
];
{
: S3Client;
: ;
() {
. = ({});
. = process..!;
}
(): <{
: ;
: ;
: ;
}> {
stats = { : , : , : };
now = ();
{ } = ..( ({
: .,
: ,
}));
(!) stats;
: [] = [];
( ) {
stats.++;
(!.) ;
metadata = .(.);
policy = .(metadata);
expirationDate = (metadata.);
expirationDate.(expirationDate.() + policy.);
(now > expirationDate && !metadata.) {
toDelete.(.);
stats.++;
} {
stats.++;
}
}
(toDelete. > ) {
.(toDelete);
}
logger.(, stats);
stats;
}
(: <, >): {
(metadata. === ) {
policies.( p. === )!;
}
(metadata. === ) {
policies.( p. === )!;
}
policies.( p. === )!;
}
(: []): <> {
batches = .(keys, );
( batch batches) {
..( ({
: .,
: {
: batch.( ({ })),
},
}));
db..({
: { : batch },
});
}
}
chunk<T>(: T[], : ): T[][] {
.({ : .(arr. / size) },
arr.(i * size, i * size + size)
);
}
(: ): <<, >> {
{};
}
}
GDPR Right to Deletion
import { db } from './database';
import { S3Client, DeleteObjectCommand, ListObjectsV2Command } from '@aws-sdk/client-s3';
import { logger } from './logger';
interface DeletionRequest {
userId: string;
requestedAt: Date;
dataTypes: string[];
verificationToken: string;
}
export class GDPRCompliance {
private s3: S3Client;
constructor() {
this.s3 = new S3Client({});
}
async processRightToErasure(userId: string): Promise<{
success: boolean;
deletedItems: {
transcripts: number;
audioFiles: number;
metadata: number;
};
}> {
const deletedItems = {
transcripts: 0,
audioFiles: 0,
: ,
};
{
transcriptResult = db..({
userId,
});
deletedItems. = transcriptResult.;
audioFiles = .(userId);
( file audioFiles) {
..( ({
: process..!,
: file,
}));
deletedItems.++;
}
metadataResult = db..({
userId,
});
deletedItems. = metadataResult.;
.(userId, deletedItems);
logger.(, { userId, deletedItems });
{ : , deletedItems };
} (error) {
logger.(, {
userId,
: error ? error. : ,
});
error;
}
}
(: ): <> {
userData = {
: db..({ userId }).(),
: db..({ userId }),
: db..({ userId }).(),
: ().(),
};
.(.(userData, , ));
}
(: ): <[]> {
{ } = ..( ({
: process..!,
: ,
}));
?.( c.!).() || [];
}
(
: ,
: <, >
): <> {
db..({
: ,
userId,
deletedItems,
: (),
});
}
}
Audit Logging
interface AuditEvent {
timestamp: Date;
action: string;
userId: string;
resourceType: 'audio' | 'transcript' | 'user';
resourceId: string;
details: Record<string, unknown>;
ipAddress?: string;
userAgent?: string;
}
export class AuditLogger {
async log(event: Omit<AuditEvent, 'timestamp'>): Promise<void> {
const fullEvent: AuditEvent = {
...event,
timestamp: new Date(),
};
await db.auditLog.insertOne({
...fullEvent,
hash: this.computeHash(fullEvent),
});
if (process.env.SIEM_ENDPOINT) {
.(fullEvent);
}
}
(: ): {
crypto
.()
.(.(event))
.();
}
(: ): <> {
(process..!, {
: ,
: { : },
: .(event),
});
}
}
Resources
Next Steps
Proceed to deepgram-enterprise-rbac for access control configuration.