| name | deepgram-security-basics |
| description | Apply Deepgram security best practices for API key management and data protection.
Use when securing Deepgram integrations, implementing key rotation,
or auditing security configurations.
Trigger with phrases like "deepgram security", "deepgram API key security",
"secure deepgram", "deepgram key rotation", "deepgram data protection".
|
| allowed-tools | Read, Grep, Bash(curl:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Deepgram Security Basics
Overview
Implement security best practices for Deepgram API integration including key management, data protection, and access control.
Prerequisites
- Deepgram Console access
- Understanding of environment variables
- Knowledge of secret management
Security Checklist
Instructions
Step 1: Secure API Key Storage
Never hardcode API keys in source code.
Step 2: Implement Key Rotation
Create a process for regular key rotation.
Step 3: Set Up Access Control
Configure project-level permissions.
Step 4: Enable Audit Logging
Track API usage and access patterns.
Examples
Environment Variable Configuration
DEEPGRAM_API_KEY=your-api-key-here
DEEPGRAM_API_KEY=actual-secret-key
.env
.env.local
.env.*.local
Secret Manager Integration (AWS)
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager({ region: 'us-east-1' });
let cachedKey: string | null = null;
let cacheExpiry = 0;
export async function getDeepgramKey(): Promise<string> {
if (cachedKey && Date.now() < cacheExpiry) {
return cachedKey;
}
const response = await client.getSecretValue({
SecretId: 'deepgram/api-key',
});
if (!response.SecretString) {
throw new Error('Deepgram API key not found in Secrets Manager');
}
const secret = JSON.parse(response.SecretString);
cachedKey = secret.DEEPGRAM_API_KEY;
cacheExpiry = Date.now() + 300000;
return cachedKey!;
}
Secret Manager Integration (GCP)
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
const client = new SecretManagerServiceClient();
export async function getDeepgramKey(): Promise<string> {
const projectId = process.env.GCP_PROJECT_ID;
const secretName = `projects/${projectId}/secrets/deepgram-api-key/versions/latest`;
const [version] = await client.accessSecretVersion({ name: secretName });
const payload = version.payload?.data?.toString();
if (!payload) {
throw new Error('Deepgram API key not found');
}
return payload;
}
Key Rotation Script
import { createClient } from '@deepgram/sdk';
interface KeyRotationResult {
oldKeyId: string;
newKeyId: string;
rotatedAt: Date;
}
export async function rotateDeepgramKey(
adminKey: string,
projectId: string
): Promise<KeyRotationResult> {
const client = createClient(adminKey);
const { result: newKey, error: createError } = await client.manage.createProjectKey(
projectId,
{
comment: `Rotated key - ${new Date().toISOString()}`,
scopes: ['usage:write', 'listen:*'],
expiration_date: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
}
);
if (createError) ();
testClient = (newKey.);
{ : testError } = testClient..();
(testError) {
client..(projectId, newKey.);
();
}
{ : keys } = client..(projectId);
oldKey = keys?..(
k.?.()
);
(oldKey) {
.();
}
{
: oldKey?. || ,
: newKey.,
: (),
};
}
Scoped API Keys
const scopedKeys = {
transcription: {
scopes: ['listen:*'],
comment: 'Read-only transcription key',
},
admin: {
scopes: ['manage:*'],
comment: 'Administrative access only',
},
usage: {
scopes: ['usage:read'],
comment: 'Usage monitoring only',
},
};
async function createScopedKey(
adminKey: string,
projectId: string,
keyType: keyof typeof scopedKeys
) {
const client = createClient(adminKey);
const config = scopedKeys[keyType];
const { result, error } = await client.manage.createProjectKey(
projectId,
config
);
if (error) throw error;
return result;
}
Request Sanitization
export function sanitizeAudioUrl(url: string): string {
const parsed = new URL(url);
if (parsed.protocol !== 'https:') {
throw new Error('Only HTTPS URLs are allowed');
}
const blockedHosts = ['localhost', '127.0.0.1', '0.0.0.0', '::1'];
if (blockedHosts.includes(parsed.hostname)) {
throw new Error('Local URLs are not allowed');
}
const privateRanges = [
/^10\./,
/^172\.(1[6-9]|2[0-9]|3[0-1])\./,
/^192\.168\./,
];
if (privateRanges.some(range => range.test(parsed.hostname))) {
throw new Error('Private IP addresses are not allowed');
}
return url;
}
export function (): {
( response !== || response === ) {
response;
}
allowedFields = [
,
,
,
,
,
,
,
,
,
];
: <, > = {};
( [key, value] .(response)) {
(allowedFields.(key)) {
sanitized[key] = value;
}
}
sanitized;
}
Audit Logging
interface AuditEvent {
timestamp: Date;
action: string;
projectId?: string;
requestId?: string;
userId?: string;
ipAddress?: string;
success: boolean;
metadata?: Record<string, unknown>;
}
export class AuditLogger {
private events: AuditEvent[] = [];
log(event: Omit<AuditEvent, 'timestamp'>) {
const fullEvent: AuditEvent = {
...event,
timestamp: new Date(),
};
this.events.push(fullEvent);
console.log(JSON.stringify({
...fullEvent,
timestamp: fullEvent.timestamp.toISOString(),
}));
}
async () {
startTime = .();
{
result = ();
.({
: ,
: ,
: context.,
: context.,
: {
: .() - startTime,
},
});
result;
} (error) {
.({
: ,
: ,
: context.,
: context.,
: {
: error ? error. : ,
: .() - startTime,
},
});
error;
}
}
}
Data Protection
import crypto from 'crypto';
export function encryptTranscript(transcript: string, key: Buffer): string {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
let encrypted = cipher.update(transcript, 'utf8', 'hex');
encrypted += cipher.final('hex');
const authTag = cipher.getAuthTag();
return JSON.stringify({
iv: iv.toString('hex'),
data: encrypted,
tag: authTag.toString('hex'),
});
}
export function decryptTranscript(encrypted: string, key: Buffer): string {
const { iv, data, tag } = JSON.parse(encrypted);
const decipher = crypto.(
,
key,
.(iv, )
);
decipher.(.(tag, ));
decrypted = decipher.(data, , );
decrypted += decipher.();
decrypted;
}
(): {
patterns = [
{ : , : },
{ : , : },
{ : , : },
{ : , : },
];
redacted = transcript;
( { pattern, replacement } patterns) {
redacted = redacted.(pattern, replacement);
}
redacted;
}
Resources
Next Steps
Proceed to deepgram-prod-checklist for production deployment checklist.