Case Study 2: Pinnacle Health Insurance's HIPAA Security Implementation
Background
Pinnacle Health Insurance processes 50 million health insurance claims per month on a two-LPAR Parallel Sysplex. Every claim contains electronic Protected Health Information (ePHI): patient demographics, diagnosis codes, treatment details, provider information, and payment data. Under HIPAA, Pinnacle is a covered entity — a health plan — subject to the full HIPAA Privacy Rule, Security Rule, and Breach Notification Rule.
In 2021, Pinnacle underwent a significant security transformation. The catalyst was not an audit finding or a breach — it was Diane Okoye's arrival as systems architect. Diane came from a distributed environment (Java/Spring microservices at a health tech startup) and brought a modern security mindset to a platform with legacy security practices.
"When I arrived," Diane recalls, "the mainframe team had RACF. It was configured. It worked. But there was no security architecture — no documented threat model, no data classification scheme, no formal access control policy. Ahmad Rashidi had been trying to get the security posture modernized for years, but he was a compliance officer without a technical champion. I became that champion."
The Pre-Transformation State
Ahmad Rashidi documented the security posture Diane inherited:
What was good: - RACF was active with PROTECTALL(FAILURES) — no unprotected datasets - CICS transaction security was enabled for the primary claims processing transactions - DB2 connection control via RACF DSNR class was properly configured - SMF recording was active for types 30, 80, and 102
What was not good: - No encryption — neither dataset encryption nor DB2 column encryption for ePHI - No AT-TLS — EDI transmissions (837/835 claims files) from providers used FTP over unencrypted TCP - DB2 authorization was table-level, not column-level — anyone with SELECT on the CLAIMS table could see all columns, including diagnosis codes and treatment notes - The application audit trail was minimal — the COBOL programs wrote a "transaction processed" log entry but didn't capture which specific data fields were accessed - RACF access reviews were annual, not quarterly - No documented incident response plan - Four shared batch userids ran all batch processing — no per-job-function userid separation
Ahmad summarized the gap: "We met the letter of HIPAA's Security Rule — we could check every box on a compliance checklist. But we couldn't answer the auditor's real question: 'Can you prove that only authorized individuals accessed this specific patient's diagnosis codes in the last 90 days?' The honest answer was no."
The Transformation Plan
Diane and Ahmad designed a two-phase transformation plan with a total timeline of 18 months.
Phase 1: Foundation (Months 1-9)
Workstream 1: Data Classification
Ahmad led the data classification effort, categorizing every field in the claims database:
| Classification | Definition | Fields | Required Controls |
|---|---|---|---|
| PHI-Critical | Directly identifies patient + medical condition | Diagnosis codes, treatment notes, provider notes | Encryption + column-level access control + audit logging |
| PHI-Standard | Identifies patient (demographics) | Name, DOB, SSN, address, phone, member ID | Encryption + row-level access control + audit logging |
| PHI-Financial | Payment and billing data | Billed amount, allowed amount, paid amount, payment method | Encryption + role-based access control + audit logging |
| Non-PHI | Operational data with no patient identification | Claim status, processing timestamps, batch run IDs | Standard RACF protection |
This classification drove every subsequent technical decision. "We couldn't design the encryption strategy, the access control strategy, or the audit strategy without knowing what we were protecting and why," Diane said. "Data classification is the prerequisite for security architecture."
Workstream 2: Encryption Implementation
Pinnacle implemented encryption in three layers:
Layer 1: Dataset encryption. All datasets containing ePHI were migrated to SMS data classes with AES-256 encryption. This was transparent to applications — no COBOL changes required.
DATACLAS NAME(ENCHI)
KEYLABL1(PIN.PHI.AES256.PRIMARY)
KEYLABL2(PIN.PHI.AES256.BACKUP)
RACF CSFKEYS profiles controlled access to the encryption keys:
RDEFINE CSFKEYS PIN.PHI.AES256.PRIMARY UACC(NONE)
AUDIT(ALL(READ))
PERMIT PIN.PHI.AES256.PRIMARY CLASS(CSFKEYS)
ID(PINCICS) ACCESS(READ)
PERMIT PIN.PHI.AES256.PRIMARY CLASS(CSFKEYS)
ID(PINBATCH) ACCESS(READ)
PERMIT PIN.PHI.AES256.PRIMARY CLASS(CSFKEYS)
ID(PINAUDIT) ACCESS(READ)
Layer 2: DB2 column encryption for PHI-Critical fields.
ALTER TABLE PINNACLE.CLAIMS
ADD COLUMN DIAGNOSIS_CD_ENC VARCHAR(256) FOR BIT DATA;
UPDATE PINNACLE.CLAIMS
SET DIAGNOSIS_CD_ENC =
ENCRYPT_AES(DIAGNOSIS_CD, 'PIN.DIAG.AES256');
ALTER TABLE PINNACLE.CLAIMS
DROP COLUMN DIAGNOSIS_CD;
ALTER TABLE PINNACLE.CLAIMS
RENAME COLUMN DIAGNOSIS_CD_ENC TO DIAGNOSIS_CD;
This migration required changes to every COBOL program that accessed diagnosis codes — approximately 34 programs. The COBOL changes were straightforward (adding DECRYPT_AES calls to SELECT statements and ENCRYPT_AES calls to INSERT/UPDATE statements), but the testing effort was significant.
Layer 3: AT-TLS for all ePHI in transit.
Pinnacle replaced all unencrypted FTP connections with FTPS (FTP over TLS) using AT-TLS:
TTLSRule FTP_PROVIDER_EDI
{
LocalPortRange 21
Direction Inbound
TTLSGroupActionRef PROVIDER_GROUP
TTLSEnvironmentActionRef PROVIDER_ENV
}
TTLSEnvironmentAction PROVIDER_ENV
{
HandshakeRole ServerWithClientAuth
TTLSKeyringParmsRef PINNACLE_KEYRING
TTLSCipherParmsRef TLS13_CIPHERS
Trace 2
}
The ServerWithClientAuth setting requires providers to present a client certificate, providing mutual TLS authentication — Pinnacle authenticates the provider, and the provider authenticates Pinnacle.
Workstream 3: Batch Userid Separation
The four shared batch userids were replaced with function-specific userids:
| Old Userid | New Userids | Function |
|---|---|---|
| PINBAT01 | PINCLMRX (claims receipt), PINCLMVL (claims validation) | Claims intake |
| PINBAT02 | PINCLMAJ (claims adjudication), PINCLMPAY (payment calculation) | Claims processing |
| PINBAT03 | PINEDI83 (EDI 837 processing), PINEDI85 (EDI 835 generation) | EDI processing |
| PINBAT04 | PINRPT01 (regulatory reporting), PINRPT02 (management reporting) | Reporting |
Each new userid received the minimum RACF and DB2 permissions required for its specific function. The claims receipt userid (PINCLMRX) could INSERT into the claims staging table but could not read the adjudicated claims. The reporting userid (PINRPT01) could SELECT from aggregated reporting tables but could not access individual claim records.
"Breaking apart those shared userids was the single hardest change," Diane recalled. "Every batch job's JCL had to be updated. Every scheduler dependency had to be reverified. The operations team pushed back hard — 'What if something breaks at 2 AM and we can't figure out which userid to use?' My answer: the same answer you'd give for any other production change — we test thoroughly, we document the runbook, and we have a rollback plan."
Phase 2: Advanced Controls (Months 10-18)
Workstream 4: Column-Level DB2 Authorization
Ahmad designed the role-based access model described in Section 28.6.3 of the chapter:
-- Claims Processor role: demographics + payment, no clinical
CREATE ROLE PIN_ADJUSTER;
GRANT SELECT(CLAIM_ID, MEMBER_ID, PROVIDER_ID,
CLAIM_DATE, BILLED_AMT, ALLOWED_AMT,
PAID_AMT, CLAIM_STATUS)
ON TABLE PINNACLE.CLAIMS TO ROLE PIN_ADJUSTER;
-- Clinical Reviewer role: demographics + clinical, no payment
CREATE ROLE PIN_CLINICAL;
GRANT SELECT(CLAIM_ID, MEMBER_ID, PROVIDER_ID,
CLAIM_DATE,
DECRYPT_AES(DIAGNOSIS_CD, 'PIN.DIAG.AES256'),
PROCEDURE_CD, TREATMENT_NOTES)
ON TABLE PINNACLE.CLAIMS TO ROLE PIN_CLINICAL;
-- Customer Service role: demographics + status only
CREATE ROLE PIN_CUSTSVC;
GRANT SELECT(CLAIM_ID, MEMBER_ID, CLAIM_DATE,
CLAIM_STATUS)
ON TABLE PINNACLE.CLAIMS TO ROLE PIN_CUSTSVC;
-- Audit role: everything
CREATE ROLE PIN_AUDIT;
GRANT SELECT ON TABLE PINNACLE.CLAIMS TO ROLE PIN_AUDIT;
The implementation required modifying every COBOL program to use role-specific SQL views rather than direct table access. Ahmad created views for each role that exposed only the authorized columns:
CREATE VIEW PINNACLE.V_CLAIMS_ADJUSTER AS
SELECT CLAIM_ID, MEMBER_ID, PROVIDER_ID,
CLAIM_DATE, BILLED_AMT, ALLOWED_AMT,
PAID_AMT, CLAIM_STATUS
FROM PINNACLE.CLAIMS;
GRANT SELECT ON PINNACLE.V_CLAIMS_ADJUSTER
TO ROLE PIN_ADJUSTER;
COBOL programs were then modified to use the views instead of the base tables:
* Before: direct table access (all columns accessible)
EXEC SQL
SELECT CLAIM_ID, MEMBER_ID, BILLED_AMT,
ALLOWED_AMT, PAID_AMT, CLAIM_STATUS
INTO :WS-CLAIM-ID, :WS-MEMBER-ID,
:WS-BILLED-AMT, :WS-ALLOWED-AMT,
:WS-PAID-AMT, :WS-CLAIM-STATUS
FROM PINNACLE.CLAIMS
WHERE CLAIM_ID = :WS-SEARCH-CLAIM
END-EXEC
* After: view access (only authorized columns visible)
EXEC SQL
SELECT CLAIM_ID, MEMBER_ID, BILLED_AMT,
ALLOWED_AMT, PAID_AMT, CLAIM_STATUS
INTO :WS-CLAIM-ID, :WS-MEMBER-ID,
:WS-BILLED-AMT, :WS-ALLOWED-AMT,
:WS-PAID-AMT, :WS-CLAIM-STATUS
FROM PINNACLE.V_CLAIMS_ADJUSTER
WHERE CLAIM_ID = :WS-SEARCH-CLAIM
END-EXEC
Workstream 5: Application Audit Trail Enhancement
The minimal "transaction processed" log was replaced with a comprehensive audit trail that captures PHI access events:
01 WS-PHI-AUDIT-RECORD.
05 WS-PHI-TIMESTAMP PIC X(26).
05 WS-PHI-USERID PIC X(08).
05 WS-PHI-TERMINAL PIC X(04).
05 WS-PHI-TRANID PIC X(04).
05 WS-PHI-ACTION PIC X(10).
88 PHI-VIEW VALUE 'VIEW'.
88 PHI-CREATE VALUE 'CREATE'.
88 PHI-UPDATE VALUE 'UPDATE'.
88 PHI-DELETE VALUE 'DELETE'.
05 WS-PHI-MEMBER-ID PIC X(12).
05 WS-PHI-CLAIM-ID PIC X(15).
05 WS-PHI-DATA-CLASS PIC X(12).
88 DC-CRITICAL VALUE 'PHI-CRITICAL'.
88 DC-STANDARD VALUE 'PHI-STANDARD'.
88 DC-FINANCIAL VALUE 'PHI-FINANCL'.
05 WS-PHI-COLUMNS PIC X(200).
05 WS-PHI-RESULT PIC X(10).
05 WS-PHI-REASON PIC X(50).
The WS-PHI-COLUMNS field records which specific columns were accessed — not just that the claim record was viewed, but whether the user viewed diagnosis codes, treatment notes, or payment details. This enables Ahmad to answer the auditor's key question: "Who viewed this patient's diagnosis codes in the last 90 days?"
Workstream 6: Incident Response Plan
Diane and Ahmad developed Pinnacle's first formal incident response plan for ePHI security incidents:
Decision tree for ePHI incidents:
Incident detected
|
+-- Is ePHI confirmed compromised?
|
+-- YES: Is the ePHI encrypted?
| |
| +-- YES (encrypted): Security incident, NOT a breach
| | -> Investigate and remediate (internal)
| | -> No notification obligation (Safe Harbor)
| |
| +-- NO (unencrypted): BREACH
| -> 60-day notification clock starts NOW
| -> Notify General Counsel immediately
| -> Engage breach response team
| -> Determine scope (how many individuals?)
|
+-- NO / UNKNOWN: Investigate
-> 72-hour investigation deadline (internal SLA)
-> If confirmed: re-enter decision tree
-> If ruled out: document and close
"The decision tree was Ahmad's idea," Diane says. "He said, 'When you're in the middle of a 3 AM security incident, you don't have time to read the HIPAA regulations. You need a decision tree that tells the on-call person exactly what to do and when.' He was right. We laminated it and posted it in the operations center."
Outcomes
After 18 months, Pinnacle's security posture was transformed:
| Metric | Before | After |
|---|---|---|
| Dataset encryption coverage for ePHI | 0% | 100% |
| Column-level encryption for PHI-Critical fields | 0% | 100% |
| Network encryption for ePHI in transit | 0% | 100% (AT-TLS) |
| DB2 authorization model | Table-level | Column-level with roles |
| Batch userids | 4 shared | 8 function-specific |
| Application audit trail | Transaction-level | Field-level |
| Audit log retention | 1 year | 7 years |
| Access reviews | Annual | Quarterly |
| Incident response plan | None | Documented, tested quarterly |
| HIPAA audit response time for "who accessed this patient's data" | Hours (manual search) | Seconds (automated query) |
Cost of the transformation: - 18 months of project work (Diane full-time, Ahmad 50%, 2 additional developers) - 34 COBOL programs modified for DB2 column encryption - All batch JCL updated for userid separation - 200 GB/month additional DASD for enhanced audit logs - Zero production outages during the transformation
Cost avoided: - In 2023, Pinnacle experienced a security incident: a former employee's userid (not yet revoked) was used to access the claims system from a VPN connection. Because all ePHI was encrypted and the former employee did not have access to the CSFKEYS encryption keys (that access had been automatically revoked when the userid was suspended), the incident was classified as a security event, not a breach. No patient notification was required. - Ahmad estimates the cost of a breach notification for the 50,000 claims that the userid could have theoretically accessed: $150-$200 per individual (credit monitoring, legal, administrative costs) = $7.5M-$10M. The entire 18-month transformation cost less than $2M in labor and infrastructure.
Ahmad's Compliance Framework
Ahmad codified Pinnacle's HIPAA compliance into a quarterly review framework:
Quarterly Review Checklist (90-day cycle):
-
Access Review: Pull RACF access list for all ePHI datasets and DB2 roles. Verify each userid against current HR records. Revoke access for terminated/transferred employees.
-
Encryption Verification: Verify all ePHI datasets are in encryption-enabled SMS data classes. Verify all PHI-Critical DB2 columns are encrypted. Verify AT-TLS is active on all ePHI-carrying network ports.
-
Audit Log Integrity: Verify SMF recording is active for types 80, 102, 110. Verify audit log retention meets 7-year requirement. Run a sample audit query: "Who accessed patient [random sample] in the last 90 days?"
-
Key Management: Verify encryption key rotation (quarterly for data keys). Verify dual control for master key access. Verify key backup and recovery procedures.
-
Incident Response: Review any incidents from the last 90 days. If no incidents occurred, run a tabletop exercise.
-
Batch Userid Review: Verify each batch userid's permissions match its documented function. Check for any permission creep (new GRANTs added since last review).
Discussion Questions
-
Diane's security transformation took 18 months and modified 34 COBOL programs. Many of those modifications were straightforward (changing table names to view names, adding encryption function calls). Would you classify this as a "security project" or a "technical debt project"? Does the classification matter?
-
Ahmad's data classification scheme has four levels. Is this the right number? What would change if Pinnacle added a fifth classification for "anonymized data" or a sixth for "de-identified data" under HIPAA's de-identification standard?
-
The former employee incident was contained because encryption keys were revoked when the userid was suspended. This worked because Pinnacle's offboarding process included CSFKEYS profile removal. What would have happened if CSFKEYS access had not been revoked? Design the offboarding checklist for ePHI access.
-
Pinnacle's column-level access model uses DB2 views to expose only authorized columns to each role. An alternative approach is to use a single COBOL program with in-application role checking (using EXEC CICS QUERY SECURITY). Compare the two approaches in terms of security, maintainability, and performance.
-
Ahmad's quarterly review takes approximately 40 hours of analyst time per cycle. Is this sustainable for a mid-size organization? How would you automate portions of the review?