How to comply with the FDA part 11 digital signatures in Epicor 10.2.300+

The question comes up pretty often. Is Epicor FDA compliant? Can we use the corrective action system in Epicor or what? Is the DMR process ok or do I have to keep doing it on paper? The answer out of the box is no, everything has to be done on paper.

FDA Part 11 has a requirement where if the record of an activity is recorded, a password must be provided. If a user has to record 5 activities, when they make each record a password must be given. A person should not be able to log in with their password once, make 5 records with no password prompt, then log out. The worry is that a different person could walk up to the terminal and start approving stuff under the user’s name.

In order to make a record, the FDA needs to know who signed what, and when (usually date only). We can use a BPM to write the current user ID to a custom field and the date to another field. That part is simple. The password requirement is the hard part but with the advent of Data Masking in 10.2.300 it gets much simpler. Since the QA department wanted to ditch their antique access database and paper record system, I thought I’d give it a try.

I wanted to create a custom field on the User table and use it to store the FDA password but it’s a huge pain setting anything like that up on that table so I just used one of the UD tables, UD03.

Key 1 is the user ID and the intentionally obscurely named ud01_c will store the corresponding user’s FDA password.

In Field Security Maintenance, I enabled Data Masking on that field.

For corrective actions, I created a matching custom field on DMRCorAct_ud and applied the same Data Masking.

I have a heavily customized form for corrective actions. in the verification area, there is a field for the user to click ‘CAR Verified’ and enter their FDA Authorization code. For non-security manager users the code field will always just display asterisks.

Upon save, an In-Transaction Data Directive on DMRCorAct will do the following:

  1. If the verify box is changed from false to true (this is a custom field) then proceed.

  2. Make sure user is in the CAR Managers security group, an extra level of security.

  3. Set the FDACode variable to what the user entered.
    image

  4. By query, make sure the FDA code the user entered matches the one for the current user on table UD03.
    image

  5. Check for completeness of the form (previous steps marked complete)

  6. Writes the current user ID to a custom verified by field.

  7. Sets ttDMRCorAct.AuditDt field of the changed row to the DateTime.Now expression (this will close the corrective action in the system will make the form read only using Epicor built in functionality)

  8. Clear the FDA code from ttDMRCorAct, there is no reason to save it.

As long as testing this functionality is part of a controlled software validation protocol, there should be no reason to reject this methodology by ISO or GMP auditors.

“Security by obscurity” is frowned upon.

How would an audit deal with the fact that passwords change?

If I created a record last year, and have since changed my password, how would you confirm that the password recorded with the transaction was valid at the time?

I’m thinking that a BPM that prompts for the users E10 password (like the login screen) - prior to creating each transaction. would suffice.

I wonder if there is an Epicor DLL, or someway to validate a user/password combo. Only allow the record to be created if that check passes.

I’m really sure you don’t want to store a password with the transaction record. The minimum to do would be to store a hash generated from the userID, Date, and some unique Record ID. During an audit, the record could be validated by creating the hash for the user/date/recordID combo, and seeing if matches the has stored with the record

Does the password have to be different than their Epicor password? You can force them to enter that, without creating your own insecure password storage.

2 Likes

Evan, it does not have to be a different password. Great suggestion, had no idea that functionality existed. How would that work with SSO? Would it prompt for windows PW?

We have pseudo-SSO (we use Windows binding), and a BPM Form with the password field, checks it against epicor password.

Also, there is no option to specify the user the password is for. The password entered is only checked against currently logged in user.

And a HUGE security issue exists in the fact that the password entered is passed to the BPM in plain text.

Ew. That isn’t great.

@Bart_Elia what would be the recommended way of securely forcing a user re-authenticate?

Not the BEST alternative security wise but their is a legacy API on Ice.UserFile just for these ad hoc checks. HUGE concerns about ensuring that the wire is encrypted but I just took a minute to create a Function to do this.

Create a Function with user / password parameters:

Then in the function, call the method of interest:

Now call the Function from a client form. Place behind a button or action where you want to trigger a pop up form to force the user to enter their credentials.

NOTE - One of the nice things about this is that calling a function can only be done by a logged in user so that reduces some risk.


So as long as the REST call is made over a TLS connection this would be considered acceptable…? Isn’t that required for Epicor REST access or is that only enforced for MT cloud users?

1 Like

You need to jump through hoops to turn off https.
TLS x.y support is a negotiation of what is turned on both client and server.

Aright so I am trying to make certain - the wire is encrypted by default for REST so this huge concern is met, right?

1 Like

correct.

1 Like

Just curious, do failed calls (as in password incorrect for the userID) count against the lockout policy? Or could some malicious actor use this to brute force a password?

Supplying credentials to a transaction is very important for Part 11 compliance. Also consider requirements for audit trail and preventing deletion of data. We have had to define which fields require change log data directives. We also had to write BPMs to prevent deletion of data. Another consideration is that we had to disable fields that allow users to change the LotNum value. Epicor allows users to enter transactions that might not be appropriate in a Part 11 environment. Providing audit trails and ensuring that data are complete are also important Part 11 factors.

This is true, out of the box the CAPA system does not even comply with ISO 9001 much less ISO 13485 or 21 CFR 820. For us, the amount of BPM work was pretty intense. We created a procession of ‘capa stages’ from assignment to verified with lots of logic in between. Nobody can delete a CAPA but someone in the car manager security group can void it with a required note.
Due to the low level of activity (maybe a CAPA a week) I turned on logging on everything. Additionally, if someone for example indicates that risk review was completed, a BPM will record their user name and date into a separate custom field which displays on the customized form.

I am still confused as to why building a custom function is better than using the built in BPM form functionality.

Also I have switched to the out of box BPM form for password prompting in my CAR system. For some reason my original post can’t be edited to reflect what I’m actually doing. Can we blow this away and start over?