OSX, FreeRadius, Netscreen, and me

Oh, wow, this was crazy. What I needed to get done is to have a Juniper SSG-5 firewall (which runs Netscreen OS 6.2) authenticate users from the FreeRadius server that runs by default in OSX Snow Leopard server (10.6.3). And I needed the SSG-5 to differentiate depending on groups on Open Directory on the OSX. But, man, is this poorly documented… the only thing you find in the OSX documentation is how to get an accesspoint to allow users in. That’s it. Not good enough.

You can click any of the images in this post to see the screenshots full size

First, a list of documents you may need, or I may need later and don’t want to lose:

dictionary.freeradius.internal – an Apple document listing the attributes passed to FreeRadius.

A usegroup message with some useful examples

Using OSX Radius with third party devices – has some info on hunt groups

Make sure radius is running

Via Server Admin, make sure Radius is selected in the services tab so it occurs in your list of services in the left pane.

Then select “Radius” in the left panel, select “Settings” and click the dropdown for “RADIUS Certificate”. There you should either select a cert you already have installed on the server, or else select “Manage Certificates…” to go and create one. I already had one, and I had it created by CAcert, a free service for certificates of all kinds.

When you’ve got the cert sorted out, click the button “Edit Allowed Users…” and you’ll get to this screen:

See to it that you’ve selected “For selected services below:” in the left half of the right pane and that “RADIUS” is selected in the list. Then use the plus sign below right to add all groups you want to manage through Radius. Don’t forget to click the “Save” button when you’re done.

If you have any regular wireless access points you want to add, you can do that through the Server Admin as well, but you can’t add any other devices this way.

Just to see if things are more or less right, try to start the Radius server and then check the logs. You can do that by selecting RADIUS in the left panel, click the “Logs” tab on top and then play with the “Start RADIUS” and “Stop RADIUS” button at the bottom of the screen:

If it complains about the lack of any clients, don’t bother. Just leave it off, since we’ll add clients through the command line shortly.

Once you’ve played with this for a while and are satisfied that it is not too bad, you can leave the Radius server off. We’ll start it from the command line later.

It’s important to understand that all the groups you select here, and only those groups, are copied over to the user database in the Radius server. Any users that are not in one of these groups cannot ever be enabled through Radius; they’re simply not seen by the Radius server.

Also important to understand is the fact that this is as far as Apple goes in its GUI implementation of Radius. That is, any user that is enabled for Radius this way can log in to any Radius enabled wireless access points on your net. They don’t make any distinction according to user or group as to what you can do, nor do they implement anything else but wireless access points. This means that for more sophisticated usage, you have to proceed on your own, largely through the command line and config files.

Add clients to radius

A “client” is a piece of equipment that will ask the radius server to authenticate users, so clients are accesspoints, firewalls, maybe switches and routers. Each of these pieces of equipment that you want to have call the radius server needs to be configured in the server with its IP number and a shared secret (password). This shared secred is the same on both sides, so each piece has its secret shared with the radius server, but each pairing has another shared secret. If you want to add just Apple supported wireless access points, you can do that through Server Admin, but for everything else you have to do it as follows.

To add a client to the radius server, you use the radiusconfig utility on the OSX server:

sudo radiusconfig -addclient 172.16.200.241 ssg5 firewall

After you enter this command, radiusconfig will ask you for the shared secret. Remember it, because this is the same secret we will need to enter in the SSG-5 later. A side note: the last parameter is the type and I gave it as “firewall”. As far as I can see, it’s purely descriptive and you can call it “bigbrownbear” for all the difference it makes.

If you check the list of “Base Stations” in Server Admin, you’ll should see this client in the list, at least if Radius is running:

Add the DEFAULT entries to the users file

Even though Radius users are held in an sql-lite database under OSX, the users file still does exist and is read. In this file, we can add in rules that will be processed for any user that is accepted by Radius, so we can add on values to be returned to the Radius client (in our case, the firewall). In the users file, you also have access to some information from Open Directory on OSX, so the users file is the place where information is transformed from OSX Open Directory to Radius clients. This is where the magic happens. We write all our rules for the magic user “DEFAULT”, which matches any user accepted by Radius. More than one rule may match a real user, and all of the matching rules will be applied.

Open the “/etc/raddb/users” file on the server with pico as root:

sudo pico /etc/raddb/users

In that file, towards the end, in among the other “DEFAULT” rules, add this one:

DEFAULT   Group-Name == "Parents"
     NS-User-Group = "majors"

What this rule does is that it checks if the user under OSX in open directory belongs to a group called “Parents” and if so it sends the NS-User-Group attribute with the value “majors” to the client, in this case our firewall. We’ll add another rule:

DEFAULT   Group-Name == "Children"
     NS-User-Group = "kids"

Note: I made the group names very different on the OSX Open Directory side (“Parents” and “Children”) and on the Radius client side (“majors” and “kids”) just to make it extra clear which group is which.

Set up authentication server on the SSG-5

Now we have to tell the SSG-5 how to find and talk to the Radius server. Log in on the SSG-5, go to “Configuration” – “Auth” – “Auth Servers” and click “New”.

Give the OSX Server a name, any name. It’s used to refer to this server when you create policies in the SSG-5 later. Enter the IP number, and select the “Auth” under “Account type”.

In the lower part, select “Radius” radio button, set the “RADIUS Port” to 1812, which is the default on the OSX FreeRadius server. Set the “RADIUS Accounting Port” to 1813, even though we don’t use accounting in this example. In the field “Shared Secret” you have to enter the same shared secret you entered while defining the SSG-5 client on the OSX Server using radiusconfig (see above). Leave the other fields unchanged and click “Save” at the bottom of the screen.

Add external groups to the SSG-5

We configured the OSX FreeRadius, via the DEFAULTS in the users file, to return groups “majors” and “kids” depending on who is logging on. Now we have to set up these groups on the SSG-5 as well. Go to “Objects” – “Users” – “External Groups” and click “New”.

In “Group Name”, write “majors”, then select the “Auth” checkbox for “Group Type”. Click the Ok button, then repeat the process for the “kids” group.

Now we do a policy

Now we finally arrive at the writing of policies that make use of the groups. In this example, I’m going to limit access to the dn.se site, Sweden’s largest newspaper, and I’ll only make it accessible to OSX users that belong to the “Parents” group on OSX. To do this, I’ll first have to make a policy that by default disallows everyone from accessing dn.se, then add a policy that allow members of the external group “majors” to access it anyway (remember that the OSX group “Parents” is translated to the group “majors” in the users file, so the external group is “majors” on the SSG-5). Let’s first do the policy that disallows all access to dn.se for everyone.

Go to “Policy” – “Policies”.

Select from “Trust” in upper left, to “Untrust” in upper right dropbox, then click “New”.

Use dig or nslookup from the command line to find the IP number for dn.se. As of the writing of this post, it was a single IP number: 62.119.189.4.

When the form opens, give the policy a reasonable name like “No DN”, leave the source address set to “Any”, but change the destination address to “62.119.189.4” and put in “32” in the mask field. The “Action” dropdown should be set to “Reject” and you can leave everything else as it was and click “Ok”.

Use the move tools in the policy list (far right) to move this policy to the top of the list. The policies are processed from top to bottom, so we want to make sure the rejection happens before any other policy may allow the connection.

Add another policy from “Trust” to “Untrust”, then fill it in as in the following screen:

Give it another name, in this case “Allow DN”. You can now select the destination address from the address book entry dropbox so you don’t have to type it in, it’s just a convenience since the SSG-5 now knows about this IP from the previous policy. The “Action” dropbox should now be set to “Permit”.

If this was all we did, we just simply nullified the previous policy, at least if we put this one above it in the policy list, and that would be pointless. Instead, click on the “Advanced” button at the bottom of the screen.

Now everything comes together. Enable “Authentication” by selecting that checkbox, then select “Auth Server” using the radio buttons. In the dropbox, select the auth server you created earlier, the MiniSL. Slightly to the right, you can select who is going to be authenticated and here you select “User Group”, then “External – majors”. If this selection isn’t available, check that you did define that external group as I described a bit earlier.

With all this done, save. In the list of policies, you should put this new policy at the top using the move tools in the last column so it ends up above the first policy we did that is set to reject connections to dn.se for everyone. The result should look like this:

Testing it all

If you started the Radius server through Server Admin, go there and stop it first. Log in to the OSX server and open a terminal shell. Start the Radius server in debug mode from here by:

sudo radiusd -X

This should get your Radius server running and you’ll see how it handles requests. Now go to a browser on any other machine on the local net and try to open dn.se. You should get a login dialog from the browser itself and if you provide a username and password from someone who is defined in the OSX Workgroup manager, is in the “Parents” group, then you should get access, else not.

I hope it works for you. If not, explore the raclient tool as well, since it’s very useful for finding configuration errors. Once it all works, stop the Radius server on the command line and go start it from Server Admin instead, so it runs as it normally would.

A little remark: if you change settings in the users file, you have to stop and start the Radius server again each time, else it won’t see the changes.

I’m planning to do a post on hunt groups as well, but I haven’t done them yet, so it could be a while.

Additional notes

You will find files with all the predefined attributes in the folder /usr/share/freeradius. Each type of equipment has its own file. The attribute names I used above come from the file “dictionary.netscreen”.

Problem: too much secretarial work

Since current electronic health-care record systems are largely text based, there is a large amount of text to be written after each encounter. In Sweden, doctors generally dictate the entry after each encounter, and a secretary then types it out. The same procedure is used for referrals, reports, and letters.

Brevity in notes is definitely something to strive for, but the dictation system lends itself to overly long notations instead. This, in turn, makes the text mass of the EHR grow faster than it otherwise would need to do, a problem I already discussed elsewhere.

Since secretaries are often overloaded with work, it takes a day or two, in the best of cases, before the notes actually show up in the EHR. It is not unusual to see a delay of two or three weeks between dictation and transcription. During that time, work is made more difficult for other doctors and staff, since the only recourse is to listen to an original sound track of the dictation, if you need the information, while it is almost impossible for anyone but a trained secretary to understand the garbled and mumbled monologue doctors are usually producing. It seems that the only thing worse than our handwriting is our dictation.

If the doctor dictated referrals, these also wait for days, or in the worst case weeks, before being sent off. Meanwhile, nothing happens and the patient is left suffering, waiting, and possibly drawing disability from the insurance as well.

The underlying problem here is that the health-care records are text based, due to the lack of a correct analysis of the problem domain. Since the user cannot interact with the object that should have been there but isn’t, the “disease”, he is forced to describe the interactions with words instead.

Problem: closed interfaces

Current electronic health-care systems are built as monoliths. They are constructed and sold as all-in-one solutions, largely because of the failure of care provider organizations to successfully manage collections of smaller, more specialized systems. This failure is caused by two factors:

  • The failure of the smaller vendors to cooperate and produce simple methods of supporting each other’s need for interconnection
  • The failure of IT departments at health-care institutions to actively seek out and support such best-of-breed solutions

Since the specifications are designed by the IT departments, and the negotiations with the vendors are also done by the IT department, the ultimate choice of system will be something that is primarily intended to keep the IT department budget within bounds. If that involves having less functionality for the ultimate users, that is not something the IT department is aware of. It also has no incentive to find out.

What appears to us as a problem of closed interfaces is then rooted in a deeper problem, namely that closed interfaces is exactly what the current IT departments wish for. First and foremost, they do not wish to have any open feature that enables the medical departments to ask for, and possibly get, the smaller best-of-breed systems they need for clinical care, since it would often involve committing more resources for IT configuration and support.

Ultimately, this is a problem of priorities. Currently, savings of IT department resources are clearly prioritized above the needs for better IT support on the floor. I find it very hard to believe that the savings achieved in the IT departments of our health-care institutions, if any, is anywhere near the cost to health-care in the form of delayed diagnoses, increased pain and suffering, and increased insurance costs. As long as the authorities let IT departments scrimp on medical IT support by specifying solutions that inhibits any attempts at improving health-care IT beyond what the all-in-one vendor deigns to produce, we will not be able to improve health-care by better IT use. This is basically a political problem.

Problem: confidentiality

Electronic health-care records must implement and respect confidentiality settings, such that certain care givers will not be able to view information that the patient may not want them to. There are many aspects to this problem, such as if the doctor should be able to break these confidentiality barriers in emergency situations, if the existence of hidden data should be indicated, and so on, but the only problem we will discuss in this section is to what entity the confidentiality is applied.

Currently, in Sweden at least, confidentiality is applied to entities such as care provider, document, referral, record notations, warnings, and prescriptions. Exactly which elements you can apply confidentiality attributes to, varies according to EHR system vendor.

The reason confidentiality has to be applied to all these peripheral data types is because the element you actually need to apply confidentiality to, the disease as such, does not exist in these systems. This explains both why there are so many complicated rules and elements and why it will always result in error.

Applying confidentiality causes different problems in each of these cases. A very short list of problems and dangers follows:

  • If applied to care provider, any non-confidential actions performed by that care provider will be hidden behind the confidentiality shroud as well. Also, any action taken by any other, non-included care provider for the confidential disease, will not be hidden and will divulge the existence of the condition. Something as simple as a general practitioner renewing a prescription for a drug used in schizophrenia, for example, will divulge the existence of the condition, regardless of the wishes of the patient.
  • If applied to prescriptions, the doctor will be unable to check for interactions and contraindications, resulting in outright danger to the patient. If the patient develops liver disease or renal failure or any other condition that would make a prescribed but confidential medication dangerous, the doctor will not know about that. The current EHR systems are also unable to warn for contraindications in these situations, since they have no concept of diseases or contraindications.
  • If applied to warnings, such as chronic infections, it puts medical staff at risk by not alerting them to the necessity of taking extra precautions while working with the patient
  • If applied to investigations, referrals, lab results, etc, then the same kind of dangers occur. Since the EHR is unaware of diseases as concepts, it is also totally unable to draw any conclusions on its own and issue warnings for possible medical errors due to the hiding of information.

The only medically responsible conclusion you can draw is that it is dangerous to apply any confidentiality of any kind to current medical health-care records. There is no way these systems can hide information in a way that makes the risk of serious error low enough to be acceptable. Sadly, the law mandates these confidentiality mechanisms, clearly prioritizing the patient’s right to confidentiality above medical safety. Personally, I don’t know if this is right or wrong, but the lawmaker is placed in the unenviable position of having to make such a choice by the unnecessarily poor design of current EHR systems.

Problem: too much text

This post is part of a series detailing the problems of current electronic healthcare records. To orient yourself, you can start at the index page on “presentation” on the iota wiki. You will find this and other pages on that wiki as well. The wiki pages will be continuously updated.

Current electronic health-care record systems contain huge amounts of textual data without any useful structure. The mass of text in itself becomes a big problem when there is no structure, standing in the way of the reader. Since there is no useful structure, the entire text must be read and internalized at every encounter where the patient is new to the doctor or if he hasn’t seen the patient recently, which in primary care is most encounters. If the amount of text could be reduced to the absolute essentials, then the reader might have a chance of getting through it, but we passed that point a while ago in most systems. That was a point of no return, as far as current EHR systems are concerned.

A number of initiatives coming from the outside of direct patient care result in an additional increase of the amount of non-essential or duplicated text. For example, a number of quality register initiatives and the “lifestyle” questionnaires add large amounts of text to the EHR, further obscuring the useful text we’re looking for.

Once a certain point is reached where the amount of text becomes too large to read before each encounter, several things happen, all of them bad:

  • The reader gives up on the EHR text and asks the patient instead. Since he needs to allow time for the patient to answer, he actually reads considerably less of the EHR than he did before. Most doctors I asked admitted to often reading just the one or two most recent entries before simply asking the patient for a short history.
  • Once the doctor does understand the essentials of the patient’s history, he usually summarizes the history and adds it to his own journal entry, so as not to lose it. This isn’t as useful as it may seem since it will scroll away beyond the “reading horizon” of two entries pretty soon. Once it has scrolled away beyond the “reading horizon” it isn’t useful anymore and only contributes to the enormous mass of unstructured text, reinforcing the vicious circle.
  • Not knowing what’s in a medical record is very stressful and tends to make doctors more defensive in writing new notes. These notes tend to be more elaborate than they need to be, once more further contributing to the mass of text.

In other words, as the EHR looks today, it is of critical importance to maintain the absolute minimum of text in the records and to avoid duplication and unrelated information as much as humanly possible. A disturbing number of government initiatives, however, result in exactly the opposite effect, interconnecting EHR systems over large geographic areas while at the same time sprinkling the EHR text mass with redundancies and irrelevancies to a degree that is outright dangerous.

Problem: no searcheability

This post is part of a series detailing the problems of current electronic healthcare records. To orient yourself, you can start at the index page on “presentation” on the iota wiki. You will find this and other pages on that wiki as well. The wiki pages will be continuously updated.

Since current electronic health care record systems have no knowledge of diseases as entities, we can’t drill down into the structure to locate necessary detail about the diagnosis or treatment of that disease. The information about diseases is spread out in the huge block of text that forms the EHR for a patient, so the only way to locate information in that is by searching on particular words or terms one could hope is related to the treatments one is looking for. Interestingly, not one of the EHR systems the author has seen has implemented even the most rudimentary search abilities such as “Find”. It’s hard to believe that these multimillion dollar systems don’t even have the features the lowly “Notepad” app has had since the inception of Windows in the 80’s, but that is the case. This leaves us with nothing else than eyeballing all the text manually, from start to finish. A clearly absurd state of affairs.

Search, even if implemented right, helps only in some edge cases. If you look for a reason why a certain medication was given or not given, it can help. If you look for treatments for a known disease, it can also help, but if you look for issues in the patient’s history that you don’t know about yet (the most important and most frequent search we do in an EHR in primary care), you’re out of luck even with a search function since you don’t know what you are searching for. A search can fill the function of an index, but not of a table of contents.

A summary of contents could be in the form of a “tag cloud”, but no EHR the author is aware of has even attempted to implement any such feature. Implementing a “tag cloud” of terms used in a medical record, if done right and with taste, could make the search problem somewhat more tractable by making it easier to navigate the old unstructured information from current EHR systems. It would not by any means replace “issues” as a structure, but would be helpful when linking legacy information to “issues” in a modern iotaMed based EHR.

In specialist care, the balance is somewhat different. Since searching for unrelated diseases is less frequent, a search on words or terms is relatively more important (one more often knows what one is looking for) and both a “Find” function and a “tag cloud” are even more sorely missed than in primary care. Even though both of these functions would be very useful, their usefulness arises from the fact that the lack of “issues” makes the EHR information such a mess to begin with. In the presence of “issues”, there would rarely be a reason to do a free search at all over an EHR, since information would be found in the place where it belongs.

This is not a reason to cast aside “Find” and “tag clouds” even for specialist care, since the legacy data in current EHR systems will be with us for a very long time still, before it all can be linked up with “issues” and brought into an “issue”-based structure. And even then, in that far future, “Find” and “tag clouds” will be essential tools, albeit not anymore the only tools to aid in the comprehension of the medical record.

Problem: no current status

The entries in our electronic health care records as they are currently built, only give us a chronological list of measurements and changes of the patient’s condition and investigations and treatments applied to him. A number of these steps naturally result in a change in the status of the patient, such as becoming less ill (if cured), having one leg less (after an amputation), having cardiac insufficiency (after a myocardial infarction) and so on. It would be only natural to always have a current picture of how the patient is and apply those changes to him, but that is not the case. There is no such current picture available in the medical record. To know how many legs the patient has, we have to assume he started out with two, then try to find any note in the EHR that indicates he lost one or more legs, to finally arrive at the current count. If we miss a record, we reach the wrong conclusion. You would be excused if you found it much more rational to check the actual patient and count his legs, in this situation.

When we paint our red house green, it is a green house from that point forward. However, if we reasoned according to medical records, it would still be a red house, albeit painted green on a certain date by a certain person who works in a certain department. If all I need to know is that the house is in fact green, that is a very circuitous description of a green house, but that is how we work. Actually, this example may seem contrived, but it’s over simplified. In real medical life, we would probably find records of the house being painted both blue, black, and all shades of pink, but unless we caught all these records and got them in the right order, it would be very difficult to be certain of the current color of that red house.

It’s painfully obvious that we absolutely must have a record of the current state of the patient in the EHR, but so far, I’ve not seen a single EHR system that even attempts to implement that. A curious state of affairs, indeed.

Problem: no archiving

Patients naturally progress through life by accumulating some diseases and becoming cured from other diseases. The accumulated diseases are what we call “chronic diseases”. Typical examples are diabetes, rheumatoid arthritis, vascular disease, hypertension, etc. Other, temporary, diseases are for example: bone fracture, most infections, myocardial infarctions (except for the underlying vascular disease), and an increasing number of cancers.

When you look at a patient’s medical records, you do want to be alerted to his chronic diseases, since most of them are relevant in the context of diagnosing new problems or treatment of a new or old problem. You also want to be able to see a list of resolved temporary diseases or afflictions, in particular when you’re diagnosing something new and don’t know what you’re looking for. But most of the time, the resolved diseases or afflictions from times gone by only clog up the records and stand in the way when you try to form an accurate picture of the patient’s history.

As an example, you may find a patient with a history of urinary infections, maybe once a year, where the annotations due to urinary infections can form half or more of the total volume of text in the medical record. None of that is interesting when the patient presents with chest pains (for example), but it severely diminishes our ability to find the annotations that are relevant to the chest pains in between all that urinary bladder gunk.

It would be wrong to erase the information about urinary infections, of course, since the chest pain may possibly have something to do with it (unlikely), and it’s important to maintain a count of how frequent these infections are, since if they recur often and during a long period, they may indicate a more severe problem that may need more thorough investigation, but these infections definitely do not warrant occupying prime screen real estate when I’m clearly looking for something else. I should be able to see just a one-liner mention of “urinary tract infection” for each such infection, and be able to read all about it only if I explicitly asked the system to show me.

This sounds like it ought to be a piece of cake to do, but in reality it’s close to impossible, since the system doesn’t have a clue that the annotations for all these urinary infections all belong together, simply because, you guessed it, the EHR has no concept of “disease”.

You can also find this page on the iotaMed wiki, here.

Problem: no contraindications

Electronic health care record systems are widely and frequently claimed to reduce injury and death due to prescription errors, since they are able to detect and warn for interactions between products. This claim is largely nonsense, because of the following:

  • Interactions between products are not the only dangerous effects we have from bad prescriptions
  • Interactions aren’t even among the most important dangers
  • Most doctors know of most important interactions and do not generally need these warnings
  • Most warnings we do get from these systems are hilarious or tragic, or plain boring, depending on your mood. They are rarely useful.

Most of these warning systems actually contribute to the danger instead of reducing it, simply because of their existence. It’s too easy for trusting young (or old) doctors to rely on the system to warn for interactions, creating a habit of optimistic prescribing. These users don’t realize how bad these systems generally are, so they adopt dangerous behavior and simply try out prescriptions just to see if they get warnings. If not, they prescribe.

The real problem, however, is contraindications. The presence of certain diseases makes it dangerous to administer certain therapies. A number of classes of medications should not be used if the patient is pregnant or has an enlarged prostate, certain cardiac arrythmias, or glaucoma of the eye, just to name a few examples. Some of these contraindications are deadly and most are hard to remember and easy to miss. But nobody talks about them, since our EHR systems, due to the lack of the concept of “disease” in some form, are totally unable to check for contraindications. Instead, the vendors praise the abilities of their interaction warnings, which in actual fact are near to nothing.

You can find this page on the iotaMed wiki. You can discuss it on Vard IT Forum, where you can find my blog posts published a day or more ahead of time.

Problem: no connection between prescriptions and diseases

Prescriptions made in classic EHR systems have no context of “why” and “for what”. The only information about the reason for the prescription is an entirely optional field on the physical label informing the patient about the purpose of the medication. That is far from sufficient. The drawbacks due to the lack of a structured identification of the indication for the prescription are:

  • It’s harder to know when a medications is not needed anymore
  • It’s impossible to calculate recommended dosages and length of treatment
  • If recommendations change for certain diseases, the prescriptions cannot be tracked
  • Dangerous omissions due to confidentiality

Hard to know when not needed anymore

If a patient has multiple diseases and some medications may serve for more than one treatment, it’s sometimes very hard to figure out for which of these diseases it was originally intended. This way, it’s harder to know which prescriptions to review when one disease is cured or deemed resolved in some other way. Additionally, it’s a great time waster, since no doctor knows all indications of all medications by heart, so the lack of a formal link forces one to either ignore the medication and hope for the best, or waste time looking it up in a database, wade through the indications and check them against the possible diseases the patient may have, if you know them.

There is also good reason to assume that too many prescriptions are continued beyond their point of usefulness, simply because it’s too difficult to go through the review process. As long as they don’t cause actual harm, it’s easier to just leave them unchanged.

Impossible to calculate dosage and duration

Many medications have different recommended dosages and treatment durations depending on indication, and often depending on concomitant disease. For instance, antibiotics are often given with higher dosage and longer durations if it’s a recurrent infection or depending on locale. Some medications must be reduced in the presence of kidney or liver insufficiency. Without a disease concept in the EHR, none of these checks and calculations can be automated, even though they are well documented in pharmacological databases.

If recommendations change, therapies cannot be tracked

If the indication or recommended dosage for a particular medication changes, there is no way to find the cases where this recommendation change should be applied. The only method we have today is looking up every patient that gets the product and manually check the EHR to see if the change should apply. Needless to say, this is very rarely done, leaving far too many patients on treatment modalities that are outdated, and sometimes even detrimental to them.

Absurd and dangerous omissions due to confidentiality

Confidentiality in the medical records is currently applied to care givers, so that information originating from “hidden” caregivers is not shown to other caregivers without the patient’s permission. Prescriptions also have to be subjected to these rules, causing twisted and dangerous situations to occur. Examples:

  • Medication started by a “confidential” source becomes confidential. One can argue about the safety of this, but at least it’s consistent with the intention of the law.
  • Medication started by a “non-confidential” source is visible to others, but any changes to that medication such as an increase or decrease in dosage done by a “confidential” source is invisible, so the “non-confidential” source only sees the unchanged, erroneous, dosage. This is outright dangerous.

If the patient has a disease that is marked “confidential” but that forms a contraindication for some medications, there is nothing the EHR can do to prevent serious medical errors from occurring due to this confidentiality. The EHR has no “idea” exactly what is held confidential and which consequences this may have for other therapies, so it actively promotes dangerous prescription behavior.