O

ne area of Knowledge Management that is typically fairly confusing to new admins of the ServiceNow platform is the public (unauthenticated) security model. A ‘Mark Public’ UI button is displayed at the top of each knowledge article in its edit view. While clicking that button adds the ‘public’ role to the article, it doesn’t actually do anything to make the article public! Unauthenticated users attempting to view the knowledge homepage, or an individual knowledge article will still be redirected to the ServiceNow login page. In reality, setting the ‘public’ role on a knowledge article does very little to impact the security of that article. Controlling public availability of Knowledge Base content can be easily accomplished if you know where to look!

Public Knowledge Base

Making the entire Knowledge Base publicly available

Caution! Completing this step will make any KB article without an assigned role available to any unauthenticated user!

In order to make your Knowledge Base available without authentication you need to make the UI components (UI pages and UI macros) that display the knowledge base publicly available. This is done via the ‘Public Pages’ table. Public Pages can be accessed by admins by navigating to ‘System Definition -> Public Pages’ in your left nav. You can activate the module if you don’t see it in the list, or you can simply type ‘sys_public.list’ in the left nav filter to bring up the table.

The ‘Public Pages’ table shows every page in the system that is available to unauthenticated users. Not all of these records are active however. For the KB, you’re interested in the five public page records with a ‘Page’ value containing ‘kb_’. If you’re making your knowledge base public, I suggest making ALL FIVE of these records active. Here’s what they control.

  • kb_comments – comments section when viewing a single KB article
  • kb_find – knowledge search results page
  • kb_home – knowledge home page
  • kb_list – topic, category or (sometimes) search listing
  • kb_view – individual article page

Knowledge Base Public Pages

Require login for public articles

The only problem with the ‘Public by default’ knowledge security model in ServiceNow is that ALL articles end up being public unless you assign a role to them. This leaves you without a way to secure articles to authenticated end-users since they don’t have a role. It’s also inconsistent with the ‘Role’ fields everywhere else in the system…where no roles equals a logged-in end user and the ‘public’ role equals unauthenticated users.

Unortunately, there’s no simple solution with a ‘before query’ business rule or an ACL on the ‘kb_knowledge’ table since the ‘kb_view’ UI page disregards all article security–even though the other KB pages honor it. This means that even if you did restrict an article somehow, any user who knew the URL could access an article that may only logged-in end users should have access to. Here’s what you need to do to fix it.

1Create a new True/False field, named ‘Login required’ on the ‘kb_knowledge’ table by personalizing the back-end knowledge edit form.

2Create a new UI macro named ‘kb_view_custom’ (or edit it if it already exists in your instance). This UI macro is automatically included by the ‘kb_view’ UI page so there’s no additional action necessary to make it work other than to create the macro. See this ServiceNow wiki article for details.

‘kb_view_custom’ UI macro
Name: kb_view_custom
XML:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
   <g2:evaluate var="jvar_login_required">
      //Restrict non-public articles to logged-in users
      var answer = false;
      if(gs.getUser().isDefault() $[AMP]$[AMP] $[kb.u_login_required]){
         answer = true;  
      }
      answer;
   </g2:evaluate>
   <j2:if test="$[jvar_login_required]">
      <script>
         //Insert a restricted message and remove article contents
         try{
            $('sys_id').up('td').insert({
               top: '<table><tr><td><h3>${gs.getMessage('INSUFFICIENT ROLES TO VIEW PROTECTED ARTICLE')} $[kb.number].</h3></td></tr></table>'
            });
            $('sys_id').up('form').remove();
         }catch(e){}
      </script>
   </j2:if>
</j:jelly>

3Finally, just check the new ‘Login required’ checkbox for any article that you want to display only for authenticated users.