Correct use of AuditEvents in web applications / apps

I am currently implementing the AuditEvent resource in our system. The system stores data that is exchanged between practitioners and patients and its data is consumed through a web application and an app.

The goal of the audit log is to be able to reconstruct every change being made to the data as well as to record every request for data. I would like to hear your input to my questions and the proposed solution in order to figure out if I’m on the right track at all.

  • Accounting for the fact that other software may access our system through the FHIR interface, I believe that audit events should only be generated by the server system which only exposes Read, Search and Versioned Read access to the audit log.

    • I assume that this is the correct way of doing things.
  • Given that audit events are only generated by the server, this limits the amount of information available when creating an audit event. There is no way of dynamically setting AuditEvent.agent.type, AuditEvent.agent.role, etc. as this information can not be supplied to the server through the standard FHIR interface. Similar restrictions apply to the AuditEvent.purposeOfEvent and AuditEvent.entity.

    • My current approach is to only record who, name, requestor (always true), policy (OAuth token) and network for the agent. Does this make sense at all? Or should we try to tie users to certain roles for example?
  • In case that we should allow clients to supply custom audit events, there is still a lot of user input required in terms of AuditEvent.agent and AuditEvent.entity.

    • Is there any guidance on the level of detail that should be provided in the audit log? Asking the user why he or she is requesting information may be cumbersome but acceptable for a practitioner but certainly not suitable for a patient or a related person.
  • We consider using AuditEvent.source.site to store the current data center in a distributed server environment.

    • Is AuditEvent.source.site a suitable place for this type of information? Should we model each instance of the application as a device and track it as the observer in AuditEvent.source.observer?
  • The last question is around AuditEvent.entity.securityLabel. Again, this information can not be inferred from the server. Plus, even if it could be supplied by the client, it would need to be set by the user.

    • How should this field be used in general? Some observation codes for example could be statically mapped to different security labels, but I doubt this is the correct way. For other resources it may not be possible to provide static security labels. Again, it is very tedious for a practitioner to correctly label each event and certainly too error prone to without a significant reduction in the number of labels being used. Patients themselves can clearly not be bothered by making this assessment.

I hope it’s fine that I collected all of these questions in one point. I’ll be happy to split it up though or to restructure it in order to make the answers more helpful for others that stumble upon some of them in the future.

There are use-cases where a system might serve as a repository for audit information written by other systems (possibly about changes done somewhere else entirely). However, the interface you’ve described is most typical.

Agent type and role are typically gathered through the authorization process (e.g. oauth) and this information (or a link to it) is communicated through the HTTP headers.

What level of data is appropriate is driven by the use-case. For some types of action, it may be completely reasonable to ask ‘why’ regardless of who the user is. In other cases, less so.

Not sure about site - I’ve asked John Moerhke to share his thoughts

Security labels can be conveyed on all resources (in meta.security label). As well, they can be inferred by the server based on business rules/policy. Typically practitioners only label data in exceptional cases (e.g. patient asks provider to mark data that isn’t typically sensitive as ‘sensitive’.)

The AuditEvent is available for many uses. It is designed upon a long linage of standards focused on Security and Privacy. There is significant discussion on the questions you have within the referenced standards. I also have many articles I have written on this topic
https://healthcaresecprivacy.blogspot.com/p/topics.html#Audit

  • Yes the AuditEvent can be used in an environment where only the server logs data. In that case the richness of the record will be limited to the data that the server can know. This is clear in your follow on questions. Given that the clients accessing the data are proving that they are trustworthy of receiving patient data, then why are you not trusting them to record AuditEvent details? If you add a requirement that they need to record the security and privacy events as well, then you get pairs of audit events that can show two perspectives on the same event. And when you find the audit event is missing a pair, you have a security event to look into, that is to say the lack of a pair means that some client got a request to happen without your security keeping them out.
    –> so you certainly can use server only logging, but as you have seen that will be limited in detail.
  • As Lloyd has indicated the .agent detail can come from the client security token. Presumably you are protecting your service from non-authorized, by using some mechanism like OAuth. If you have OAuth, then you can use that. Either by inspection and transposing the details; or by logging the token id, because you also add a recording of the issuing of that token as an independent AuditEvent. In the second case, you correlate two AuditEvent to actually know who requested the data; which also has the benefit of having the detail logged by/when the most details is known…
    The alternative is to have the client record an AuditEvent with the more rich context of why IT is asking for the data. This can be much more rich than even the OAuth solution above, as it can include what part of a workflow triggered a need to ask for data.
    –> but if you are satisfied with the level of detail you are recording, that is all that is needed. Meaning your enforcement policy is more critical.
  • It would be unusual to prompt the user for information necessary for an audit log. The intention of the AuditEvent richness is to enable data to be recorded if it is known. If the element is not known then it is simply not provided. A critical principle of audit logging is that it is better to record some facts you know, then to not record an event because you don’t know all the facts.
  • The .source element is there to record what ‘detected’ the auditable event. This helps differentiate between server records, client records, intermediary records, security-layer records, etc. It might be useful to differentiate between which data-center detected the event. It seems this is what you are intending.
  • as Lloyd points out, the .securityLabel is just a copy of the .meta.security of the data returned. Your server surely knows this data. It is possible you are not planning on using the .meta.security mechanism, if so then you have nothing to put into .securityLabel. However the .meta.security is available for enabling data segmentation, attribute based access control, obligations, etc… The sum of all the Resources in a bundle would be “combined” into the .meta.security on the Bundle returned. Additional obligations or restrictions can be added to the Bundle .meta.security. The bundle .meta.security is what is recorded in the AuditEvent .securityLabel to indicate the tags returned.

John

Thank you both for your extensive answers. I’m still processing all of this information but already have some new questions.

Agent type and role are typically gathered through the authorization process (e.g. oauth) and this information (or a link to it) is communicated through the HTTP headers.

We do use OAuth. I assume that this means that an agent usually has one fixed role? I’m still struggling with this as a practitioner for example could edit one piece of information as an AMENDER while acting as a PRIMAUTH for other pieces of information.

With no further information, I would not set the role by default. PRIMAUTH and AMENDER in particular can often be derived from the history of individual resources. I would only specify a role in case a practitioner for example reviews care plans drafted by younger practitioners by using a special review page in the application.

Given that the clients accessing the data are proving that they are trustworthy of receiving patient data, then why are you not trusting them to record AuditEvent details?

My idea was to protect the audit log from intruders using a stolen or hacked account. They could forge audit events to pretend that another person has violated some policy by accessing information that they did not have a reason to.

The .source element is there to record what ‘detected’ the auditable event. This helps differentiate between server records, client records, intermediary records, security-layer records, etc.

Looking at your answer, I like the idea of different perspectives on the same event. I need to do some more thinking here but am confident, that I can address my original issue using your suggestion. I guess it is all about making sure that a client cannot set the source to be the server.

…the .securityLabel is just a copy of the .meta.security of the data returned. Your server surely knows this data. It is possible you are not planning on using the .meta.security mechanism, if so then you have nothing to put into .securityLabel.

Thanks, now I get it. We will indeed leave this away for v1 but will come back to it once we have the basics running.