DEV Community

Cover image for 2026年 HIPAA準拠API構築ガイド:安全な医療アプリ開発
Akira
Akira

Posted on • Originally published at apidog.com

2026年 HIPAA準拠API構築ガイド:安全な医療アプリ開発

要約

APIのHIPAA準拠には、転送中および保存中の暗号化、監査ログ、アクセス制御、ビジネスアソシエイト契約など、保護対象保健情報(PHI)に関する厳格なセキュリティ制御の実装が必要です。本記事は、PHIを扱うヘルスケアアプリケーション向けのAPIアーキテクチャパターン、認証要件、監査証跡の実装、コンプライアンス検証方法を、実装手順ベースで解説します。

Apidog を今すぐ試そう

💡 Apidogなら、安全なエンドポイント設計、暗号化要件の検証、アクセスパターン監査、コンプライアンス制御の文書化を一つのワークスペースで実現。API仕様をコンプライアンスチームと共有し、監査対応ドキュメントを効率維持できます。

はじめに

ヘルスケアデータの侵害は1件あたり平均1,093万ドルのコストが発生します。ヘルスケアアプリケーション開発者にとって、APIセキュリティは選択肢ではなく、HIPAA(医療保険の携行性と説明責任に関する法律)で義務付けられています。

現実にはヘルスケアデータ侵害の79%はAPIやアプリケーションの脆弱性経由です。堅牢なHIPAA準拠APIアーキテクチャは侵害防止・監査証跡・患者プライバシー保護の基盤となります。

このガイドでは、HIPAA API準拠の実装フローを順に説明します。PHI取扱要件、暗号化標準、アクセス制御の実装、監査ログ、コンプライアンス文書化を実装例・コード中心で解説します。最終的に、本番対応のHIPAA準拠APIアーキテクチャを開発できるようになります。

HIPAAとは何か、そしてAPIにとってなぜ重要なのか?

HIPAAは、患者の健康情報を保護するための連邦法です。HIPAAセキュリティ規則は、APIで送信される電子保護対象保健情報(ePHI)にも適用されます。

誰が遵守しなければならないか

エンティティの種類 APIへの影響
対象事業体 医療提供者、医療保険機関、保険情報処理機関 直接的なHIPAA責任
ビジネスアソシエイト APIプロバイダー、クラウドサービス、ソフトウェアベンダー BAAが必要、直接的な責任
下請け業者 サブプロセッサ、下流のAPIサービス BAAが必要

APIに関する主要なHIPAA規則

プライバシー規則: PHIの使用・開示を管理

  • 最小必要限度基準
  • 患者のアクセス権
  • 承認要件

セキュリティ規則: ePHIの技術的保護措置

  • アクセス制御
  • 監査制御
  • 完全性制御
  • 送信セキュリティ

侵害通知規則: インシデント対応要件

  • 60日以内の通知
  • リスク評価文書
  • 軽減策

APIアーキテクチャの概要

HIPAA準拠APIアーキテクチャの全体像:

┌─────────────────────────────────────────────────────────────────┐
│                    HIPAA-COMPLIANT API STACK                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐         │
│  │   CLIENT    │───▶│   API       │───▶│  DATABASE   │         │
│  │   (App)     │    │   Gateway   │    │  (Encrypted)│         │
│  └─────────────┘    └─────────────┘    └─────────────┘         │
│        │                  │                  │                  │
│        ▼                  ▼                  ▼                  │
│  ┌─────────────┐    ┌─────────────┐    ┌─────────────┐         │
│  │   OAuth 2.0 │    │   WAF +     │    │   Audit     │         │
│  │   + MFA     │    │   Rate Limit│    │   Logging   │         │
│  └─────────────┘    └─────────────┘    └─────────────┘         │
│                                                                  │
│  All data encrypted: TLS 1.3+ in transit, AES-256 at rest       │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

開始: コンプライアンスの基盤

ステップ1: ビジネスアソシエイト契約(BAA)を締結する

PHIを扱う前に下記を実施:

  1. PHIにアクセスするベンダーを特定
  2. 各ベンダーとBAA締結
  3. サブプロセッサをBAA内で文書化
  4. 毎年見直し・更新

BAAが必要な主なベンダー例:

  • クラウドホスティング(AWS/GCP/Azure)
  • データベースプロバイダー
  • ロギング/バックアップ/監視サービス
  • APIゲートウェイ

BAAなしでの利用禁止例:

  • 標準のGoogle Analytics
  • 無料枠クラウド
  • 個人メールアカウント
  • 非ヘルスケア向けSlack

ステップ2: データ分類

APIが扱うすべてのデータを分類:

データ型 分類 保護レベル
患者名 + 生年月日 PHI 完全なHIPAA制御
医療記録番号 PHI 完全なHIPAA制御
診断コード(ICD-10) PHI 完全なHIPAA制御
治療記録 PHI 完全なHIPAA制御
予約時間(患者IDなし) PHIではない 標準的な制御
集計・匿名化データ PHIではない 標準的な制御

ステップ3: 最小必要限度基準

APIは必要最小限のデータのみ返却する設計を徹底。

// 悪い例: すべての患者データを返す
app.get('/api/patients/:id', async (req, res) => {
  const patient = await db.patients.findById(req.params.id);
  res.json(patient); // 全フィールド返却
});

// 良い例: フィールドレベルで制限
app.get('/api/patients/:id', async (req, res) => {
  const fields = req.query.fields?.split(',') || ['id', 'name'];
  const allowedFields = ['id', 'name', 'dateOfBirth']; // ホワイトリスト

  const patient = await db.patients.findById(req.params.id);
  const filtered = Object.fromEntries(
    Object.entries(patient).filter(([key]) => allowedFields.includes(key))
  );

  res.json(filtered);
});
Enter fullscreen mode Exit fullscreen mode

技術的保護措置の実装

アクセス制御: 認証

強力な認証(MFA必須)を実装:

const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

class HIPAAAuthService {
  async authenticate(username, password, mfaCode) {
    const user = await this.getUserByUsername(username);
    if (!user) throw new Error('Invalid credentials');
    const validPassword = await bcrypt.compare(password, user.passwordHash);
    if (!validPassword) throw new Error('Invalid credentials');
    const validMFA = this.verifyTOTP(user.mfaSecret, mfaCode);
    if (!validMFA) throw new Error('Invalid MFA code');

    const token = jwt.sign(
      {
        sub: user.id,
        role: user.role,
        mfa_verified: true
      },
      process.env.JWT_SECRET,
      { expiresIn: '15m' }
    );
    await this.auditLog('AUTH_SUCCESS', { userId: user.id, ip: req.ip });
    return { token, expiresIn: 900 };
  }

  verifyTOTP(secret, token) {
    const period = 30;
    const digits = 6;
    const now = Math.floor(Date.now() / 1000);
    const counter = Math.floor(now / period);

    const buffer = Buffer.alloc(8);
    buffer.writeUInt32BE(0, 0);
    buffer.writeUInt32BE(counter, 4);

    const hmac = crypto.createHmac('sha1', secret).update(buffer).digest();
    const offset = hmac[hmac.length - 1] & 0xf;

    const code = (
      ((hmac[offset] & 0x7f) << 24) |
      ((hmac[offset + 1] & 0xff) << 16) |
      ((hmac[offset + 2] & 0xff) << 8) |
      (hmac[offset + 3] & 0xff)
    ) % Math.pow(10, digits);

    return code.toString().padStart(digits, '0') === token;
  }
}
Enter fullscreen mode Exit fullscreen mode

アクセス制御: 認可(RBAC)

ロールベース認可をミドルウェアで実装。

const ROLES = {
  ADMIN: 'admin',
  PROVIDER: 'provider',
  NURSE: 'nurse',
  BILLING: 'billing',
  PATIENT: 'patient'
};

const PERMISSIONS = {
  [ROLES.ADMIN]: ['read:all', 'write:all', 'delete:all'],
  [ROLES.PROVIDER]: ['read:patients', 'write:patients', 'read:labs', 'write:orders'],
  [ROLES.NURSE]: ['read:patients', 'write:vitals', 'read:labs'],
  [ROLES.BILLING]: ['read:billing', 'read:patients:limited'],
  [ROLES.PATIENT]: ['read:self', 'write:self']
};

const authorize = (...requiredPermissions) => {
  return async (req, res, next) => {
    const user = req.user;
    const userPermissions = PERMISSIONS[user.role] || [];
    const hasPermission = requiredPermissions.every(
      perm => userPermissions.includes(perm)
    );
    if (!hasPermission) {
      await auditLog('AUTHZ_DENIED', {
        userId: user.id,
        action: req.method,
        path: req.path,
        required: requiredPermissions
      });
      return res.status(403).json({ error: 'Insufficient permissions' });
    }
    next();
  };
};

app.get('/api/patients/:id/records',
  authenticate,
  authorize('read:patients'),
  getPatientRecords
);
Enter fullscreen mode Exit fullscreen mode

転送中の暗号化

TLS 1.3をAPIサーバーに強制:

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),
  ca: fs.readFileSync('ca-cert.pem'),
  minVersion: 'TLSv1.3',
  ciphers: [
    'TLS_AES_256_GCM_SHA384',
    'TLS_CHACHA20_POLY1305_SHA256',
    'TLS_AES_128_GCM_SHA256'
  ].join(':'),
  honorCipherOrder: true
};
const server = https.createServer(options, app);

app.use((req, res, next) => {
  if (!req.secure) {
    return res.redirect(`https://${req.headers.host}${req.url}`);
  }
  next();
});

app.use((req, res, next) => {
  res.setHeader(
    'Strict-Transport-Security',
    'max-age=31536000; includeSubDomains; preload'
  );
  next();
});
Enter fullscreen mode Exit fullscreen mode

保存中の暗号化

保存データ(PHI)はAES-256-GCMで暗号化。

const crypto = require('crypto');

class EncryptionService {
  constructor(key) {
    this.key = crypto.scryptSync(key, 'salt', 32);
    this.algorithm = 'aes-256-gcm';
  }
  encrypt(plaintext) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(this.algorithm, this.key, iv);
    let encrypted = cipher.update(plaintext, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    const authTag = cipher.getAuthTag().toString('hex');
    return {
      encryptedData: encrypted,
      iv: iv.toString('hex'),
      authTag: authTag
    };
  }
  decrypt(encryptedData, iv, authTag) {
    const decipher = crypto.createDecipheriv(
      this.algorithm,
      this.key,
      Buffer.from(iv, 'hex')
    );
    decipher.setAuthTag(Buffer.from(authTag, 'hex'));
    let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
  }
}

// データベース保存例
class PatientRecord {
  constructor(db, encryptionService) {
    this.db = db;
    this.encryption = encryptionService;
  }
  async create(data) {
    const encryptedData = {
      ...data,
      ssn: this.encryption.encrypt(data.ssn),
      diagnosis: this.encryption.encrypt(data.diagnosis),
      treatmentNotes: this.encryption.encrypt(data.treatmentNotes)
    };
    await this.db.patients.insert(encryptedData);
    await auditLog('PHI_CREATED', { recordType: 'patient' });
  }
  async findById(id) {
    const record = await this.db.patients.findById(id);
    return {
      ...record,
      ssn: this.encryption.decrypt(record.ssn.encryptedData, record.ssn.iv, record.ssn.authTag),
      diagnosis: this.encryption.decrypt(record.diagnosis.encryptedData, record.diagnosis.iv, record.diagnosis.authTag),
      treatmentNotes: this.encryption.decrypt(record.treatmentNotes.encryptedData, record.treatmentNotes.iv, record.treatmentNotes.authTag)
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

監査制御の実装

包括的な監査ロギング

PHIアクセスはすべてログに記録。追記専用ストレージ推奨。

const winston = require('winston');

const auditLogger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.File({
      filename: '/var/log/hipaa-audit/audit.log',
      maxsize: 52428800,
      maxFiles: 365
    }),
    new winston.transports.Http({
      host: 'siem.internal',
      path: '/api/logs',
      ssl: true
    })
  ]
});

const auditLog = async (event, details) => {
  const logEntry = {
    timestamp: new Date().toISOString(),
    event: event,
    actor: details.userId,
    action: details.action,
    resource: details.resource,
    outcome: details.outcome || 'SUCCESS',
    ipAddress: details.ip,
    userAgent: details.userAgent,
    details: details.metadata
  };
  auditLogger.info(logEntry);
  await db.auditLogs.insert(logEntry);
};

app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', async () => {
    const duration = Date.now() - start;
    if (req.path.includes('/patients') || req.path.includes('/records')) {
      await auditLog('API_ACCESS', {
        userId: req.user?.id || 'anonymous',
        action: req.method,
        resource: req.path,
        outcome: res.statusCode < 400 ? 'SUCCESS' : 'FAILURE',
        ip: req.ip,
        userAgent: req.headers['user-agent'],
        metadata: {
          duration: duration,
          statusCode: res.statusCode,
          queryParams: Object.keys(req.query)
        }
      });
    }
  });
  next();
});
Enter fullscreen mode Exit fullscreen mode

必要な監査イベント

イベントタイプ ログ内容 保持期間
認証 成功/失敗、MFA、IP 6年間
認可 拒否アクセス 6年間
PHIアクセス 誰が・いつ・何にアクセス 6年間
PHI変更 変更前/後の値 6年間
PHI削除 誰が・何を削除 6年間
システム変更 設定変更・新規ユーザー 6年間
セキュリティイベント 失敗リク・レート制限 6年間

監査レポートの生成

const generateAuditReport = async (startDate, endDate, options = {}) => {
  const query = {
    timestamp: {
      $gte: new Date(startDate),
      $lte: new Date(endDate)
    }
  };
  if (options.userId) query.actor = options.userId;
  if (options.eventType) query.event = options.eventType;
  const logs = await db.auditLogs.find(query).sort({ timestamp: 1 });
  return {
    reportPeriod: { start: startDate, end: endDate },
    generatedAt: new Date().toISOString(),
    summary: {
      totalEvents: logs.length,
      uniqueUsers: new Set(logs.map(l => l.actor)).size,
      failures: logs.filter(l => l.outcome === 'FAILURE').length,
      phiAccess: logs.filter(l => l.event === 'PHI_ACCESS').length
    },
    events: logs
  };
};

// 週次レポート自動送信例
cron.schedule('0 0 * * 1', async () => {
  const end = new Date();
  const start = new Date(end.getTime() - 7 * 24 * 60 * 60 * 1000);
  const report = await generateAuditReport(start, end);
  await sendToComplianceTeam(report);
});
Enter fullscreen mode Exit fullscreen mode

APIセキュリティのベストプラクティス

入力検証

インジェクション攻撃対策に厳格なバリデーションを導入。

const { body, param, query, validationResult } = require('express-validator');

const validatePatientRequest = [
  body('firstName')
    .trim()
    .notEmpty()
    .matches(/^[a-zA-Z\s'-]+$/)
    .withMessage('Invalid first name format')
    .isLength({ max: 50 }),
  body('dateOfBirth')
    .isISO8601()
    .withMessage('Invalid date format')
    .custom(value => new Date(value) < new Date())
    .withMessage('Date of birth must be in the past'),
  body('ssn')
    .optional()
    .matches(/^\d{3}-\d{2}-\d{4}$/)
    .withMessage('Invalid SSN format'),
  body('email')
    .optional()
    .isEmail()
    .normalizeEmail(),
  param('id')
    .isUUID()
    .withMessage('Invalid patient ID format'),
  (req, res, next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({
        error: 'Validation failed',
        details: errors.array()
      });
    }
    next();
  }
];
Enter fullscreen mode Exit fullscreen mode

レート制限

ブルートフォースと悪用を防止。

const rateLimit = require('express-rate-limit');

const authLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分
  max: 5,
  message: { error: 'Too many authentication attempts' },
  standardHeaders: true,
  legacyHeaders: false,
  handler: async (req, res) => {
    await auditLog('RATE_LIMIT_EXCEEDED', {
      userId: req.body.username,
      ip: req.ip,
      endpoint: 'auth'
    });
    res.status(429).json({ error: 'Too many attempts' });
  }
});

const apiLimiter = rateLimit({
  windowMs: 60 * 1000, // 1分
  max: 100,
  message: { error: 'Rate limit exceeded' }
});

app.use('/api/auth', authLimiter);
app.use('/api', apiLimiter);
Enter fullscreen mode Exit fullscreen mode

エラー処理

情報漏洩防止のためのエラーハンドリング。

app.use((err, req, res, next) => {
  // 内部ログ
  console.error('Error:', {
    message: err.message,
    stack: err.stack,
    path: req.path,
    user: req.user?.id
  });

  // クライアントには一般的なメッセージのみ返す
  res.status(err.status || 500).json({
    error: 'An error occurred processing your request',
    requestId: req.id
  });
});

// 公開禁止情報:
// - スタックトレース
// - データベーススキーマ
// - 内部IP
// - ユーザー数
// - エラーメッセージ内のPHI
Enter fullscreen mode Exit fullscreen mode

一般的なHIPAA API違反とその回避方法

違反: 不適切なアクセス制御

: すべての認証済みユーザーが任意の患者記録にアクセス可能。

修正:

// 悪い例: 認可チェックなし
app.get('/api/patients/:id', async (req, res) => {
  const patient = await db.patients.findById(req.params.id);
  res.json(patient);
});

// 良い例: ユーザーが患者自身or担当プロバイダーか確認
app.get('/api/patients/:id', async (req, res) => {
  const patient = await db.patients.findById(req.params.id);
  if (req.user.id === patient.userId) {
    return res.json(patient);
  }
  const assignment = await db.providerAssignments.findOne({
    providerId: req.user.id,
    patientId: patient.id
  });
  if (assignment) {
    return res.json(patient);
  }
  await auditLog('UNAUTHORIZED_ACCESS_ATTEMPT', {
    userId: req.user.id,
    patientId: patient.id
  });
  res.status(403).json({ error: 'Access denied' });
});
Enter fullscreen mode Exit fullscreen mode

違反: 監査ログの欠如

: 患者データへのアクセス記録がない

修正: すべてのPHIアクセスは監査ログに記録(上記例参照)

違反: 暗号化されていないデータ転送

: APIがHTTPを受け入れる

修正:

app.use((req, res, next) => {
  if (!req.secure && process.env.NODE_ENV === 'production') {
    return res.status(403).json({
      error: 'HTTPS required. Connect via https://' + req.headers.host
    });
  }
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  next();
});
Enter fullscreen mode Exit fullscreen mode

違反: 過剰なデータ公開

: 必要以上の患者情報を返してしまう

修正:

app.get('/api/patients/:id', async (req, res) => {
  const fields = req.query.fields?.split(',') || ['id', 'name'];
  const projection = Object.fromEntries(fields.map(f => [f, 1]));
  const patient = await db.patients.findById(req.params.id, projection);
  res.json(patient);
});
Enter fullscreen mode Exit fullscreen mode

本番環境展開チェックリスト

本番PHI運用前に下記をすべて実施:

  • [ ] すべてのベンダーとBAA締結
  • [ ] すべてのユーザーにMFA実装
  • [ ] すべてのエンドポイントでTLS 1.3を有効化
  • [ ] すべてのPHIをAES-256で保存時暗号化
  • [ ] 包括的な監査ログ実装
  • [ ] ログ保持期間を6年以上に設定
  • [ ] RBACでアクセス制御
  • [ ] レート制限実装
  • [ ] インシデント対応計画作成
  • [ ] セキュリティ制御を文書化
  • [ ] セキュリティリスク評価を実施
  • [ ] HIPAA要件のスタッフ教育
  • [ ] 定期セキュリティ監査をスケジュール

セキュリティリスク評価テンプレート

## HIPAAセキュリティリスク評価

### システム概要
- システム名: [API名]
- 処理されるPHIの種類: [リスト]
- データフロー: [図]

### 脅威評価
| 脅威 | 可能性 | 影響 | 軽減策 |
|--------|------------|--------|------------|
| 不正アクセス | 中 | 高 | MFA、RBAC |
| データ侵害 | 低 | 致命的 | 暗号化 |
| 内部脅威 | 中 | 高 | 監査ログ |

### 制御テスト
- [ ] 認証バイパステスト
- [ ] 認可バイパステスト
- [ ] SQLインジェクションテスト
- [ ] XSSテスト
- [ ] 暗号化検証

### 承認
セキュリティ責任者: _______________ 日付: _______
CTO: _______________ 日付: _______
Enter fullscreen mode Exit fullscreen mode

実世界のユースケース

遠隔医療プラットフォームAPI

  • 課題: ビデオ通話のPHI安全転送
  • 解決策: HIPAA準拠のシグナリングAPI+WebRTCエンドツーエンド暗号化
  • 結果: SOC2 Type II取得、50万件診察で侵害なし

実装ポイント:

  • MFA付きJWT認証
  • 診察後期限切れのエフェメラルトークン
  • ログにPHI保存禁止
  • Twilio(BAA付き)でビデオインフラ

患者ポータルAPI

  • 課題: レガシー20システムのセキュリティ不均一
  • 解決策: 統合APIゲートウェイ+一元化認証・監査
  • 結果: シングルソース、簡素なコンプライアンス報告

実装ポイント:

  • SMART on FHIR+OAuth 2.0
  • 一元監査ログ
  • フィールド単位アクセス制御
  • 自動侵害検知

ヘルスデータ統合プラットフォーム

  • 課題: EHRベンダー間の多様なセキュリティ
  • 解決策: 統一されたHIPAA制御付き抽象化レイヤー
  • 結果: 100病院統合・違反ゼロ

実装ポイント:

  • 一貫した暗号化
  • テナント単位監査証跡
  • BAA自動追跡
  • リアルタイムコンプライアンスダッシュボード

結論

APIのHIPAA準拠には、認証、暗号化、アクセス制御、監査ロギングの計画的実装が不可欠です。主な実装ポイント:

  • PHI取扱開始前にBAAを全ベンダーと締結
  • MFA+ロールベースアクセス制御
  • 転送中(TLS1.3)/保存中(AES-256)の暗号化
  • PHIアクセスは6年間全記録
  • 最小必要限度基準をすべてのエンドポイントに適用
  • ApidogはAPIドキュメントとコンプライアンスワークフローの効率化に最適です

FAQセクション

APIがHIPAAに準拠しているとはどういうことですか?

APIがHIPAAに準拠とは、ePHI保護のための技術的(暗号化・アクセス制御・監査ログ)、管理的(ポリシー・トレーニング・BAA)、物理的措置を実装している状態です。

私のAPIにBAAは必要ですか?

PHIを処理・保管・アクセスする場合、ビジネスアソシエイトとなりBAA締結が必須です(クラウド・APIサービス・サブプロセッサ含む)。

HIPAAで要求される暗号化とは?

転送中: TLS1.3、保存中: AES-256。HIPAA上は「対応可能」ですが実質必須要件です。

HIPAA監査ログはどのくらいの期間保持?

生成日/最終有効日いずれか遅い方から6年保持が義務。

HIPAA準拠の認証にJWTは使える?

短寿命(PHIアクセスは最大15分)、安全な保存、リフレッシュトークンのローテーション、MFA組み合わせなら許容されます。

最小必要限度基準とは?

APIが業務に必要な最小限PHIのみ公開すること。フィールドフィルタ+目的別アクセス制御を実装。

監査ログは暗号化が必要?

PHIを含む場合、保存時暗号化必須。追記専用ストレージで改ざん防止も推奨。

侵害通知はどう処理する?

  1. 侵害封じ込め
  2. 4要素テストでリスク評価
  3. 60日以内に影響者通知
  4. HHS通知(500名超は即時)
  5. 全過程を文書化

HIPAAワークロードにクラウドサービスは使える?

BAA締結済みのAWS、GCP、Azure等なら利用可能。HIPAA構成ガイドに従い設定。

HIPAA違反の罰則は?

民事: 違反ごと100~50,000ドル、カテゴリごと最大年150万ドル

刑事: 最大25万ドル罰金・最大10年懲役


(※本記事内のリンク・画像・コード例は原文のまま維持)

Top comments (0)