6

As an ISV, what is considered best practice for implementing application role based security? In other words, only allow users to access certain features in the application based on what roles they belong to.

We currently just use a table in our database to store this, but it has been suggested that for maximum HIPAA compliance, this isn't secure enough.

My first thought was to just use Active Directory groups, as it would seem that is what they are designed for, however, it just doesn't seem practical to rely on our clients IT departments to create groups and assign users to them for groups that are specific only to our application. This can't be best practice for ISVs...

At this point it my research, it seems that possibly the best solution might be to use something like Active Directory Application Mode (ADAM) (Active Directory Lightweight Directory Services) and possibly AzMan (Windows Authorization Manager)?

Again, this is for a Windows Forms application, not a Web application or in an "in house" solution.

If it matters, we are also in the process of transitioning our home-baked authentication to instead use active directory for authentication.

Also of note is this needs to be secure (HIPAA compliant).

All the information I can find on these subjects seems to be for developing applications for in house use, or for web applications, and neither of these approaches feels appropriate for a Windows Forms application.

(We are using .NET for development.)

  • Where is the database? – JeffO Sep 12 '14 at 18:01
  • Well currently sybase, and likely moving to SQL Server. However, it's been suggested to me that this data should not be stored in the same database as the data it's meant to protect. – jonchicoine Sep 12 '14 at 19:59
  • the answer depend on many different business-aspects of your softwareproduct: How flexible/fine-grained is your role modell? How many different roles do you have? How many end-users exist per Customer/Installation (min/max)? Why is using "Active Directory Groups" not an option for you? – k3b Sep 15 '14 at 14:06
  • 1
    Well, someone actually has to assign permissions for the application or application systems to individual users. The IT department is typically responsible for managing/bookkeeping which desktop applications are available for whom (since they are the ones installing those applications). For more finegrained permissions inside one application system, either the IT manages this too, or you have some "power users" from the individual department, using some application specific administrative form or tool. – Doc Brown Sep 20 '14 at 11:49
  • 1
    Why is storing the information inside your database considered not to be secure enough? Any why should storing that information somewhere else make it more secure? IMHO introducing a second storage system makes the system more complex and thus potentially less secure. – Doc Brown Sep 20 '14 at 11:57
4

Moving the roles to LDAP / AD as a solution isn't going to address your root problem in a simple fat client architecture, but that isn't a reason not to do it, read on...

In the case of HIPAA security, we want to implement a system such that someone that knows database security and .NET internals can't hack your system by reverse engineering your application. If I were to audit your application, a disassembler and a network sniffer are two of the tools I'd use.

Don't get distracted with "we don't know who has the database password..." and all that. HIPAA doesn't depend on that. That isn't the application's concern. Actually in a HIPAA-secure environment, you will assume that certain people are authorized to maintain the system data, and it isn't up to you to solve all potential security problems in the organization. Likely the owner/doctor and system administrators will have access to all of it. Much of HIPAA is legal contract. A HIPAA security implementation requires you to place some level of burden on the customer to maintain the appropriate policies and procedures at their healthcare practice.

The customer, and their staff, will have all signed HIPAA contracts that pertain to their role in the customer organization. So will you, if you are engaged to install, maintain or support the system in any capacity that means you may touch data. All other partners, associates, including system administrators and third-party contractor, will usually be covered by BAA agreements, based on who they are and what data they may handle.

For an RBAC architecture, our job is to secure the application. As an PHI Application Architect, we are concerned, in our application, with security of PHI data from:

  1. Unauthenticated users
  2. Unauthorized users - Example: If I have roles(Technician), I should never be able to view data for roles(Physician, Nurse, Admin)
  3. Spoofed roles - the user is a Tech but claims he is a Doctor

To be HIPAA compliant the application must:

  1. Identify unauthorized access
  2. Identify which data was accessed
  3. Identify when it was accessed
  4. Identify where it was accessed
  5. Identify who accessed it
  6. Record the event
  7. Notify appropriate parties of the access in a timely fashion

Some companies use very broad definitions for a HIPAA compliant application, but in designing several EMR systems and having had to answer a lot of hard questions from customers, CEOs, auditors, and critics, I've learned that if I use sound computer science, I can formally prove that the system is secure (bugs notwithstanding).

So in that light, what does LDAP accomplish? There are a couple of benefits that have nothing to do with security:

  1. Stores roles for the organization in a standard format that a Windows system administrator might be more comfortable with.
  2. Centralizes roles such that other applications can share these roles, and you don't have to repeat yourself.

So it's a good thing. Large organizations have a lot of separate systems and a lot of duplicate data and entry. Particularly hospitals! If you can support LDAP and HL7, you can possibly plug in to their IT infrastructure (but usually with a bit of customization). To be competitive, it is a good feature.

But LDAP alone solves nothing regarding enforcement of roles and data access; you shouldn't make it a requirement to run your application (unless you are in the mid- to high-end space where the cost and skill set requirement is minor compared to the overall price of the application, or your application is for a specific organization that already has AD). For small "mom and pop" practices, your application should be turnkey, probably on a simple architecture of one or two PCs or a PC and a cheap server. We often think of healthcare practices as cash rich, but as I'm sure you know, the truth is many of them are not, or if they were, they have already been burned over and over by software vendors claiming to have the total solution. That said, I'll proceed now on pure technical aspects and leave your business to you.

Technical Perspective:

A good practice is to think as if your front end application is written in Ruby (or some other scripting language). I can compromise a compiled binary if I have read-access to that binary program. On most OSes, if I can run it, I can read it. The privileges are Read Write and Execute (X), and X doesn't come without (R). So assume with a .NET local application, that I can decompile the application.

Don't entrust authorization and role management to the client application. I should not be able to use knowledge of the code to obtain data from the database that I have no rights for. If I decompile the end user application, replace the string "TECH" with "ADMIN", it should only impact the application, not the data access. However, it is perfectly acceptable to use these roles in the application for controlling which screens are presented. Screen access doesn't dictate data access. Don't burn up man-hours trying to control screen visibility. Assume a well-behaved user. If he tries hard enough, he gets a blank screen, but it isn't usually worth writing code for, just worry about the data.

If the application is designed to use individual database users (i.e. I authenticate to Oracle as MSMITH, and MSMITH has its own views to protect the base table data) then you can still get away with direct database access, as long as the roles are protected, and enforced. However, many (most) designs use shared-schema multitenancy and application/LDAP managed users and roles, and in that case, to really solve the problem, you have to introduce a middle layer; a gatekeeper that doesn't trust the application. The gatekeeper will independently authenticate and authorize the user's role and only serve up data accordingly.

Storing the roles in a database isn't less secure. We just can't allow people to assign roles to themselves (unless that is their role). And we can't allow the RBAC to be circumvented.

That leaves you with a decision regarding your architecture. Whether to move the database and/or gatekeeper of the data into a realm that isn't accessible to the user or front-end application, except through some communication protocol. This is one reason that SaaS is more secure for EMR applications, it provides a clean solution; the user can't read or directly execute the application, because he doesn't own it or the domain it runs in; he just accesses it through the exposed interface. Many people think SaaS means "cloud", or that they login to some remote application across the Internet. But it simply means your user accesses the software as a service, and the software is centrally hosted. If you think about it, you can architect your Windows Forms application to use the benefits of the SaaS model, or narrow it down to DaaS (data as a service). Move your database off of the client, so it isn't co-resident, or if you must make it work on a single computer, put it in a separate user account or secure VM, and run the application without administration privileges, to communicate with the database through a service layer. The DaaS server might run in a back computer room, or at a remote office; that part isn't relevant.

This solves the security problem completely in that the server can perform the authentication, authorization, and administration of the roles, and no amount of spoofing roles in the client is going to override the server. If your client application has to request data through a service layer, then the security is out of his control, and secure. It may sound expensive to implement; it isn't too bad if you already have an MVC / MVP and/or SOA architecture. And if rearchitecting your application is unreasonable or cost-prohibitive, there are ways to do it purely at the database level with most robust relational databases.

0

It seems to me you want to protect your application from two perspectives:

  1. You want to make sure that only authorized people can modify your role-based security via the official user interface for role-based security management.

  2. You want to make sure that people can't view or modify your role-based security via an unofficial mechanism.

This first part is pretty easy, you include a role in your application for maintaining role group members and role authorized actions. Connecting this to (or forcing it into) your customer's AD is a bit dubious. You don't know how well the customer manages their AD. Also, what if they use something other than AD? The complexity of connecting to and integrating with your clients' AD is something that may raise its own HIPAA or security concerns, i.e. some clients may not allow your application to connect to your AD to get information about users.

The second part is a concern for storing your role information in a database. How many people know the DBA password for your clients' systems? You don't know, so how can you be sure that you are secure? You want to encrypt the role information in your application's database and obfuscate the code that accesses it. This will reduce the risk of someone viewing or changing the role rules with plain old database tools, for example. Since you're dealing with private information, you probably need to consider encrypting all of your sensitive data, not just your role-based security rules.

Let your client's IT department concern themselves with who can get basic access to your application. This is the bread and butter of IT departments. Once a user gets to your application, however, you need to take responsibility for who is logged in and what they can see and do.

  • 1
    Actually you should know, as the owner of the organization, who has DBA password. That is covered under HIPAA contracts. It isn't up to your app to solve all of those problems. You must assume HIPAA policies are in place, outside the app as well. If you work in a healthcare organization, nowadays, you are going to have a HIPAA agreement on file. – codenheim Oct 22 '14 at 20:39
-1

The Solution can be implemented in following method. The required screens in the application would be.

  • User Group Master - Create Multiple groups from the screen
  • User Master - create multiple users from the screen
  • User Group Detials Master - Select User, the screen would list different user group. Assign different groups to the user.
  • User Group Rights Master - Select the Group, List different menus in the application and grant different privilages.

Method For Implementation

  • Assign Menu ID to all Menus, Keep a menu master table to list in screen for assigning rights.

  • Create a rights details table with menu id,group id and different rights you want to control,visibility,save,editing details and additional stuffs based on your requrements.

  • Create a function checkpermission while doing any operations in the screen or accessing the menu item with the menu id and the permission to check and user id as parameter. The function will return value True or False and the rights can be controlled.

The same can be achieved in Web Application also. It has been implemented succesfully in various personal projects which I had undertaken. Additionaly you could also have an Audit log insert in the permission checking function and provide access reports based on screen accessed or data modified on screen or task completed on screen or additional task you would want logged in your application

Alternatively, Coupled with the Same you can generate and ldap Authentication function using active directory services. With this you will be able to log on to the System only when the user logs in from the specified domain set by the IT Administrator group.

You can also find a sample code for the same and can develop based on the same.

using System.Text;
using System.Collections;
using System.DirectoryServices;
using System;
using System.DirectoryServices.AccountManagement;
using System.ServiceModel;namespace ClassLibrary
{
    public class LdapAuthentication
    {
        #region Variables/Constructor
        private string _path;
        private string _filterAttribute;

        public LdapAuthentication(string path) 
        {
            //to initialize the Active Directory path
            _path = path;
        }
        #endregion

        #region User Authentication
        public bool IsAuthenticated(string domain, string username, string pwd)
        {
 #region Active Directory Direct Connection
            //accepts a domain name, user name and password as parameters and returns bool to indicate whether or not the user with 
            //a matching password exists within Active Directory. The method initially attempts to bind to Active Directory using the 
            //supplied credentials. If this is successful, the method uses the DirectorySearcher managed class to search for the 
            //specified user object. If located, the _path member is updated to point to the user object and the _filterAttribute member 
            //is updated with the common name attribute of the user object

            string domainAndUsername = domain + @"\" + username;
            DirectoryEntry entry = new DirectoryEntry(_path,  domainAndUsername, pwd);
            try
            {               
                // Bind to the native AdsObject to force authentication.
                Object obj = entry.NativeObject;
                DirectorySearcher search = new DirectorySearcher(entry);
                search.Filter = "(SAMAccountName=" + username + ")";             
                search.PropertiesToLoad.Add("CN");
                SearchResult result = search.FindOne();
                if (null == result)
                {
                    return false;
                }
                // Update the new path to the user in the directory
                _path = result.Path;
                _filterAttribute = (String)result.Properties["cn"][0];
            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
            }
            return true;

            #endregion
        }
        #endregion
}
}
  • 2
    I appreciate the effort, but this doesn't answer my question. We already have what you describe implemented. – jonchicoine Sep 21 '14 at 19:36
  • The answer was solely directed at the first para of your question to control user rights. If that has been implemented it would meet your compliance department. Could you please provide in detail why you need to change from that structure. The structure can be suitably ammended to include modules and IT administrator could control the rights provided. – Dilip Sep 22 '14 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.