From openmed-skills
Generates and verifies 21 CFR Part 11 audit trails for OpenMed pipelines in GxP/clinical-trial settings, with electronic signatures and tamper-evidence.
How this skill is triggered — by the user, by Claude, or both
Slash command
/openmed-skills:auditing-part11-trailsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
In FDA-regulated **GxP** work (GCP clinical trials, GLP, GMP) any electronic
In FDA-regulated GxP work (GCP clinical trials, GLP, GMP) any electronic record used to support a regulatory decision must meet 21 CFR Part 11: it has to be attributable (who), contemporaneous and time-stamped (when), describe what changed, be tamper-evident, and — where a signing event occurs — carry a controlled electronic signature. These map onto the ALCOA+ data-integrity expectations (Attributable, Legible, Contemporaneous, Original, Accurate, +Complete/Consistent/Enduring/Available).
OpenMed's deidentify(..., audit=True) already emits a deterministic,
PHI-free AuditReport that you can .sign() (HMAC-SHA256) and later
.verify(). That gives you the tamper-evidence and attribution primitives;
this skill wraps them in the who/when/what/e-signature envelope Part 11 wants.
This is a compliance-enablement aid. Part 11 compliance also requires validated systems (CSV), SOPs, and access controls that live outside any single library — a QA/validation lead signs off.
AuditReport with who/when/what + an
e-signature manifestation (meaning, signer, timestamp).| Part 11 expectation | 21 CFR cite | OpenMed mechanism |
|---|---|---|
| Tamper-evident, accurate copies | 11.10(b),(c) | AuditReport.to_json() + repro_hash over the canonical payload |
| Audit trail: what changed, when | 11.10(e) | AuditReport.spans (action per identifier), input_hash/deidentified_text_hash, openmed_version, manifest_hash |
| Operational/authority checks; attribution | 11.10(d),(g) | AuditSignature.key_id (signer/key identity) + your envelope's user id |
| Signature manifestation (name, date, meaning) | 11.50 | Your envelope fields signer, signed_at, meaning |
| Signature/record linking, non-repudiation | 11.70, 11.200 | HMAC-SHA256 over the canonical payload via .sign() / .verify() |
The HMAC binds the signature to that exact report content: any later edit to a
span, hash, or field changes repro_hash, so .verify() fails — that is the
tamper-evidence.
import openmed, json, datetime as dt
note = "Subject S-014 (DOB 1962-08-09) reported headache on 2024-05-01."
# 1) Produce the deterministic, PHI-free audit record for this processing step.
report = openmed.deidentify(note, policy="hipaa_safe_harbor", audit=True)
# 2) Sign it with a controlled release key (stored in a vault / HSM, never in code).
report.sign(b"<release-hmac-key>", key_id="omv-signer-2026")
# 3) Wrap in a Part 11 envelope: who / when / what / signature meaning.
trail = {
"record": report.to_dict(), # tamper-evident, no PHI
"who": "[email protected]", # authenticated user (your IdP)
"when": dt.datetime.now(dt.timezone.utc).isoformat(),
"what": "PHI de-identification of source narrative (study X, subject S-014)",
"signature_manifestation": { # 21 CFR 11.50
"signer_printed_name": "Jane Smith",
"meaning": "reviewed and approved",
"signed_at": dt.datetime.now(dt.timezone.utc).isoformat(),
},
"system": {"openmed_version": report.openmed_version,
"manifest_hash": report.manifest_hash},
}
with open("part11_trail.json", "w") as fh:
json.dump(trail, fh, indent=2, sort_keys=True)
# 4) Later — verify integrity (optionally bind to the exact source/output text).
ok = report.verify(b"<release-hmac-key>", original_text=note)
assert ok, "AUDIT TRAIL TAMPERED OR KEY MISMATCH"
audit=True to get the deterministic record.key_id.
Never embed the key in source or the trail..verify(key, original_text=..., deidentified_text=...)
to confirm neither the record nor the bound texts changed.auditing-deidentification-runs
(deidentify(audit=True) → AuditReport) is the source of the signed,
PHI-free trail this skill envelopes.auditing-safe-harbor-checklist documents that the
18 identifier categories were handled — useful as a CSV artifact.enforcing-nophi-logging ensures the surrounding
application logs don't leak identifiers into the trail.checking-hipaa-compliance — Part 11 audit controls and the
HIPAA Security Rule audit-controls standard (164.312(b)) reinforce each other.AuditReport gives tamper-evidence and
attribution, but Part 11 also requires validated systems (CSV), SOPs, training,
and access controls you implement around it. Don't claim "Part 11 compliant"
from the audit object alone..sign() is a deliberate step; signature
is None until called. Empty/None keys are rejected.key_id, and never store the key with the trail.AuditReport is hash-and-offset only; don't
reintroduce identifiers in the what/who free-text fields.report.to_json().openmed/core/audit.py.npx claudepluginhub maziyarpanahi/openmed --plugin openmed-skillsProduces signed, PHI-free audit trails for OpenMed de-identification runs. Use for HIPAA/GDPR compliance evidence, verifying redactions, and reviewing de-id decisions without exposing plaintext.
Implements electronic signatures compliant with 21 CFR Part 11 Subpart C and EU Annex 11 for GxP records, covering signature manifestation, binding, biometric/non-biometric controls, policy creation, and user certification.
Audits applications and infrastructure for HIPAA compliance: Security Rule safeguards, Privacy Rule, Breach Notification Rule, ePHI scoping, BAA chain, and minimum-necessary standard.