Using and understanding Reader Names fields in IBM Lotus Notes and Domino
Reader Names fields (also known as Reader and Author Access or Reader Names) restrict access to documents in IBM Lotus Notes and Domino databases. This security feature provides robust protection against unwanted intrusion and provides designated users easy access to documents that they should see. In other words, itâs an intelligent and granular method for granting data access. This article provides a roadmap for implementing Reader Names fields and provides plenty of tips to help you avoid problems down the road.
This article is intended for Notes/Domino application developers, although no particular level of expertise is required to understand the concepts and examples.
Overview of security methods in Lotus Notes/Domino
Lotus Notes/Domino gives you many methods for securing data in a database. Here is a brief overview of the more common methods so that you can see where Reader Names fields fit in:
- Physical access. If your server is in a room with no cables, network connectivity, or modem access, then naturally, the data has achieved some level of security simply by means of being unavailable to anyone not physically in the room. Although theoretically a good experiment, this is not typically a good solution for most data.
- Server access. The Lotus Domino server allows/denies users based on access lists in the Server document, a feature most often used to deny access to terminated employees who may still have a valid ID file and network connectivity.
- Access Control List (ACL). Each database has its own ACL, which can allow/deny users based on their individual name, groups they belong to, or the hierarchy of their ID.
- Reader Names fields. This feature can allow/deny access to individual documents based on the same criteria used in the ACL. In addition, you can use [roles], which are defined in the ACL.
- Encryption. This feature lets you allow/deny access to individual fields within individual documents. You can use encryption based on a userâs name or a secret key that has been physically shared between ID files.
Although each of these topics is interesting and worthy of consideration, this article focuses on securing data by means of Reader Names fields.
If a user with a Notes client or Web browser has access to your database, then we may assume that he's been granted access down through number three in the previous list. If no further security measures are taken (for example, Reader Names fields), then this user can theoretically find a way to access any document. For example, hiding data by not including it in the main views -- although easy to accomplish from a development perspective -- does not protect that data from someone who is determined to find it.
Based on years of studying, testing, and using the various security measures available in Lotus Notes/Domino, we created table 1 to help you decide which security measures are most appropriate for different situations.
NOTE: The term "obfuscation" is used to denote hiding data by not displaying it in public views or hiding data on a form by using hide-when formulas. It is not true security, but it can be useful in certain contexts.
Table 1. Comparing the different security measures
|Type of security||Pros/Cons||How to implement|
|Obfuscation||Hide-when attributes on fields in forms or on navigation options. You can also hide views using the hide-when attributes in the View Properties box.|
|Reader Names fields||Field of type Reader on a form is the most common method of applying this security measure.|
|Encryption||Enable encryption on appropriate fields, and then use secret key or public key encryption to encrypt document for access only by Notes client users with correct ID.|
You can see from table 1 that using Reader Names fields has some powerful advantages over other forms of security. They provides real security, but are also convenient to use if you have the appropriate access whether using a Notes client or a Web browser. Critically, the data can be seen in views, and agents can programmatically access the data. Finally, itâs relatively easy to implement and change if your security or business needs change in the future.
Implementing Reader Names fields
To use Reader Names fields, you typically set a field type to Readers in the Field Properties box (see figure 1). Thatâs all there is to it. After you populate these fields with user names, groups, or roles (discussed later in this article), only specified users can see documents based on this form.
Figure 1. Field Properties box
Itâs advantageous to make this field multi-value so that you can add more than one name to the field. If you save a document with this form and look at the field properties, you see that the Field Flags list SUMMARY READ-ACCESS NAMES (see figure 1). This means that the data can be seen in views (SUMMARY) and that it is a Reader Names field (READ-ACCESS NAMES). A common mistake when using Reader Names fields is to forget to make the field the correct type, so performing this quick check of document properties is a good way to confirm that you've set things up correctly (see figure 2).
Figure 2. Document Properties box
Using multiple Reader Names fields
You can have multiple Reader Names fields on your form. If you have more than one, then to determine who has access, take the cumulative names from all the Reader Names fields. In addition, anyone with the ability to edit a document can add a Reader list (last tab of document properties), which is then stored as a field called $Readers. If such a field is added, then it is treated exactly the same as all other Reader Names fields with respect to determining document access.
Using Author fields
If you were to create an Author field, it would have the property SUMMARY READ-WRITE ACCESS. Interestingly, if you have only an Author field and no Reader Names field on a document, then anyone can see it. However, only users with Author access to the database who are also listed in the Author field can edit it, plus anyone with Editor access or greater in the ACL -- regardless of whether or not his/her name is in the Author field.
If, however, there is also a Reader Names field, then the Author field serves as both a Reader list and an Editor list. Suppose that you have someone with Editor access in the ACL, but whose name isn't in either field, that users cannot see the document and therefore, cannot edit it even though he has Editor access to all documents in the database. If the user name is in any Reader or Author field on the document (you can have as many as you want of each type), then that user can read and edit the document.
You can also add such a field programmatically to a document using LotusScript, in which case your code may look like listing 1:
Listing 1. Sample LotusScript code
Dim item as NotesItem Set item = doc.ReplaceItemValue ( "RNames", NewValue ) Item.IsReaders = True â Item.IsSummary = True
In this code, RNames is the name of your Reader Names field, and NewValue is a string or array of strings. Also, Item.IsSummary = True is superfluous in recent releases of Lotus Notes/Domino; in early releases, it was necessary to guarantee that the new field is saved as summary data.
If you attempt to add a new Reader Names field to a document using the @Formula language, it won't be assigned the appropriate type. It will be considered a text field. Examining the document properties, you see SUMMARY, but not SUMMARY READ ACCESS. If the field already exists and you update the contents, however, then the @Formula language preserves the correct Reader attributes.
Reader Names and Author fields must have individual names in either flat or canonical format, but not abbreviated format. For example, CN=Raphael Savir/OU=Boston/O=LSDevelopment is fine, and Raphael Savir is also fine, but Raphael Savir/Boston/LSDevelopment does not work.
This can be confusing because a Reader Names or Author field displays canonical data in an abbreviated format to make it easier to read. When you open a document and read the names in such a field, you see Raphael Savir/Boston/LSDevelopment. But if you look at the underlying data using document properties, you see that itâs really stored canonically as CN=Raphael Savir/OU=Boston/O=LSDevelopment (see figure 3). This ability to clean up the display of canonical names is true of all Names fields, but not true of plain text fields.
Figure 3. Canonically stored Reader Names field
If you put a flat name into a Reader Names or Author field, it works only as long as the server has the same hierarchy as the user. For example, suppose that your company merges with another company and that you have data replicating between servers of different hierarchies. Letâs call one Apps/NorthEast/LSDevelopment, and the other HQ/ACME. If our user attempts to access the data in each replica, and if his data is in Reader Names fields using his flat name, then he is only successful on the Apps/NorthEast/LSDevelopment server because he shares hierarchy with only that server (the /O= portion of his name). He may be cross-certified to access the other server, HQ/ACME, but the Reader Names and Author fields do not grant him access to the data itself.
The lesson here is that canonical names are safest. You should never use abbreviated names, and you should use flat names only if you're confident that your data cannot replicate across company or domain boundaries.
NOTE: In this article, when discussing business roles, we write out the word "roles" normally. However, when referring to the feature found in the ACL of every Notes database, we bracket the word to distinguish it: [roles].
When first using Reader Names fields, it is tempting to put into the field the names of each individual user who needs to access the document. However, this is impractical because if the user changes business roles within your company, you may need to replace his name in many documents, perhaps hundreds of thousands. Although itâs certainly possible to do this accurately, you would never want to be in this position unless no other option were available. In many companies, this is a frequent occurrence, so you should prepare for this situation.
In addition, your Reader Names fields may reference a large group of people. For example, all 30 directors and executives in your company need to see all the sales data in your application. It is a waste of space to repeat these names for every document, and of course, the more names there are, the more frequently you need to make changes in that list of names. Finally, although uncommon, it is certainly not unheard of for the list of names to exceed the 32K SUMMARY data limit for a field.
Instead, it is preferable to use groups or [roles] whenever possible. In theory, either is fine, but in practice you should use [roles] whenever possible. One way to think about the difference between groups and [roles] is that groups are maintained in the Domino Directory. There are many thousands of groups, their names may change if your company merges with another company, and itâs always possible for the directory to become corrupt or to have other problems that you are unable to address personally. Figure 4 shows an ACL with a role assigned to user Rafael Savir/Boston/LSDevelopment.
Figure 4. ACL with a [role] assigned to a user
On the other hand, [roles] are particular to your application. Through a few clicks in the ACL, you can apply a [role] to one group or multiple groups. You can take the [role] off one group and apply it to another group, or, in a pinch, you can apply the [role] to individual names in the ACL. Crisis situations have been seen in which a directory was corrupt, but users were granted complete access to critical data by adding their names temporarily to the ACL and applying the relevant [roles] to their names. If the Reader Names fields had groups instead of [roles], this would have been impossible.
To use [roles] in this way, think of the group or groups that need access to your secured documents. Suppose the groups are as follows:
- Executive Committee
- HR Reps
- Sales Management Team
You can approach the problem of how to grant these people access in two ways. One is to make a [role] for each group, and the other is to make a single [role] that you apply to all three groups. It depends upon your particular situation, but because you can have up to 75 [roles], you can typically be liberal in how you create and apply them. Over many years of using [roles] in developing applications, we have compiled the guidelines below that have served us well. These are not absolute rules, but in every case their application has prevented problems:
- Keep them short. This saves disk space and makes it more likely that you correctly spell the [role] in code, which invariably becomes necessary over time.
- Don't use spaces or other strange punctuation characters. Again, it makes correct spelling easier, plus you avoid problems in full-text searches and potentially in Web applications if you have to pass the [role] through a URL.
- Itâs fine to mimic a group name, but remember that the group name may change over time.
- Always reserve at least one [role] for your developers and/or administrators. In other words, if you have a group called Development, do not make a [role] called simply [Dev] or [Development] because thatâs probably a [role] you should use for the actual Notes/Domino developers who are working on this application. For your other group, apply a [role] called, for instance, [ProdDev].
So, in our example, we create Reader Names fields with the following [roles]:
Note that the last two were added so that all the developers and administrators can access the data.
Effects of Reader Names fields in replication, agents, and views
Now that you know exactly how you want to set up your [roles] and Reader Names fields, you should take a few minutes to think about other ways in which your data is accessed. Specifically, we found that replication, agents, and views can sometimes exhibit unexpected behavior after the application of Reader Names fields on documents. In this section, we delve into each of these.
If your data replicates across servers, the only thing you need to consider is including all the servers in your [Admin] role as discussed earlier. You can do this through the LocalDomainServers group so that you are guaranteed that all servers in your domain can see all Reader restricted documents in your database.
If you don't want all data to replicate to all servers, you need to change that approach. One example of this is a big sales application in which each geographical region maintains only its own data to streamline performance. In that case, you might use [roles] such as [Servers-APAC], [Servers-EMEA], and so on, and apply these [roles] to documents according to their geographical region, and then to the individual server names in your ACL. You still need to be careful that you don't unintentionally grant all servers access to all data through LocalDomainServers or some other group, so test carefully after rolling out such a model.
A more vexing problem is what to do with local replication. For example, suppose your 20,000 sales representatives each have a laptop and replicate their own data locally every night. Without Reader Names fields, you may worry about replication/save conflicts, but thatâs all. With Reader Names fields, you also have the possibility that local replicas will become out of synch with the server copy, if a document is edited on both the local copy and the server copy, and the serverâs edit includes removing that userâs name from the Reader Names fields.
In other words, replication conflicts cannot be resolved if one of the two replicas is simultaneously being denied access to the document in question. The result is that the server retains its own edits, and the local copy retains its own edits, and neither realizes that they are out of synch. There is no trivial solution to this problem, and you should keep it in mind when designing your overall architecture and workflow.
Agents are actually very straightforward when it comes to Reader security. If the agent is triggered by a user, for example, by a click of a button, then the agent runs as though that user were performing those actions. If that user has access to a document, then the agent can access the document, too. If the user does not have access to the document in question, then an error displays when the agent runs (for example, "Entry not found in index" or "Unauthorized to attempt that operation").
If the agent is a scheduled agent, then the agent runs as if it were the signer of the agent, unless the agent has its "Run on behalf of" field populated, in which case it runs as if it were that user (see figure 5).
Figure 5. Agent Properties box
Perhaps the most significant user impact is in views due to functionality and to performance.
If a view is categorized, users may see a category with a twisty, but cannot see the documents within that category. This is a very common complaint for users. One solution is to create an embedded view using the Show single category option (see figure 6) and to have the user choose a category to display from a list of categories to which he has access. This way, the user doesn't see the other categories and so doesn't find empty views. This functionality works seamlessly for Web browsers and can be used for Notes clients as well. Another solution is to rethink your categories so that users don't find an empty category.
Figure 6. Show single category under Embedded View
Reader Names fields can make a view perform much slower than it would otherwise because the server must check every document to make sure it can be seen. It must do this for every user, so if you have many concurrent users and many documents with Reader Names fields, your server/application can slow down dramatically. This is especially true when many users have access to a small subset of the documents in the view as may be the case in a sales or HR application. Again, the best solution is to create an embedded view using Show single category. This is typically faster than opening the native view with no Reader restrictions on the documents at all.
Alternatively, you can categorize and initially collapse your view. This improves speed, although it can lead to the problems discussed earlier; users see a category, but cannot see any documents within that category. In some cases, it may make sense to break up your data into multiple views, and then to guide your users to the correct view. For example, if a user clicks Regional Sales in the navigation, then you may have a formula that checks @UserRoles, and then opens the appropriate view, Sales-US, Sales-APAC, and so on.
For more information about view performance, see the developerWorks Lotus article, "Lotus Notes/Domino 7 application performance: Part 2: Optimizing database views."
In this section, we address two troubleshooting topics that occur frequently in user groups and conferences.
Multi-value Reader Names fields
If you make your Reader Names field single value in your form, and then later decide to add additional values, you may do so by writing an agent that adds these extra values. So far, so good, but when a user edits and saves the document, your form still treats the field as single value, not multi-value, so it may render your Reader Names field useless.
For example, support you put the [HR] role into your Reader Names field. A year later, you realize that it makes sense to also put the [ProdDev] role in there. You write an agent to append that value, you test with a user who has the [ProdDev] role, but not the [HR] role, and everything looks great. But if you forget to change the field properties on the form, the next time someone saves a document with that form, your Reader value looks like "[HR], [ProdDev]" instead of "[HR]" "[ProdDev]". In other words, the Reader Names field now looks for a person or group called [HR], [ProdDev] (where the comma is simply part of their name, not a value separator), and no one has access to the document.
The easy way to avoid this kind of problem is to always make your Reader Names/Author fields multi-value.
Rescuing hidden documents
If you use Reader Names fields on documents and you inadvertently make some documents inaccessible to all users (for example, by inserting multiple entries as a single invalid entry as described earlier), then you can use Full Access Administration mode (see figure 7) to open the database and to rescue those documents. In advance, create an agent that applies the appropriate Reader values, and then when in Full Access Administration mode, you can trigger that agent to fix your data.
In most organizations, only a select group of administrators has the ability to use this Full Access Administration mode, so users may need to queue up to get this done, but at least, itâs possible without sitting down at the server and using the local Notes client to bypass Reader security.
Figure 7. Full Access Administration option
We hope that this article helps make the process of planning and implementing Reader Names fields as painless and efficient as possible. Itâs a brilliant feature and a great security measure, and itâs easy to implement and maintain as long as you configure everything in advance. The key to remember is just that: configure everything in advance. If you do that, you should have a great experience while taking advantage of a powerful feature in Lotus Notes/Domino.
- developerWorks Lotus article, "Lotus Notes/Domino 7 application performance: Part 1: Database properties and document collections
- developerWorks Lotus article, "Lotus Notes/Domino 7 application performance: Part 2: Optimizing database views"
- developerWorks Lotus article, "Troubleshooting application performance: Part 1: Troubleshooting techniques and code tips"
- developerWorks Lotus article, "Troubleshooting application performance: Part 2: New tools in Lotus Notes/Domino 7"
- developerWorks Lotus article, "Application Performance Tuning, Part 1"
- developerWorks Lotus article, "Application Performance Tuning, Part 2"
- Lotus Support technote, "Documents with Readers Fields do not work as expected in Directory Catalog"
- Download a trial version of Lotus Domino from developerWorks.
- Download a trial version of Lotus Notes from developerWorks.