In this section, you will implement HIPAA audit events using the SDK. Whenever protected health information (PHI) is displayed to users, those events need to be logged. One of the advantages of building a Bridge application is the centralized audit logging provided by an SDK method.
HIPAA Auditing¶
The audit logging functionality associates a user with clinical data from the Bridge data model. Currently, audit record creation is supported at the patient_mrn, rad_exam, and claim levels.
Best Practice - Some applications may not show the user every records requested from the server, i.e. a data structure with PHI that is updated client-side, but only displays an aggregate metric without the PHI. It is critical to still log that information: anything sent to a client/browser (even if not intended to be rendered) should be logged. While typical users will not see the data, a malicious actor or compromised workstation would have access to that data. In the case of an audit, the request URL and application name help to identify page display state.
To log an audit event, use the SDK method Java::HarbingerSdk::Hipaa.explicitLogger
. This method takes seven arguments:
- the approved unique application name
- the full HTTP request URL
- the IP of the the request (typically the IP of the computer running the web browser connected to the application)
- the user's SSO username
- the user's SSO domain
- the table name of the PHI (e.g.
rad_exams
orpatient_mrns
) - a list/array of primary keys of the records that will be shown to the user
Build a method in app/controllers/application_controller.rb
to use the SDK logger to submit audits:
# Takes a list of ORM objects (rad_exams, or patient_mrns, but NOT rad_exams and patient_mrns)
# and does the HIPAA auditing.
def log_hipaa_view(objects,options={})
if objects.size > 0
options.reverse_merge!({
:app_name => "rails-developer-tutorial",
:request_info => request.original_fullpath,
:requesting_ip => request.remote_ip,
:table_name => objects.first.class.table_name,
:username => session[:username],
:domain => session[:domain] || "not set in session",
:table_ids => objects.collect {|exam| exam.id }
})
objects.compact! if objects.class == Array
Java::HarbingerSdk.Hipaa.explicitLogger(
options[:app_name],
options[:request_info],
options[:requesting_ip],
options[:username],
options[:domain],
options[:table_name],
options[:table_ids])
end
end
This is a generalized method that accepts an Array of ORM objects, extracts the table name, then builds the explicitLogger
call. This method also presents the option to override some of parameters in the audit event (via the options argument) and will safely ignore the call if an empty Array is passed.
Note - The comments in the code above also note that you cannot send ORM objects of more than one type to this method in a single call. You can send an Array of
rad_exams
or an Array ofpatient_mrns
but not an Array of bothpatient_mrns
andrad_exams
in a single call.
This enables HIPAA logging to be added to the views in the WorklistController
. Edit app/controllers/worklist_controller.rb
in index
method:
def index
query = Java::HarbingerSdkData::RadExam.createQuery(@entity_manager)
expression = query.equal(".currentStatus.universalEventType.eventType","complete")
query.where(query.and([expression,query.isNotNull(".radExamTime.endExam")]))
query.order(".radExamTime.endExam desc")
@exams = query.limit(100).list().to_a
log_hipaa_view(@exams)
end
This calls the log_hipaa_view
method and passes the rad_exam
objects set in the @exams
variable.