Agent Skills by ALSEL
Anthropic Claudeセキュリティ⭐ リポ 1品質スコア 58/100

deepgram-security-basics

Deepgramのセキュリティベストプラクティスに従い、APIキーの管理とデータ保護を実施します。Deepgramの統合を保護したい、キーローテーション機能を導入したい、セキュリティ設定を監査したいという場合に活用できます。「deepgram security」「deepgram APIキーセキュリティ」「secure deepgram」「deepgram key rotation」「deepgram data protection」などのフレーズで起動します。

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".

SKILL.md 本文

Deepgram セキュリティの基礎

概要

APIキー管理、データ保護、アクセス制御を含む Deepgram API 統合のセキュリティベストプラクティスを実装します。

前提条件

  • Deepgram コンソールへのアクセス
  • 環境変数の理解
  • シークレット管理の知識

セキュリティチェックリスト

  • API キーが環境変数またはシークレットマネージャーに保存されている
  • 開発/ステージング/本番環境で異なるキーを使用している
  • キーローテーションスケジュールが確立されている
  • 監査ログが有効になっている
  • ネットワークアクセスが制限されている
  • データ処理が規制に準拠している

手順

ステップ 1: API キーの安全な保存

ソースコードに API キーをハードコーディングしないでください。

ステップ 2: キーローテーションの実装

定期的なキーローテーションのプロセスを作成します。

ステップ 3: アクセス制御の設定

プロジェクトレベルの権限を設定します。

ステップ 4: 監査ログの有効化

API の使用状況とアクセスパターンを追跡します。

環境変数設定

# .env.example (これをコミット)
DEEPGRAM_API_KEY=your-api-key-here

# .env (絶対にコミットしない)
DEEPGRAM_API_KEY=actual-secret-key

# .gitignore
.env
.env.local
.env.*.local

シークレットマネージャー統合 (AWS)

// lib/secrets.ts
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> {
  // Use cached key if not expired
  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; // 5 minute cache

  return cachedKey!;
}

シークレットマネージャー統合 (GCP)

// lib/secrets-gcp.ts
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;
}

キーローテーションスクリプト

// scripts/rotate-key.ts
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);

  // 1. Create new key
  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), // 90 days
    }
  );

  if (createError) throw new Error(`Failed to create key: ${createError.message}`);

  // 2. Test new key
  const testClient = createClient(newKey.key);
  const { error: testError } = await testClient.manage.getProjects();

  if (testError) {
    // Rollback: delete new key
    await client.manage.deleteProjectKey(projectId, newKey.key_id);
    throw new Error('New key validation failed');
  }

  // 3. Get old key ID (from current key metadata)
  const { result: keys } = await client.manage.getProjectKeys(projectId);
  const oldKey = keys?.api_keys.find(k =>
    k.comment?.includes('Current production key')
  );

  // 4. Update secret manager with new key
  // (Implementation depends on your secret manager)

  // 5. Delete old key after grace period
  if (oldKey) {
    console.log(`Old key ${oldKey.key_id} scheduled for deletion`);
    // Schedule deletion for later to allow propagation
  }

  return {
    oldKeyId: oldKey?.key_id || 'unknown',
    newKeyId: newKey.key_id,
    rotatedAt: new Date(),
  };
}

スコープ付き API キー

// Create keys with minimal required permissions
const scopedKeys = {
  // Transcription-only key
  transcription: {
    scopes: ['listen:*'],
    comment: 'Read-only transcription key',
  },

  // Admin key (for key management only)
  admin: {
    scopes: ['manage:*'],
    comment: 'Administrative access only',
  },

  // Usage tracking key
  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;
}

リクエスト サニタイゼーション

// lib/sanitize.ts
export function sanitizeAudioUrl(url: string): string {
  const parsed = new URL(url);

  // Only allow HTTPS
  if (parsed.protocol !== 'https:') {
    throw new Error('Only HTTPS URLs are allowed');
  }

  // Block internal/local URLs
  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');
  }

  // Block private IP ranges
  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 sanitizeTranscriptResponse(response: unknown): unknown {
  // Remove any unexpected fields that might contain sensitive data
  if (typeof response !== 'object' || response === null) {
    return response;
  }

  const allowedFields = [
    'results',
    'metadata',
    'channels',
    'alternatives',
    'transcript',
    'confidence',
    'words',
    'start',
    'end',
  ];

  const sanitized: Record<string, unknown> = {};

  for (const [key, value] of Object.entries(response)) {
    if (allowedFields.includes(key)) {
      sanitized[key] = value;
    }
  }

  return sanitized;
}

監査ログ

// lib/audit.ts
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);

    // In production, send to your logging service
    console.log(JSON.stringify({
      ...fullEvent,
      timestamp: fullEvent.timestamp.toISOString(),
    }));
  }

  async transcribe(
    transcribeFn: () => Promise<unknown>,
    context: { userId?: string; ipAddress?: string }
  ) {
    const startTime = Date.now();

    try {
      const result = await transcribeFn();

      this.log({
        action: 'TRANSCRIBE',
        success: true,
        userId: context.userId,
        ipAddress: context.ipAddress,
        metadata: {
          durationMs: Date.now() - startTime,
        },
      });

      return result;
    } catch (error) {
      this.log({
        action: 'TRANSCRIBE',
        success: false,
        userId: context.userId,
        ipAddress: context.ipAddress,
        metadata: {
          error: error instanceof Error ? error.message : 'Unknown error',
          durationMs: Date.now() - startTime,
        },
      });

      throw error;
    }
  }
}

データ保護

// lib/data-protection.ts
import crypto from 'crypto';

// Encrypt transcripts at rest
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.createDecipheriv(
    'aes-256-gcm',
    key,
    Buffer.from(iv, 'hex')
  );

  decipher.setAuthTag(Buffer.from(tag, 'hex'));

  let decrypted = decipher.update(data, 'hex', 'utf8');
  decrypted += decipher.final('utf8');

  return decrypted;
}

// Redact sensitive information from transcripts
export function redactSensitiveData(transcript: string): string {
  const patterns = [
    // Credit card numbers
    { pattern: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g, replacement: '[REDACTED-CC]' },
    // SSN
    { pattern: /\b\d{3}[\s-]?\d{2}[\s-]?\d{4}\b/g, replacement: '[REDACTED-SSN]' },
    // Phone numbers
    { pattern: /\b\d{3}[\s-]?\d{3}[\s-]?\d{4}\b/g, replacement: '[REDACTED-PHONE]' },
    // Email addresses
    { pattern: /\b[\w.-]+@[\w.-]+\.\w+\b/g, replacement: '[REDACTED-EMAIL]' },
  ];

  let redacted = transcript;
  for (const { pattern, replacement } of patterns) {
    redacted = redacted.replace(pattern, replacement);
  }

  return redacted;
}

リソース

次のステップ

本番環境デプロイメントチェックリストについて、deepgram-prod-checklist に進みます。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
Brmbobo
リポジトリ
Brmbobo/Web2podcast
ライセンス
MIT
最終更新
2026/1/26

Source: https://github.com/Brmbobo/Web2podcast / ライセンス: MIT

関連スキル

Anthropic Claudeセキュリティ⭐ リポ 8,981

secure-code-guardian

認証・認可の実装、ユーザー入力の保護、OWASP Top 10の脆弱性対策が必要な場合に使用します。bcrypt/argon2によるパスワードハッシング、パラメータ化ステートメントによるSQLインジェクション対策、CORS/CSPヘッダーの設定、Zodによる入力検証、JWTトークンの構築などのカスタムセキュリティ実装に対応します。認証、認可、入力検証、暗号化、OWASP Top 10対策、セッション管理、セキュリティ強化全般で活用できます。ただし、構築済みのOAuth/SSO統合や単独のセキュリティ監査が必要な場合は、より特化したスキルの検討をお勧めします。

by Jeffallan
汎用セキュリティ⭐ リポ 1,982

claude-authenticity

APIエンドポイントが本物のClaudeによって支えられているか(ラッパーやプロキシ、偽装ではないか)を、claude-verifyプロジェクトを模した9つの重み付きルールベースチェックで検証できます。また、Claudeの正体を上書きしているプロバイダーから注入されたシステムプロンプトも抽出します。完全に自己完結しており、httpx以外の追加パッケージは不要です。Claude APIキーまたはエンドポイントを検証したい場合、サードパーティのClaudeサービスが本物か確認したい場合、APIプロバイダーのClaude正当性を監査したい場合、複数モデルを並行してテストしたい場合、またはプロバイダーが注入したシステムプロンプトを特定したい場合に使用できます。

by LeoYeAI
Anthropic Claudeセキュリティ⭐ リポ 2,159

anth-security-basics

Anthropic Claude APIのセキュリティベストプラクティスを適用し、キー管理、入力値の検証、プロンプトインジェクション対策を実施します。APIキーの保護、Claudeに送信する前のユーザー入力検証、コンテンツセーフティガードレールの実装が必要な場合に活用できます。「anthropic security」「claude api key security」「secure anthropic」「prompt injection defense」といったフレーズでトリガーされます。

by jeremylongshore
汎用セキュリティ⭐ リポ 699

x-ray

x-ray.mdプレ監査レポートを生成します。概要、強化された脅威モデル(プロトコルタイプのプロファイリング、Gitの重み付け攻撃面分析、時間軸リスク分析、コンポーザビリティ依存関係マッピング)、不変条件、統合、ドキュメント品質、テスト分析、開発者・Gitの履歴をカバーしています。「x-ray」「audit readiness」「readiness report」「pre-audit report」「prep this protocol」「protocol prep」「summarize this protocol」のキーワードで実行されます。

by pashov
汎用セキュリティ⭐ リポ 677

semgrep

Semgrepスタティック分析スキャンを実行し、カスタム検出ルールを作成します。Semgrepでのコードスキャン、セキュリティ脆弱性の検出、カスタムYAMLルールの作成、または特定のバグパターンの検出が必要な場合に使用します。重要:ユーザーが「バグをスキャンしたい」「コード品質を確認したい」「脆弱性を見つけたい」「スタティック分析」「セキュリティlint」「コード監査」または「コーディング標準を適用したい」と尋ねた場合も、Semgrepという名称を明記していなくても、このスキルを使用してください。Semgrepは30以上の言語に対応したパターンベースのコードスキャンに最適なツールです。

by wimpysworld
汎用セキュリティ⭐ リポ 591

ghost-bits-cast-attack

Java「ゴーストビッツ」/キャストアタック プレイブック(Black Hat Asia 2026)。16ビット文字が8ビットバイトに暗黙的に縮小されるJavaサービスへの攻撃時に使用します。WAF/IDSを回避して、SQLインジェクション、デシリアライゼーション型RCE、ファイルアップロード(Webシェル)、パストトラバーサル、CRLF インジェクション、リクエストスマグリング、SMTPインジェクションを実行できます。Tomcat、Spring、Jetty、Undertow、Vert.x、Jackson、Fastjson、Apache Commons BCEL、Apache HttpClient、Angus Mail、JDK HttpServer、Lettuce、Jodd、XMLWriterに影響し、WAFバイパスにより多くの「パッチ済み」CVEを再度有効化します。

by yaklang
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: Brmbobo · Brmbobo/Web2podcast · ライセンス: MIT