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!
Making the entire Knowledge Base publicly available
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
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.
Name: kb_view_custom
XML:
<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.
Hi Mark,
Great Article, perhaps as a fail-safe plan the default value for this new field (answer) could be assigned TRUE, so that you must explicitly select that field in order to allow any article to be posted publicly. I can just see the MGMT and Legal having a field day with the posting of non-public KB article(s) on the Net. Get the popcorn ready!
Thanks Joel. That’s certainly not a bad idea as a failsafe, and simple to configure with a default on the dictionary of the ‘Login required’ field. It just depends on whether the organization wants to default to public or secured access for their KB. One other item to note is that since Aspen, ServiceNow includes a business rule and client script that display a warning message on the knowledge form if the ‘kb_view’ UI page has been made public.
Mark, Do you have any recommendation on making other areas public? We have a need to make submitting a request or Incident form public for different types of needs. all internal users are using SAML 2 to get into the system. Wiki doesn’t help much in this area
Each area is probably going to be a bit different. I’m not aware of any way to make the catalog interface public-facing. You could make a standard table form public just by adding it to the public pages list. Then you could set up a business rule on that table to transfer that data into a standard incident record. The other alternative would be to require registration or somehow allow users to self-register so they could log in.
Hi Mark,
Great post. Could you use the public flag on knowledge article to restrict access rather than create a new custom field u_login_required? Require the user to login if public field is false.
There is no ‘public flag’ on knowledge articles. That’s why the field had to be created. Knowledge articles only have the ‘Roles’ field to mark something as public. You could potentially adjust the read ACL to work with the ‘public’ role in that field, but ServiceNow has built other pieces of functionality around the public role so I think it’s best to leave it as-is.
Hi Mark,
it seems the ACL does not work on the kb_view page. When I try to access a login required article with an unauthentificated user (eg. https://demo005.service-now.com/kb_view.do?sysparm_article=KB0000001) directly – the ACL is not working and I can see the article. On the kb_home.do page instead all is working correctly and the article is not shown to the user. Maybe you know a way to fix this?
Thanks.
Best regards,
Robert
You’re right! Unfortunately, ServiceNow has made this one way more challenging than it should be. ACLs and ‘Before query’ business rules have no effect on this issue. I’ve come up with a UI macro solution that seems to handle it well though. Give it a try and let me know how it goes.
Works like a charm! Thank you very much.
Hi Mark,
Can I see the UI macro as well? I can still directly link to the kb_view.do after using the above UI macro
Jeff
Sure. The UI macro is included in the article above for your reference.
Oh, I thought you had another one, that is the one I am using and I am still able to directly link to the article…
And you can still see the full contents of the article even though you’re not authenticated?
Yes: https://mapfreusadev.service-now.com/kb_view.do?sysparm_article=KB0010173
Hard to say exactly without having access to your instance. You’ll want to make sure that your ‘kb_view’ UI page includes the ‘kb_view_custom’ UI macro and that your UI macro is named correctly.
Want to auto-display the knowledge aricles in Incident Page (Create New Incident) which are relevant to the short description for both ITIL Users and Employees.
Is it possible? Could you please anyone help on this?
Thanks.
The behavior you’re asking for is something that Crossfuze Solutions has built out as a standard feature of their Knowledge/Incident turnkey solutions. If you (or a client) is interested in that functionality we can provide that as a paid-for product. That’s not a solution that we have freely available through ServiceNow Guru though.
Hi Mark,
My test solution without a role and the Login required field checked is still being displayed when I am not logged in. Is ‘u_login_required’ a valid field name for the script as is? Do I need to modify kb_view or does it work with kb_view_custom as is?
Thanks, Jim
The whole point of using ‘kb_view_custom’ is to keep you from having to modify out of box code and breaking upgrades so you should never have to modify ‘kb_view’. The only thing I can say is to review the instructions and try again, or try setting it up in a demo instance and see if there are any differences. Regardless of what you do, the article will still be visible. The solution I’ve created here simply removes the article text and replaces it with a message indicating that the user can’t view a protected article.
Hi Mark,
is there a way to seperate the knowledge base into two modules. Based on what group the user is in thats the knowledge base and articles they are able to see?
ServiceNow only allows you to separate KB content by role out-of-box. This is a problem that we’ve solved at Crossfuze in our Knowledge turnkey solution. It allows you to separate by role, group, department, company, location, and individual user. You can view information on our KB solution (and our other turnkey offerings) at the Crossfuze website. Let me know if you’d like a demo or further discussion.
http://www.crossfuze.com/solutions/turnkey-solutions
Hi folks,
I know this is a bit old, but is still useful. I am new to servicenow and jelly scripting. There seems to be step 4 missing, which is how and where to actually invoke the ui macro in the ui page. I know the syntax – which is – but when I insert that near the top of the kb_view ui page – it doesn’t cause any change. So, a bit more detail on how to call the macro would be appreciated.
Hey Andrew. 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. I’ve adjusted the documentation in step 2 above for future reference. It includes a wiki link that describes the out-of-box capability.
Thanks Mark,
It looks like it was a server cache issue. Others might also be confused with the create field Login required but the field name you reference is u_is_public (like my intern was). I have higher expectations of those utilizing jelly , but I would still adjust the instructions if it were mine :P.
I can’t blame anyone for being confused by that, I typed in the wrong field name! Thanks for pointing that out, I’ve fixed it up above so that it makes sense.
Mark,
This is great stuff. Just one question. If a user who isn’t logged in visits the kb_home.do page, they still see a list of all articles that have no role associated with them, regardless of the “Login required” value. I get this, because the UI macro only gets executed when a specific article is loaded. But do you know of any way of restricting what is publicly visible on kb_home.do i.e. so that role-less articles aren’t listed? (Hope that makes sense.)
Thanks a lot,
Patrick
That does make sense, but unfortunately the ServiceNow security model around this doesn’t. You really have to go and start modifying additional ACLs and query business rules to make that happen. It’s not simple so I don’t have a written solution for it. If you’re interested in exploring a fully-featured knowledge management product for ServiceNow that addresses this (and a whole bunch of other KB issues) let me know and I can give you a demo of the Crossfuze KB turnkey solution.
Mark,
Thanks for this. I’ll do some more thinking. Crossfuze is maybe something I’ll look into.
Thanks again,
Patrick