跳轉到

FDA 21 CFR Part 11 合規

FDA 21 CFR Part 11 規範製藥、生技、醫療器材等受管制產業的電子記錄(Electronic Records)電子簽章(Electronic Signatures)的合規要求。NextPDF Enterprise 在 PDF 生成層直接實施這些要求,確保每份文件天生具備可舉證的合規性。


法規要求對應

21 CFR Part 11 條款 要求 NextPDF Enterprise 實現
§ 11.10(a) 系統驗證 確定性文件生成、內容雜湊驗證
§ 11.10(b) 準確可讀副本 PDF/A-4 符合性(不可變格式)
§ 11.10(c) 記錄保護 WORM 模式、不可修改封存
§ 11.10(d) 稽核追蹤 FdaAuditTrail — 不可刪除時間序列日誌
§ 11.10(e) 使用者存取控制 CompliancePolicy 強制身份驗證
§ 11.50 簽章關聯 簽章與簽署者、時間、含義不可分離
§ 11.70 簽章與記錄連結 數位簽章嵌入 PDF 本體,非附加
§ 11.100 簽署者身份唯一性 每位簽署者使用唯一憑證

核心 API

FdaAuditTrail

稽核追蹤是 21 CFR Part 11 § 11.10(d) 的核心要求,必須記錄所有建立、修改、刪除操作,且日誌本身不可被修改或刪除。

use NextPDF\Enterprise\Compliance\Fda\FdaAuditTrail;
use NextPDF\Enterprise\Compliance\Fda\AuditEntry;

$auditTrail = FdaAuditTrail::create(
    storageAdapter: $immutableStorageAdapter,
    hashAlgorithm: 'SHA-384',
    requireTimestamp: true,
);

// 每次文件操作自動記錄
$auditTrail->record(
    AuditEntry::documentCreated(
        documentId: $doc->id(),
        userId: $currentUser->id(),
        userName: $currentUser->fullName(),
        timestamp: new DateTimeImmutable(),
        ipAddress: $request->ip(),
        action: 'DOCUMENT_CREATED',
        reason: 'New batch record for Lot #2025-A-001',
    )
);

PHP Compatibility

This example uses PHP 8.5 syntax. If your environment runs PHP 8.1 or 7.4, use NextPDF Backport for a backward-compatible build.

SignatureEnforcer

use NextPDF\Enterprise\Compliance\Fda\SignatureEnforcer;
use NextPDF\Enterprise\Compliance\Fda\CompliancePolicy;
use NextPDF\Enterprise\Compliance\Fda\ElectronicSignature;

$policy = CompliancePolicy::fda21CfrPart11(
    requireElectronicSignature: true,
    requireSignatureReason: true,
    requireSignatureTimestamp: true,
    auditTrailRetentionYears: 7,
    enforceUserAuthentication: true,
    allowedSignatureAlgorithms: ['RSA-PSS-SHA384', 'ECDSA-P384'],
);

$enforcer = new SignatureEnforcer(
    policy: $policy,
    auditTrail: $auditTrail,
);

$signature = ElectronicSignature::create(
    signerCredential: $pkcs12Credential,
    reason: '批准:批次放行記錄',
    location: 'Quality Control Lab, Taipei',
    contactInfo: 'qa@acmepharma.com',
);

$signedDocument = $enforcer->sign(
    document: $document,
    signature: $signature,
    signerIdentity: $currentUser,
);

CompliancePolicy

use NextPDF\Enterprise\Compliance\Fda\CompliancePolicy;

// 工廠方法涵蓋最常見的合規情境
$policy = CompliancePolicy::fda21CfrPart11(/* ... */);
$policy = CompliancePolicy::gmpBatchRecord(/* ... */);
$policy = CompliancePolicy::clinicalTrialRecord(/* ... */);

// 或完全自定義
$policy = CompliancePolicy::custom()
    ->requireSignature()
    ->requireAuditTrail(retentionYears: 7)
    ->enforceTimestampAuthority('https://tsa.acmepharma.com')
    ->prohibitModificationAfterSignature();

文件生命週期

flowchart LR
    A[草稿建立] -->|AuditEntry: CREATED| B[內容填寫]
    B -->|AuditEntry: MODIFIED| C[審核中]
    C -->|AuditEntry: REVIEWED| D{需要修改?}
    D -->|是| E[退回修改]
    E -->|AuditEntry: RETURNED| B
    D -->|否| F[電子簽章]
    F -->|AuditEntry: SIGNED| G[封存鎖定]
    G -->|WORM 保存 7年| H[到期歸檔]

驗證:批次放行記錄

以下展示完整的 GMP 批次放行記錄合規流程:

use NextPDF\Enterprise\Compliance\Fda\FdaComplianceBundle;

// FdaComplianceBundle 整合所有 FDA 合規元件
$bundle = FdaComplianceBundle::create(
    policy: CompliancePolicy::gmpBatchRecord(retentionYears: 7),
    auditStorage: $wormStorageAdapter,
    tsaUrl: 'https://tsa.acmepharma.com',
);

$batchRecord = $bundle->createDocument(
    template: BatchRecordTemplate::lot(lotNumber: '2025-A-001'),
    author: $currentUser,
);

// 填寫數據後強制簽章
$batchRecord = $bundle->signAndLock(
    document: $batchRecord,
    signer: $qaManagerCredential,
    reason: '批次合格,授權放行',
);

// 自動封存至不可變存儲
$archiveRef = $bundle->archive($batchRecord);

常見合規陷阱

陷阱 風險 NextPDF Enterprise 防護
簽章後仍可修改文件 FDA 483 觀察 簽署後自動鎖定,修改嘗試拋出 PolicyViolationException
稽核日誌可被刪除 Warning Letter FdaAuditTrail 使用不可變儲存介面,拒絕刪除操作
時間戳記由用戶端產生 不可信時間 強制使用外部 TSA(RFC 3161)
缺少簽署原因欄位 不符 § 11.50 CompliancePolicy 強制要求 reason 欄位非空
多人共用簽署帳號 不符 § 11.100 每個簽章對應唯一憑證,CN 綁定驗證

延伸閱讀