System Definition Archives - ServiceNow Guru https://servicenowguru.com/category/system-definition/ ServiceNow Consulting Scripting Administration Development Tue, 07 Jan 2025 16:24:53 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 https://servicenowguru.com/wp-content/uploads/2024/05/cropped-SNGuru-Icon-32x32.png System Definition Archives - ServiceNow Guru https://servicenowguru.com/category/system-definition/ 32 32 Be a Choice List “Thief” https://servicenowguru.com/system-definition/be-a-choice-list-thief/ Tue, 07 Jan 2025 16:24:53 +0000 https://servicenowguru.com/?p=17201 Do you find yourself duplicating the same choices across different forms and tables in ServiceNow? Manually updating these lists can be a real time-consuming hassle. Here's the good news! In my second article about powerful dictionary configurations, I will showcase a time-saving technique to reuse choice list values across your instance. This saves you time

The post Be a Choice List “Thief” appeared first on ServiceNow Guru.

]]>
Do you find yourself duplicating the same choices across different forms and tables in ServiceNow? Manually updating these lists can be a real time-consuming hassle.

Here’s the good news! In my second article about powerful dictionary configurations, I will showcase a time-saving technique to reuse choice list values across your instance. This saves you time and ensures consistency in your data management. This approach is particularly beneficial for multilingual environements, as you only need to translate the main choice list.

Use case 1: Linking Catalog Variables to existing Choice Options

There is a Choice field on a table, and we need to replicate this field on a Catalog Item or Record Producer form with the same choices.

For example, adding the Incident Category drop-down to the “Create Incident” Record Producer. On the left of the screenshot below is the Incident Category field as displayed in the Service Operations Workspace, and on the right is the Create Incident Record Producer in the Employee Service Center Service Portal.

  • To get these values onto the “Create Incident” Record Producer Form, create a new Select Box Variable to hold the values that need to be displayed.

  • Next, instead of creating mirror Choice options in the Question Choices Related List, navigate to the “Type Specifications” section on the Variable form. Enter the following values and save the variable:
    • Choice table: Incident [incident]
    • Choice field: Category

  • Now when we navigate back to the form in the Service Portal, we can see that there is a new Category field on the form, and it already has Choice values that exactly match the Incident Category selections. Now if you change the available Choices for the Incident Category field, the Variable drop-down values will automatically reflect those changes without have to repeat the configuration on the Variable record.

Use case 2: Reuse Choice List values in another field

Sometimes you need to replicate a choices options across several tables and fields to create consistency as data moves from one record to another, like Asset and CI attributes that exist on both records. –OR– You have several fields on the form with the same set of Choice options. For example, a design decision to use Yes/No Choice fields instead of Checkbox fields.

  • First, choose which table and field will drive the other fields options. The example will use Incident Category.
  • Navigate to the Dictionary record for the other field(s) that will be driven by the Incident Categories.
  • Find the Choice List Specification tab. If you don’t see the Choice table field, you may have to switch to Advanced view.
  • Enter the following values and save the Dictionary record:
    • Choice table: Incident [incident]
    • Choice field: Category

That’s it! Now, when you change the main field’s list, all of the other choice lists will reflect the change.

Summary

This article explored two simple ways to reuse choice list values in the ServiceNow platform. If you are a customer that supports multiple language, you’ve exponentially saved yourself some time, because you only have to translate the main field’s Choices and those changes will also be reflected everywhere as well.

By leveraging these techniques, you can streamline your ServiceNow configuration and save valuable time!

The post Be a Choice List “Thief” appeared first on ServiceNow Guru.

]]>
Easily Move Customer Updates Between Update Sets https://servicenowguru.com/system-definition/easily-move-customer-updates-between-update-sets/ https://servicenowguru.com/system-definition/easily-move-customer-updates-between-update-sets/#comments Fri, 26 Jul 2024 12:31:03 +0000 https://servicenowguru.com/?p=15964 As ServiceNow developers, we often encounter scenarios where we need to migrate configurations from one update set to another. Traditionally, this involves manually editing each customer update record to change its update set, which can be tedious and time-consuming, especially when dealing with a large number of updates. This article demonstrates how to streamline this

The post Easily Move Customer Updates Between Update Sets appeared first on ServiceNow Guru.

]]>
As ServiceNow developers, we often encounter scenarios where we need to migrate configurations from one update set to another. Traditionally, this involves manually editing each customer update record to change its update set, which can be tedious and time-consuming, especially when dealing with a large number of updates.

This article demonstrates how to streamline this process by creating a UI Action that allows you to move multiple customer updates between update sets with a single click.

Problem Statement
When you make configurations in your instance, there are times when you need to move these updates to a different update set. The conventional method requires opening each customer update record individually and changing the update set field to the desired update set. This method becomes impractical when dealing with numerous updates.

Solution
To overcome this challenge, you can create a UI Action that facilitates the movement of multiple customer updates to another update set in one go. This approach not only saves time but also reduces the risk of manual errors.

To begin, navigate to System Definition > UI Actions and create a new UI Action:

UI Action
Name: Move Updates to Current US
Table: sys_update_xml
Action Name: move_updates_to_current_us
Show insert: true
Show update: true
Client: true
List v2 Compatible: true
List Choice: true
Onclick: showConfirmDialog()
Script:

function showConfirmDialog() {

	var entries = g_list.getChecked();
	if (!entries || entries.length == 0)
		return;

	// this function runs when the modal close
	var callback = function () {

		// To send parameters to the server script we should use GlideAjax
		var ga = new GlideAjax('MoveUpdatesToCurrentUS');
		ga.addParam('sysparm_name', 'moveEntries');
		ga.addParam('sysparm_entry_ids', entries);

		// GlideAjax callback to refresh the related list
		var afterMove = function () {
			GlideList2.get(g_form.getTableName() + '.sys_update_xml.update_set').setFilterAndRefresh('');
		};

		ga.getXMLAnswer(afterMove.bind(this));
		return true;
	};

	var dialogClass = window.GlideModal ? GlideModal : GlideDialogWindow;
	var dialog = new dialogClass('glide_confirm_standard');
	dialog.setTitle(new GwtMessage().getMessage('Confirmation'));
	dialog.setPreference('warning', true);
	dialog.setPreference('title', new GwtMessage().getMessage('move_update_set_entries'));
	dialog.setPreference('onPromptComplete', callback.bind(this));
	dialog.render();
	
}

Two points I would like to highlight in this script.
– As we need to pass the selected records as a parameter to the server script, we need to use GlideAjax.
– For the callback function I needed to update only the related list. Initially I could only update the entire record but a quick search here on the portal led me to an article explaining exactly what I needed.

For the modal message to be displayed correctly, we need to create a record in the sys_ui_message table with the text we want.  Navigate to System UI > Messages and create a new message:

Now we need to create the Script Include that will perform all the necessary validations and actions. Navigate to System Definition> Script Includes and create a new script:

Script Include
Name: MoveUpdatesToCurrentUS
Accessible from: All application scopes
Client callable: true
Active: true
Description: Ajax helper class for helping the [Move Updates to Current US] UI action
Script:

var MoveUpdatesToCurrentUS = Class.create();

MoveUpdatesToCurrentUS.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    moveEntries: function () {

        var arrMoved = [];
        var objMoved = {};
        var arrNotMoved = [];
        var objNotMoved = {};
        var currUS_ID = '';
        var customUpdateLink = '';
        var customUpdateType = '';
        var baseURL = gs.getProperty('glide.servlet.uri');

        //create a link to the syslog to return the logs created by this SI on last 15 minutes 
        var sysLogQuery = 'sys_created_onONLast 15 minutes@javascript:gs.beginningOfLast15Minutes()@javascript:gs.endOfLast15Minutes()^messageLIKEMoveUpdatesToCurrentUS';
        sysLogQuery = encodeURIComponent(sysLogQuery); //https://www.w3schools.com/jsref/jsref_encodeuricomponent.asp
        var sysLogURL = baseURL + 'syslog_list.do?sysparm_query=' + sysLogQuery;
        
        // get the user current US
        var currUS = gs.getPreference('sys_update_set');
        var grUS = new GlideRecord('sys_update_set');		

        if (grUS.get(currUS)) {
            currUS_ID = grUS.getUniqueValue();
        } else {
            gs.info('[MoveUpdatesToCurrentUS] Error: Unable to get Current US.');
            gs.addErrorMessage('There was an error. Please review the <a href="http://'%20+%20sysLogURL%20+%20'">system logs</a> for more details.');
            return false;
        }

        // get the variable sent by the UI Action
        var entries = this.getParameter('sysparm_entry_ids');

        //get all selected custom updates
        var customUpGr = new GlideRecord('sys_update_xml');
        customUpGr.addEncodedQuery('sys_idIN' + entries);
        customUpGr.query();

        while (customUpGr.next()) {
            
            //check if the user can write in the table
            if (customUpGr.canWrite()) {

                //create a link to the current update and get its type
                customUpdateLink = baseURL + 'sys_update_xml.do?sys_id=' + customUpGr.getValue('sys_id');
                customUpdateType = customUpGr.getValue('type');

                // check if it trying to move do a diferent US
                if (customUpGr.getValue('update_set') == currUS_ID) {

                    objNotMoved = {
                        sys_id: customUpGr.getUniqueValue(),
                        reasonHTML: 'Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> is already in your currently US.',
                        reasonText: 'Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - is already in your currently US.'
                    };

                    arrNotMoved.push(objNotMoved);

                } else {

                    // move the customer update to de current US
                    try {

                        customUpGr.setValue('update_set', currUS);
                        customUpGr.update();
                        
                        objMoved = {
                            sys_id: customUpGr.getUniqueValue(),
                            reasonHTML: 'Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> was moved to your currently US.',
                            reasonText: 'Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - was moved to your currently US.'
                        };

                        arrMoved.push(objMoved);

                    } catch (e) {

                        objNotMoved = {
                            sys_id: customUpGr.getUniqueValue(),
                            reasonHTML: 'Unable to move the Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> due: ' + e,
                            reasonText: 'Unable to move the Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - due: ' + e
                        };
    
                        arrNotMoved.push(objNotMoved);

                    }

                }				

            } else {

                objNotMoved = {
                    sys_id: customUpGr.getUniqueValue(),
                    reasonHTML: 'Unable to move the Custom US <a href="http://'%20+%20customUpdateLink%20+%20'">' + customUpdateType + '</a> due to ACL restrictions.',
                    reasonText: 'Unable to move the Custom US ' + customUpdateType + ' - ' + customUpGr.getValue('sys_id') + ' - due to ACL restrictions.'			
                };

                arrNotMoved.push(objNotMoved);

            }			

        }

        // create 2 messages: one to the syslog and one to show to user
        var sysLogMessage = '[MoveUpdatesToCurrentUS]' + '\r\r';

        if (arrMoved.length > 0) {
            
            var successScreenMessage = 'Move Updates to Current US Action' + '<br><br>';

            sysLogMessage += 'Custom Updates moved:\r';
            successScreenMessage += 'Custom Updates moved:<br>';

            for (var i = 0; i < arrMoved.length; i++) {
                sysLogMessage += arrMoved[i].reasonText + '\r';
                successScreenMessage += arrMoved[i].reasonHTML + '<br>';
            }

            gs.addInfoMessage(successScreenMessage);

        }

        if (arrNotMoved.length > 0) {

            var failureScreenMessage = 'Move Updates to Current US Action' + '<br><br>';

            sysLogMessage += '\r\rCustom Updates NOT moved:\r';
            failureScreenMessage += 'Custom Updates NOT moved:<br>';

            for (var x = 0; x < arrNotMoved.length; x++) {
                sysLogMessage += arrNotMoved[x].reasonText + '\r';
                failureScreenMessage += arrNotMoved[x].reasonHTML + '<br>';
            }

            gs.addErrorMessage(failureScreenMessage);

        }		

        gs.info(sysLogMessage);
        
        gs.addInfoMessage('Customer Update(s) transfer has been completed. Please review the <a href="http://'%20+%20sysLogURL%20+%20'">system logs</a> for more details.');

        return true;

    },

    type: 'MoveUpdatesToCurrentUS'
});

Using

  • Open the update set from which you want to move few customer updates
  • Go to the Customer Updates Related List
  • Select all the updates you want to move
  • Click on [Move Updates to Current US] in the actions dropdown menu

  • If everything works fine all selected customer updates have been moved to your Current US and you will see a message – simple as that.

  • If any problems occur during the transfer, you will be notified.

  • Everything will be recorded in syslog

Benefits

  • Efficiency: Moves multiple updates simultaneously, significantly reducing the time required.
  • Accuracy: Minimizes the risk of errors associated with manual updates.
  • Usability: Provides a straightforward and user-friendly method for managing update sets.

 

By implementing this UI Action, you can enhance your productivity and ensure a smoother workflow when managing update sets in ServiceNow. This method is particularly beneficial in complex development environments where rapid and accurate configuration management is essential.

The post Easily Move Customer Updates Between Update Sets appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/easily-move-customer-updates-between-update-sets/feed/ 2
Condition Builder Attributes That Pack a Punch https://servicenowguru.com/system-definition/condition-builder-attributes-that-pack-a-punch/ https://servicenowguru.com/system-definition/condition-builder-attributes-that-pack-a-punch/#comments Tue, 11 Jun 2024 12:33:01 +0000 https://servicenowguru.com/?p=16508 Condition builders are the backbone of powerful filtering and automation within ServiceNow. They allow you to define precise criteria for workflows, reports, and many other areas of the platform. Did you know there are dictionary attributes you can apply to the standard condition builder field that will supercharge your filtering capabilities? Let’s dive into my

The post Condition Builder Attributes That Pack a Punch appeared first on ServiceNow Guru.

]]>
Condition builders are the backbone of powerful filtering and automation within ServiceNow. They allow you to define precise criteria for workflows, reports, and many other areas of the platform.

Did you know there are dictionary attributes you can apply to the standard condition builder field that will supercharge your filtering capabilities?

Let’s dive into my top four condition builder field attributes that deliver significant impact with little effort!

1. condition_builder=v2 – The Modernized Interface

Condition builder fields have a more accessible, intuitive interface. Enabling this modern user experience simply requires setting condition_builder=v2 in the dictionary attributes for a Conditions field.

My favorite part is that the new interface eliminates the endless drop-down reloading when you dot-walk through several reference fields.

Without Condition Builder v2 With Condition Builder v2

2. show_condition_count – (Near) Real-Time Feedback

Ever wonder how many records your current filter criteria will return? show_condition_count is your answer. When set to true, the condition builder will display the number of matching records when you hit Preview.

This provides invaluable feedback, helping you refine your filters and avoid unexpected results. It’s especially useful when dealing with large datasets.

3. readable – Human-Friendly Conditions

Complex conditions can quickly become cryptic and challenging to understand. The readable attribute addresses this issue. When set to true, ServiceNow displays a human-readable version of your condition in Lists and settings where the condition field is read-only.

For instance, instead of seeing:

active=true^assignment_group=d625dccec0a8016700a222a0f7900d06

You’ll get:

Active is true AND Assignment group is Service Desk


Another attribute that can be used in conjunction with readable is no_truncate=true. This prevents the value from getting truncated in a list view, as you see above. I recommend considering the expected length of a typical condition for your table. If you think they will be lengthy, I would not recommend using the no_truncate attribute. The trade-off is that each record row will take up a lot of space on your screen. You can always remove the no_truncate attribute or set it to no_truncate=false later if it proves to be unwieldy.

4. allow_related_list_query – Querying Beyond the Current Table

By default, condition builders limit your queries to the fields of the current table you’re working with. But what if you need to filter based on data in a related table? That’s where allow_related_list_query comes in.

Setting this attribute to true opens up a world of possibilities. You can now construct queries that traverse relationships between tables. For example, you could filter incidents based on the priority of the associated change request.

Within the Related list query, there are three components:

  1. Quantity: such as Greater than, Less than, or None
  2. Table relationship: How does the Related Record link to the primary record?
  3. Filter: You must specify a condition. Using the Incident and Change Request example from above, specify “Priority is 3 – Moderate.” Suppose you are just looking for the existence of one record that uses the specified Table relationship. In that case, I recommend finding a condition that will always be true, like “Number is not empty.”

In the image below, you can see an example primary record condition of “Active is true AND Assignment group is Service Desk” and a condition for “At least on Change Request record where the primary record is the Parent, and the Change Request Priority is 3 – Moderate”

NOTE: Unfortunately, the Related Record conditions are not formatted for readable viewing.

Important! Be mindful of performance when using related list queries, as they can potentially impact system resources if not designed carefully.

How to activate these options

You’ll need to modify the Attributes fields on the Dictionary record for each field.

  1. Navigate to a form with a condition builder field.
  2. Right-click on the field label, for the field you want to modify, then click Configure Dictionary.
  3. In the Attributes field, add the desired setting, such as condition_builder=v2 or allow_related_list_query=true. For multiple attributes, separate by comma.
  4. Click Update.

If you have activated all the options above, the attributes field on the dictionary record will look like the string below. The order in which these attributes are listed is not important.

condition_builder=v2,show_condition_count=true,readable=true,no_truncate=true,allow_related_list_query=true

To deactivate or reset to default, you can reverse the procedure above, removing the added text from the Dictionary Attribute field.

The post Condition Builder Attributes That Pack a Punch appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/condition-builder-attributes-that-pack-a-punch/feed/ 7
Demystifying Cryptography in ServiceNow: A Comprehensive Guide to Secure Data Transmission https://servicenowguru.com/system-definition/demystifying-cryptography-servicenow/ https://servicenowguru.com/system-definition/demystifying-cryptography-servicenow/#comments Mon, 10 Jun 2024 14:03:48 +0000 https://servicenowguru.com/?p=15397 This article is the 1st in a series of posts that aim to demystify the complex world of cryptography within ServiceNow. In this installment, we dive into the foundational topics of URL encoding, base64 encoding, hashing, symmetric and asymmetric encryption, hybrid encryption, and digital signatures. These cryptographic principles are essential for understanding the more advanced

The post Demystifying Cryptography in ServiceNow: A Comprehensive Guide to Secure Data Transmission appeared first on ServiceNow Guru.

]]>
This article is the 1st in a series of posts that aim to demystify the complex world of cryptography within ServiceNow. In this installment, we dive into the foundational topics of URL encoding, base64 encoding, hashing, symmetric and asymmetric encryption, hybrid encryption, and digital signatures.

These cryptographic principles are essential for understanding the more advanced topics we will explore in subsequent articles, including a detailed look at SAML 2.0 in our second piece. This series aims to provide both newcomers and seasoned developers with a thorough understanding of cryptographic techniques used in ServiceNow.

Now, let’s begin our journey by exploring the fundamental concept of URL encoding.

Understanding URL Encoding

URL encoding is important in web development because it ensures that special characters in URLs are properly handled for internet transmission. Let’s break down the basics of URL encoding and its importance.

Why URL Encoding is Necessary?

When you construct a URL, you can’t include certain characters directly, such as spaces, question marks (?), and equals signs (=). These characters have different purposes within the URL syntax. To include them in the URL’s parameters and values, you need to encode them into a specific format.

The URL Encoding Process

URL encoding changes special characters into a text-based format so URLs can be safely sent and understood by web servers and browsers.

Example

Consider the following text that we want to include as part of a URL: “Hello World?“.  Through the URL encoding algorithm, this text is transformed into the following encoded format: “Hello%20World%3F
Here, the space is encoded as “%20“, and the question mark is encoded as “%3F“.

 

Not Encryption, but Transformation:

It’s important to understand that URL encoding is not a form of encryption. Its purpose is to convert text into a format that can be safely included in a URL, ensuring proper transmission rather than hiding the data.

Usage in ServiceNow

  1. REST API Requests: ServiceNow REST APIs often need URL encoding to handle special characters in request parameters, query strings, or resource identifiers (specific records, tables, or endpoints within the ServiceNow instance). URL encoding ensures the data in API requests is correctly formatted and interpreted by the ServiceNow instance.
  2. Integration URLs: URLs used in ServiceNow integrations, such as inbound or outbound web service integrations, may require URL encoding to manage special characters in endpoint URLs or request payloads. This encoding helps ensure smooth data exchange between ServiceNow and external systems.
  3. UI Actions and Script URLs: When setting up UI actions or script URLs in ServiceNow, URL encoding may be necessary to encode dynamic parameters or values containing special characters. This ensures that dynamically generated URLs in UI actions or scripts are correctly formatted and interpreted by the platform.

After understanding the importance of URL encoding, let’s shift our focus to another essential encoding technique utilized in ServiceNow: Base64 encoding.

Base64 Encoding in ServiceNow

Why Base64 Encoding is Necessary?

In ServiceNow, Base64 encoding addresses the need to convert binary data, such as images, compressed data, or compiled data, into a textual representation. This conversion enables the embedding of binary data into various text-based formats, such as HTML, CSS, or XML files, facilitating seamless integration and transmission across different systems and platforms.

The Base64 Encoding Process

Base64 encoding converts binary data into a text-based format using a specific encoding algorithm. This process transforms binary data into a set of ASCII characters, allowing you to safely transmit it over protocols that only support text data. Conversely, Base64 decoding reverses this process, converting the encoded text back into its original binary form.

Example

Imagine a scenario where a ServiceNow application needs to transmit binary data, such as an image file, over an HTTP request. Before transmission, the binary data undergoes Base64 encoding to convert it into a text-based representation. This encoded data can then be included in the HTTP request payload. Upon receiving the request, the ServiceNow instance decodes the Base64 encoded data to reconstruct the original binary file.

Base64 Encoding & Decoding Scripts

// Base64 Encoding Example
var binaryData = new GlideStringUtil();
var base64EncodedData = binaryData.base64Encode('Hello World'); // Base64 encode data
gs.info('Base64 Encoded Data: ' + base64EncodedData); // Log Base64 encoded data// Base64 Decoding Example
var base64EncodedData = 'SGVsbG8gV29ybGQ/'; // Base64 encoded data
var binaryData = GlideStringUtil.base64Decode(base64EncodedData); // Decode Base64 data
gs.info('Decoded Binary Data: ' + binaryData); // Log decoded binary data

Usage in ServiceNow

  1. Attachment Handling: When you upload file attachments to a ServiceNow record, ServiceNow converts the files to Base64 format before storing or sending them using REST. When you download these attachments, ServiceNow changes the Base64 data back to the original file format.
  2. Integration Payloads: In integrations between ServiceNow and external systems, you use Base64 encoding to send binary data, like images or documents, over HTTP requests or other communication methods. This ensures smooth data exchange between ServiceNow and other platforms.

Also, you often send binary data through HTTP POST requests, especially in authentication systems like SAML or OpenID Connect. In these cases, you usually convert the binary data to Base64 format before sending it via HTTP POST. If you use the Base64-encoded data in a URL, you also need to URL encode it. This process ensures that binary data is securely and reliably transmitted over text-based protocols.

Now that we’ve explored the essential encoding techniques used in ServiceNow, let’s delve into the world of hashing, a fundamental cryptographic process that ensures data integrity and security.

Hashing in Cryptography

In cryptography, hashing stands as a fundamental concept, forming the foundation of many security protocols and mechanisms. At its core, a cryptographic hashing function transforms any input data into a fixed-size text representation known as a hash or digest using hashing algorithms like SHA-256/512 or MD5. This is an irreversible process and it ensures data integrity and uniqueness.

Applications of Hashing

  1. Password Security: When storing passwords in a database, systems use hashing algorithms like SHA-256 or SHA-512 to hash the password along with any optional salt (a prefix or a postfix). To authenticate logins, the system hashes the password entered by the user using the same algorithm and compares it with the hashed password stored in the database. This ensures passwords are securely stored and enables secure logins.
  2. Data Integrity Verification: You can also hash files to generate a digest. The hashed value or digest of the file will not change unless someone tampers with the file. This helps verify data integrity during transmission.
  3. Message Authentication: Hashing ensures that messages are authentic and have maintained their integrity during transmission. In authentication systems, hashes are used to verify that the message has not been changed or tampered with.

Hashing in ServiceNow

ServiceNow prioritizes data security and integrity by using hashing algorithms like SHA-256 and SHA-512 to strengthen authentication and verify data integrity.

Hashing is also important in protocols like SAML 2.0 for checking data integrity and message authentication. We will discuss this more in the next article on SAML 2.0.

Unlocking Encryption: Key-Based Symmetric and Asymmetric Techniques

The primary goal of encryption is to safeguard confidentiality, ensuring that only intended recipients can understand the transmitted data.

In this article, we will delve into key-based encryption—a method extensively utilized in contemporary digital environments, including by platforms like ServiceNow.

We will explore two predominant types of encryption: symmetric and asymmetric, each with its unique advantages and challenges. Due to these characteristics, the industry has developed hybrid encryption, which combines the strengths of both symmetric and asymmetric methods. By understanding these three encryption types, we can better appreciate why ServiceNow adopts them and how they can help address challenges that may arise when dealing with this topic within the platform.

Let’s now explore each of them.

Symmetric Encryption: A Real-Time Approach

In symmetric encryption, you use a single key for both encrypting and decrypting data. This method is fast, uses less CPU power, and keeps the encrypted text (cipher) the same size as the original text. Such efficiency makes symmetric encryption best for applications where real-time encryption and decryption are crucial, such as secure communication channels (e.g., VPNs) or data streaming services (e.g., Netflix).

However, symmetric encryption presents a significant challenge: securely sharing the encryption key between the sender and the recipient. Without a secure mechanism for key distribution, the integrity of encrypted communication may be compromised. This necessity highlights the importance of encryption protocols and the ongoing need for robust security measures, including key management systems and secure channels for key exchange.

One commonly used algorithm in symmetric encryption is the Advanced Encryption Standard (AES). AES allows for various key lengths, such as AES-128, AES-192, and AES-256, with ServiceNow predominantly using AES-128 due to its balance between security and efficiency

Strengths of Symmetric Encryption:

  • Faster processing compared to asymmetric encryption.
  • Maintains the size of the encrypted text equal to the original plaintext.
  • Ideal for real-time encryption and decryption scenarios.

Weaknesses of Symmetric Encryption:

  • Requires secure distribution of encryption keys.
  • Vulnerable to key interception or compromise.
  • Limited scalability for large-scale encryption operations.

Example: Symmetric Encryption

In the context of symmetric encryption, let’s consider a scenario involving two users: Alice (the sender) and Bob (the recipient). They communicate over the internet, represented by a cloud icon, and exchange sensitive information securely using symmetric encryption.

 

Asymmetric Encryption: Securing Communications with Keys

To address the limitations of symmetric encryption, especially the challenge of securely sharing the secret key, cryptographers developed asymmetric encryption, also known as public-key encryption. This method uses two keys for each participant: a private key and a public key. Asymmetric encryption enhances security by allowing secure communication without the need for exchanging secret keys beforehand.

In asymmetric encryption, each participant generates a unique pair of keys: a private key and a public key. The private key is kept secure by the owner and never shared, acting as a digital signature to confirm the owner’s identity and authenticity. The public key, on the other hand, is shared freely, allowing others to send secure communications without compromising security.

The RSA algorithm is the most widely used method in asymmetric encryption. It involves a private key and a public key. Data encrypted with the public key can only be decrypted with the corresponding private key, ensuring confidentiality and security. Likewise, data signed with the private key can be verified with the public key, guaranteeing authenticity and integrity.

Now, let’s illustrate how asymmetric encryption works in practice with a scenario involving Alice and Bob:

Example: Secure Email Communication

Alice, a business executive, needs to send a confidential email containing financial reports to Bob, her colleague. To ensure the privacy and integrity of the email contents, both Alice and Bob utilize asymmetric encryption:

  • Key Generation: Both Alice and Bob generate their own pairs of asymmetric encryption keys: a Private key and a corresponding Public key. Each individual keeps their Private key securely stored and never shares it with anyone, while freely distributing their Public key to others.
  • Encryption: Before sending the email, Alice encrypts the contents using Bob’s Public key. This process transforms the plaintext email into ciphertext, ensuring that only Bob, with his corresponding Private key, can decrypt and read the message. The encrypted email is then sent to Bob via the email service provider.
  • Reception by Bob: Upon receiving the encrypted email, Bob uses his Private key to decrypt the contents. Only Bob’s Private key, known only to him, can successfully decrypt the ciphertext, revealing the original plaintext email.
  • Response: If Bob needs to respond to Alice’s email, he can encrypt his reply using Alice’s Public key. This ensures that only Alice, with her corresponding Private key, can decrypt and read the message, maintaining the security of their communication.

By leveraging asymmetric encryption with RSA keys, Alice and Bob can securely exchange sensitive information via email, confident in the confidentiality, authenticity, and integrity of their communication.

In practical implementations, the distribution and verification of public keys are facilitated by digital certificates issued by trusted Certificate Authorities (CAs). These certificates, conforming to the X.509 standard, bind public keys to identities, providing a reliable means of authentication and trust in the digital world.

Strengths of Asymmetric Encryption:

  • Private key is never shared, enhancing security.
  • Facilitates secure digital signatures and key exchange protocols.
  • Enables secure communication over insecure channels without pre-shared keys.

Weaknesses of Asymmetric Encryption:

  • Increased computational overhead compared to symmetric encryption.
  • Larger key sizes lead to larger ciphertexts and slower processing speeds.
  • Key management and distribution can pose logistical challenges in large-scale deployments.

Through asymmetric encryption with individual pairs of asymmetric encryption keys, Alice and Bob can securely exchange sensitive information via email, protecting the confidentiality, authenticity, and integrity of their email correspondence.

Hybrid Encryption: Combining the Best of Both Worlds

While symmetric encryption excels in real-time encryption and decryption scenarios, and asymmetric encryption provides secure key exchange, both methods have their limitations. Symmetric encryption requires a secure channel for key distribution, while asymmetric encryption introduces computational overhead. Hybrid encryption combines the strengths of both approaches, maximizing security in data transmission.

In hybrid encryption, symmetric encryption encrypts the actual data, while asymmetric encryption securely exchanges the symmetric key. This approach minimizes computational overhead and ensures secure key distribution, making it ideal for applications where both efficiency and security are important.

Let’s delve deeper into how hybrid encryption works through an example of secure email communication between Alice and Bob:

Example: Secure Email Communication

Alice, needing to send a large financial report to Bob, initiates the hybrid encryption process:

  • Key Generation: Alice generates a random secret key and uses symmetric encryption (e.g., AES 256) to encrypt the email contents, including any attachments.
  • Encryption of Secret Key: Alice encrypts the random secret key using Bob’s public key, ensuring that only Bob can decrypt it.
  • Secure Transfer: Alice sends the AES-encrypted data and the asymmetrically encrypted secret key to Bob through the email service provider.
  • Reception by Bob: Upon receiving the encrypted data and secret key, Bob decrypts the asymmetrically encrypted key using his private key, obtaining the original secret key. Finally, Bob uses the decrypted secret key to decrypt the AES-encrypted data, recovering the plaintext email and any attachments.

Applications automatically handle encryption and decryption using libraries. For example, when generating a SAML request, ServiceNow generates encrypted data and key information using packages, stores them in XML format, and sends them using HTTP post. ServiceNow also base64 encodes these encrypted pieces to keep the data intact during transmission.

Hybrid encryption combines the strengths of both symmetric and asymmetric methods. This approach ensures secure and efficient data exchange, providing strong protection for data as it travels.

Digital Signatures: Ensuring Data Integrity and Authenticity

In addition to encryption, digital signatures play a crucial role in securing data transmission, providing integrity and authentication. While encryption safeguards the confidentiality of data, digital signatures verify the origin and integrity of the message.

Let’s delve into how digital signatures work and how they complement encryption:

Utilizing Hashing Algorithms: Digital signatures leverage hashing algorithms to condense messages into smaller, fixed-size representations, ensuring efficient processing. These algorithms generate a unique fingerprint or digest of the original message, preserving its integrity.

Signature Generation: Suppose Alice intends to send a message to Bob. Alice first generates the message and then applies a hashing algorithm to produce a digest of the message. Next, she encrypts this digest using her private key, creating the signature. This signature serves as proof of authenticity and integrity for the message.

Signature Verification: Upon receiving the message and signature, Bob employs Alice’s public key to decrypt the signature, revealing the original digest. Independently, Bob calculates a hash of the received message. If the calculated hash matches the decrypted digest, two critical aspects are verified:

  • Integrity: Any alteration to the message would result in a different hash, ensuring that the message remains unchanged since Alice signed it.
  • Authentication: Since only Alice’s private key could have generated the signature, decrypting it with Alice’s public key confirms its authenticity. This authentication mechanism proves that Alice is the true sender of the message.

Application of Signatures: While we often associate signatures with messages, they extend beyond text-based communication. Signatures can authenticate various data forms, such as certificates, software, emails, and more. The essence of signatures lies in providing both integrity and authentication, irrespective of the data type.

Let’s illustrate the digital signature process using Alice and Bob:

Example: Signing a Data Message

Imagine Alice needs to sign a critical document or data message and send it to Bob securely. Here’s how digital signatures come into play:

  • Message Creation: Alice prepares the document or data message that needs to be signed. It could be any digital content, such as a contract, a software update, or an important report.
  • Signature Generation by Alice: Before sending the data message, Alice computes a hash (digest) of the message using a hashing algorithm like SHA256. This hash serves as a unique representation of the content. Alice then encrypts this hash using her private key, generating the digital signature.
  • Sending the Signed Message: Alice sends the data message along with the digital signature to Bob. The message contains both the original content and the attached signature.
  • Verification by Bob: Upon receiving the data message, Bob extracts the message and the attached digital signature. Using Alice’s public key, which he previously obtained or can access from a trusted source, Bob decrypts the digital signature, obtaining the hash of the original message.
  • Hash Calculation by Bob: Independently, Bob calculates the hash of the received message using the same hashing algorithm (SHA256). This calculation results in a hash value.
  • Comparing Hashes: Bob compares the hash value obtained from his calculation with the decrypted hash obtained from Alice’s digital signature. If the two hash values match, Bob can be confident that the message has not been altered since Alice signed it. This verifies the integrity of the data message.
  • Authentication: Additionally, since only Alice’s private key could have produced the digital signature that Bob successfully decrypted with Alice’s public key, Bob can authenticate that the message indeed originated from Alice.

By using digital signatures in data transmission, Alice and Bob can ensure their communication is both genuine and intact, adding more security beyond encryption.

This example shows how digital signatures make data exchange safer by keeping messages unchanged and verifying the sender’s identity.

While this example only uses digital signatures without encryption, combining both techniques often boosts security. For instance, in SAML scenarios, Alice can first sign the data with her private key, then encrypt it with Bob’s public key before sending it. Bob would then decrypt the message with his private key and verify its origin with Alice’s public key.

This hybrid method, mixing digital signatures and encryption, fully protects sensitive data during transmission, ensuring both integrity and authenticity. We’ll explore these scenarios more in our next article on SAML 2.0.

Conclusion

In this article, we explored the essential cryptographic technologies necessary for securing applications within ServiceNow. Understanding these principles sets the stage for our next discussion on SAML 2.0, where we’ll dive deeper into how these cryptographic measures are applied in implementing secure Single Sign-On (SSO) solutions. Stay tuned for more advanced topics that will further enhance your security posture in ServiceNow.

The post Demystifying Cryptography in ServiceNow: A Comprehensive Guide to Secure Data Transmission appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/demystifying-cryptography-servicenow/feed/ 1
Edge Encryption and Tokenization Explained https://servicenowguru.com/system-definition/edge-encryption-tokenization-explained/ Wed, 05 Jun 2024 16:48:11 +0000 https://servicenowguru.com/?p=15898 Introduction Many people may not fully grasp what edge encryption is or how it specifically applies to platforms like ServiceNow. The intent of this writeup is not to replace ServiceNow's technical docs on edge encryption, but to give you a solid understanding of what edge encryption and tokenization actually can do for your instance's

The post Edge Encryption and Tokenization Explained appeared first on ServiceNow Guru.

]]>

Introduction

Many people may not fully grasp what edge encryption is or how it specifically applies to platforms like ServiceNow. The intent of this writeup is not to replace ServiceNow’s technical docs on edge encryption, but to give you a solid understanding of what edge encryption and tokenization actually can do for your instance’s security posture.

Edge encryption is more than just a buzzword; it represents a potentially critical layer of security that protects sensitive data at the boundaries of your network. As cyber threats become increasingly sophisticated, ensuring that data is encrypted as it enters and exits your network is essential. Without this, any data intercepted during transit could be exploited by malicious actors, leading to data breaches, financial loss, and damage to your organization’s reputation.

Two example scenarios that come to mind are healthcare systems that may be storing PHI within the HCLS module, and retail companies storing customer PII within the CSM module. Many organizations may want to keep this plaintext data out of their instance’s database completely, but still have it accessible for platform functionality. Failing to properly secure this data can have severe consequences, not only for compliance but also for the overall security and efficiency of your business operations. With edge encryption, you own your own keys and proxy servers to give you full visibility into the encryption/decryption process.

Regulations are getting stricter all the time, including data residency requirements. In addition to standard edge encryption, adding a tokenization database on your own network to the mix allows your sensitive data to live within your network and then even the ciphertext on your instance is not derived from the sensitive data (more on that in the article). The coolest thing about tokenization is that the end-user is none the wiser, as the tokenized data is swapped in their response before it’s rendered to them!

Understanding and implementing edge encryption is not just about protecting data—it’s about adding an additional layer to your platform’s  ‘defense in depth’ strategy.

But What Does It Mean?

Edge Encryption Defined

Edge Encryption is a security mechanism that encrypts sensitive data as it enters and exits a network boundary, ensuring the data is unreadable if intercepted during transit. It allows organizations to maintain control over their encryption keys and manage the data encryption process within their own infrastructure, rather than in the cloud. This is more common in highly regulated environments where highly sensitive data is being exchanged. Tokenization is an optional function that is highly valuable when sensitive data must reside within the customer’s network and NEVER be stored within the instance. Tokenization replaces sensitive data elements with a non-sensitive equivalent, called a token, which has no exploitable value. For example, a social security number can be replaced with a randomly generated string of characters that has no inherent value outside the specific context. This ensures that even if data is intercepted, it cannot be used maliciously.

Edge Encryption is a crucial security mechanism that encrypts data as it enters and exits a network boundary, ensuring that it remains unreadable if intercepted during transit. But why should you care about edge encryption? The consequences of not understanding and implementing this technology can be dire, including data breaches, loss of sensitive information, and compliance violations. On the other hand, understanding and utilizing edge encryption can empower your organization to maintain control over encryption keys and manage the data encryption process within your own infrastructure, rather than relying on cloud services. This is particularly vital in highly regulated environments where the exchange of highly sensitive data is common.

Tokenization Defined

Furthermore, tokenization is an optional yet highly valuable function that can enhance data security. When sensitive data must remain within the customer’s network and never be stored within an instance, tokenization replaces sensitive data elements with a non-sensitive equivalent, called a token, which has no exploitable value. For example, a social security number can be replaced with a randomly generated string of characters that holds no inherent value outside its specific context. This ensures that even if data is intercepted, it cannot be used maliciously.

Hover Over Each Step To Learn More

Components

Client: The client is the user or system that initiates a request to ServiceNow.

Load Balancer: The load balancer is a device or software that distributes incoming network traffic across multiple servers to ensure no single server becomes overwhelmed. It optimizes resource use, maximizes throughput, minimizes response time, and avoids overload.

Proxy Servers: Proxy servers act as intermediaries between the client and ServiceNow. They handle client requests by forwarding them to the appropriate server and can provide additional services such as encryption, caching, and request filtering.

Database for Tokenization (Optional): This optional component is used to store tokens that replace sensitive data elements. Tokenization helps protect sensitive information by substituting it with non-sensitive equivalents that can be mapped back to the original data if necessary.

ServiceNow Instance: Where the actual processing and storage of data occur. It handles the requests from the client, processes them, and returns the responses.

Zooming In On Tokenization

Tokenization involves replacing sensitive data (such as social security numbers in the below example) with unique tokens before the data is sent to and stored in the ServiceNow instance. These tokens are meaningless outside the specific context, thereby protecting the actual data even if it is intercepted and decrypted without authorization.

When implementing tokenization, your proxy servers rely on a MySQL database located within your network. This database, shared by all proxy servers, stores mappings between the clear text values and their corresponding tokens. It’s crucial to maintain regular backups of this database to avoid data loss, as losing the database means losing the ability to restore clear text values from tokens.

Here’s a comparison of how an SSN value would be stored after edge encryption with tokenization enabled versus without:

Edge Encryption Benefits

  • Encrypts sensitive data at the network edge, ensuring data remains secure both in transit and at rest.
  • Meets requirements for data residency and sovereignty by ensuring sensitive data does not leave the customer’s environment in a readable form.
  • Customers maintain complete control over encryption keys, which are managed within their infrastructure.
  • The average additional latency introduced by the encryption process is around 40ms per transaction, which is relatively low.
  • Edge Encryption also works with mobile devices
  • Offers tokenization capabilities for additional security layers, especially useful for patterns like social security numbers and credit card information.
  • Supports load-balanced configurations to ensure high availability and continuity of encryption services.
  • Provides the ability to configure which data gets encrypted, with options for field-level encryption.
  • Users interact with data as they normally would

Edge Encryption Considerations

  • Complex Setup and Maintenance: Requires a careful and sometimes complex setup of proxy servers within the customer’s network.
  • Infrastructure Requirements: Customers need to provision and maintain the necessary infrastructure for the Edge Encryption proxies and tokenization databases.
  • Limited Field Types: Edge Encryption only supports encryption for string, journal, and date fields and not for other data types like choice fields or system fields.
  • Server-Side Processing Limitations: Encrypted data cannot be used for server-side processing, such as in business rules or scripts that need to evaluate the data.
  • Customization Needs: Custom HTTP requests or integrations may require additional encryption rules to be written.
  • Key Management Responsibilities: Customers must take on the responsibility of key management, including key rotation.
  • Potential Performance Impacts for Attachments: Encrypting attachments can have a more significant performance impact, especially for larger files.
  • Impact on Reporting and Searching: Reporting capabilities can be limited, and global searches are not supported for encrypted data unless accessed through the proxy.

Key Management

Effective key management is crucial for maintaining the security of Edge Encryption. As a ServiceNow administrator, you are responsible for providing and managing the encryption keys used in this process. When setting up Edge Encryption, you need to decide whether to use AES 128-bit or AES 256-bit encryption, with a default AES 128-bit key required even if not utilized. Key storage options include file systems, Java KeyStore, or Enterprise Key Management (EKM), each with its own considerations for security and accessibility. Regular key rotation is essential to ensure ongoing security, and it may be necessary to perform a mass encryption job to re-encrypt data with new keys. Additionally, before removing an encryption key, it is critical to decrypt all associated data to prevent data loss. Key management is an extremely critical topic to understand both at a technical and functional level. Mistakes can cause major losses of data when managing your own keys. If it isn’t obvious already, it’s critical to pay attention to the documentation when implementing. If a partner is implementing for you, ensure you have the appropriate technical and architectural documentation for handoff to your team.

Conclusion

In summary, edge encryption provides an additional layer of protection by ensuring that sensitive data is encrypted as it enters and exits your network, mitigating the risk of data breaches and unauthorized access. The ability to maintain control over your encryption keys and manage the encryption process within your own infrastructure, rather than relying on a third party, offers significant security and compliance advantages.

Tokenization adds an additional layer of security to edge encryption by replacing sensitive data with non-sensitive tokens, ensuring that even if data stored on the instance is intercepted and decrypted, it will not be useful. This approach is particularly valuable for organizations handling highly sensitive information, such as healthcare systems storing PHI or retail companies managing customer PII. By combining edge encryption with tokenization, you can meet stringent regulatory requirements and enhance your overall data protection strategy.

Ultimately, integrating edge encryption into your ServiceNow instance not only safeguards your data but also reinforces your organization’s defense in depth strategy. As cyber threats continue to evolve, adopting these advanced security measures is not just beneficial—it’s necessary for maintaining the integrity and trustworthiness of your digital operations. By taking proactive steps to implement edge encryption and tokenization, you can protect your sensitive information, ensure compliance, and provide a secure environment for your users and stakeholders.

The post Edge Encryption and Tokenization Explained appeared first on ServiceNow Guru.

]]>
Localization framework fulfillment (LP, LRITM, LFTASK) https://servicenowguru.com/system-definition/localization-framework-fulfillment-lp-lritm-lftask/ Wed, 18 Jan 2023 15:26:39 +0000 http://servicenowguru.com/?p=13161 Recently I dove into the Localization Framework, noticed some new tables, made some incorrect initial assumptions, and came out with an understanding of the table structure that I could not find consolidated on the documentation site. Number Prefix Label Name Extends LP Localization Project sn_lf_project Task LRITM Localization Requested Item sn_lf_requested_item LFTASK Localization Task sn_lf_task

The post Localization framework fulfillment (LP, LRITM, LFTASK) appeared first on ServiceNow Guru.

]]>
Recently I dove into the Localization Framework, noticed some new tables, made some incorrect initial assumptions, and came out with an understanding of the table structure that I could not find consolidated on the documentation site.

Number Prefix Label Name Extends
LP Localization Project sn_lf_project Task
LRITM Localization Requested Item sn_lf_requested_item
LFTASK Localization Task sn_lf_task Task

 

You might think as I did that this data model aligns to request fulfillment with LFTASK the same as SCTASK, LRITM as RITM, and LP as REQ however this is incorrect.

Localization Projects (LP)

Are groupings of multiple requested items (LRITM). Localization Projects are assigned to a group with the localization_manager role and “assigned to” a member of the group to manage this effort. This table extends the task table directly. Localization Projects are not required in localization fulfillment.

https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/localization-framework/concept/localization-projects.html

Module

Localization Framework > My Projects

 

Localization Requested Items (LRITM)

Can be added to a project to allow fulfillers to translate items in bulk. Localization Requested Items can be added to a project after they are created and does not need to be done during creation. The Localization Requested Item does not extend task and links through the document id to the target artifact record (knowledge, catalog item, VA topic, etc). Localization Requested Items link to Localization Tasks for translation and are not assigned or actioned directly.

https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/localization-framework/task/add-lritm-to-project.html

Module

Localization Framework > My Requested Items

 

Localization Tasks (LFTask)

Are actionable tasks per target language for localization fulfillers with the actions being “Verify Translations” and “Translate”. Localization Tasks directly extend the task table and are related to Localization projects. Localization fulfillment and approval is well documented in the links below.

Fulfillment – https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/localization-framework/task/fulfill-localization-task.html

Approval – https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/localization-framework/task/approve-localization-task.html

Module

Localization Framework > My Tasks

 

Links

Localization Framework: https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/localization-framework/concept/localization-framework.html

States: https://docs.servicenow.com/bundle/tokyo-platform-administration/page/administer/localization-framework/reference/localization-task-states.html

 

For those that like a picture, here is a representation of the tables and corresponding relationships.

The post Localization framework fulfillment (LP, LRITM, LFTASK) appeared first on ServiceNow Guru.

]]>
Harnessing the Power of Dynamic Filters in ServiceNow https://servicenowguru.com/reporting/harnessing-power-dynamic-filters-servicenow/ https://servicenowguru.com/reporting/harnessing-power-dynamic-filters-servicenow/#comments Fri, 04 Sep 2015 12:14:54 +0000 https://servicenowguru.wpengine.com/?p=5637 ServiceNow adds a ton of great functionality to each new product release. Often times, the most helpful and useful features (at least to a long-time user of the system) are enhancements to simplify or improve on existing functionality. Unfortunately, these are often some of the most under-appreciated and end up getting lost in the marketing

The post Harnessing the Power of Dynamic Filters in ServiceNow appeared first on ServiceNow Guru.

]]>
ServiceNow adds a ton of great functionality to each new product release. Often times, the most helpful and useful features (at least to a long-time user of the system) are enhancements to simplify or improve on existing functionality. Unfortunately, these are often some of the most under-appreciated and end up getting lost in the marketing hype of all of the brand new capabilities that you may or may not use. One such example that recently arrived to ServiceNow is ‘Dynamic filters’. In this post, I’ll share what dynamic filters are, and show how you can extend and leverage this capability to improve your own ServiceNow system.

DynamicallyFilteredList

The ServiceNow wiki does a decent job of explaining the basic concept and usage of dynamic filters. There are 1000’s of scenarios where users of the system need to query for information, display a list of data, generate a report, or values from a reference field based on a specific, logical filter criteria. There are many examples of this…my Group’s work, my approvals, records assigned to other members of my groups, etc. These types of scenarios, though simple on the surface, actually require sometimes very complex code to query for and return the correct data. ServiceNow has always allowed you to do this, of course, but the approach (asking a typical end-user to remember and correctly populate a specific query string with a function call directly in the filter) really isn’t one that works well — even if that user happens to be an admin of the system. Those query strings generally look something like this and can be pasted directly into any filter criteria to return information…

javascript:gs.getUserID();
javascript:getRoledUsers();
etc...

The general idea behind dynamic filters is to allow a ServiceNow administrator to pre-define the filter query logic to return the correct information from a back-end function, then set up a dynamic filter definition to point to that information via a simple label invoked from any filter field criteria in the system. These dynamic filters can be as flexible and complex as you need them to be, but the end-user doesn’t need to know or understand any of that complexity in order to benefit from them!

There are several of these dynamic filters defined out-of-box that you can use right away as examples for creating your own. You can find them under ‘System Definition -> Dynamic Filter Options’ in your left nav. For more complex scenarios, you’ll actually point your dynamic filter to a back-end Script Include function that contains all of the logic and does the heavy lifting.

One common filter criteria that I hear about all of the time that isn’t handled out-of-box is to filter for records associated to members of my groups via some user field (usually an assignment or ownership of some sort). Tickets assigned to members of my groups, outstanding approvals for members of my groups, etc. This configuration can be added to your system by following a few simple steps as shown below…

    1. Create a new ‘On Demand’ Script Include function.

I’ve written about this capability before so you can reference that article for more details if you need. Creating this script include will allow us to easily call a reusable function to return the data we want…in this case a list of users that belong to the same group as the current user. The basic idea for this function is to get a user’s groups, then find the active group members sys_id values associated with those groups and add them to an array to be returned. You can navigate to ‘System Definition -> Script Includes’ in your left nav to create this. Don’t forget that the ‘Name’ value of any on demand script include (like this one) needs to exactly match the name of the function you’re calling in the script!

‘getMyGroupMembers’ Script Include
Name: getMyGroupMembers
Active: True
Client callable: True
Description: Queries for members of groups that the currently logged-in user is also a member of.
Script:

function getMyGroupMembers(){
var myGroups = gs.getUser().getMyGroups();
var groupsArray = new Array();
var it = myGroups.iterator();
var i=0;
var groupMemberArray = new Array();
while(it.hasNext()){
var myGroup = it.next();
//Query for group members
var grMem = new GlideRecord('sys_user_grmember');
grMem.addQuery('group', myGroup);
//Only return active users
grMem.addQuery('user.active', true);
grMem.query();
while(grMem.next()){
//Add to user sys_id to array
groupMemberArray.push(grMem.user.toString());
}
i++;
}
return groupMemberArray;
}
    1. Create a new ‘Dynamic Filter’ record

      The on-demand function is great and allows you to easily return the data you want. From any place you can call scripts in the system. This is fantastic for business rules, workflow scripts, etc. but the average user running a report or filtering a list is not going to know (nor should they need to know) the exact syntax and function name to call. This is where Dynamic Filters come in! We can wrap that script call in a friendly label that displays in any filter anywhere in the system so that a normal human being can access it as well. Your dynamic filter for the script above should look just like I’ve shown in the screenshot below. You can create it by navigating to ‘System Definition -> Dynamic Filter Options’

DynamicFilter

 

NOTE: One interesting bit of information I discovered while working with dynamic filters is the way that the system handles the encoded query strings for them. You end up with a query string (that you could reuse) that looks like this…

assigned_toDYNAMIC1a570fd90856c200aa4521695cf1eb24

The ‘DYNAMIC’ keyword indicates the use of a dynamic filter, and what follows is the sys_id of the corresponding dynamic filter record.

The end result is a nice, dynamic filter option for filtering where the user listed in a user field is a member of one of your groups! This is just one example of a fantastic capability in ServiceNow. There are lots of other use cases that you can add using this same approach.

DynamicallyFilteredList

The post Harnessing the Power of Dynamic Filters in ServiceNow appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/reporting/harnessing-power-dynamic-filters-servicenow/feed/ 10
Forcing a Session Timeout for the ‘Remember me’ Checkbox https://servicenowguru.com/system-definition/forcing-session-timeout-remember-me-checkbox/ https://servicenowguru.com/system-definition/forcing-session-timeout-remember-me-checkbox/#comments Wed, 05 Aug 2015 14:54:39 +0000 https://servicenowguru.wpengine.com/?p=5617 One important piece of managing user logins in any system is determining the maximum session timeout for users. ServiceNow allows administrators to set a global session timeout or allow users the option of having their session remembered and never logging the user out unless they log out themselves. In some cases, you may need additional

The post Forcing a Session Timeout for the ‘Remember me’ Checkbox appeared first on ServiceNow Guru.

]]>
One important piece of managing user logins in any system is determining the maximum session timeout for users. ServiceNow allows administrators to set a global session timeout or allow users the option of having their session remembered and never logging the user out unless they log out themselves.

In some cases, you may need additional flexibility around these session timings. You might want to time users out of the system after a certain period of time even if they have the ‘Remember me’ checkbox checked. You might also want to evaluate the timeout based on specific user criteria. The base configuration doesn’t allow you to have this kind of flexibility, but you can introduce additional capabilities via a scheduled job script. This solution shows how you can force a session timeout even for users with the ‘Remember me’ checkbox selected.

RememberMe

This configuration can be accomplished in a few simple steps as shown below…

  1. Create a new system property to store the maximum number of hours of inactivity for ‘Remember me’ logins.

    Storing the maximum number of hours in a system property will allow for the modification of the timeout without having to go in and modify the scheduled job script directly.

  2. ‘glide.ui.remember_me_timeout’ System Property
    Name: ‘glide.ui.remember_me_timeout’
    Description: Log out ‘Remember me’ users after a certain amount of inactivity (in hours).
    Type: Integer
    Value: 24 (or whatever you like)

  3. Create a new scheduled job to automatically run a script.

    The script queries the ‘Logged in Users’ [v_user_session] table for users who haven’t had an active transaction in the last ‘x’ number of hours based on the ‘glide.ui.remember_me_timeout’ property you set up above. If the condition is met, the user session is locked, logging them out of the system. This is based on the mechanism that ServiceNow has to allow admins to log users out of the system manually. Once logged out, the user will be redirected to a login screen upon their next attempted navigation within the system. This script can be further adjusted to calculate the timeout based on minutes or even look at individual user criteria as well.

  4. ‘Force Maximum Inactivity Timeout (Remember me)’ Scheduled Job
    Name: Force Maximum Inactivity Timeout (Remember me)
    Active: True
    Run: Periodically
    Repeat interval: 15 minutes
    Run this script:

    //Log out 'Remember me' users after a certain amount of inactivity
    //Pulls number of hours from 'glide.ui.remember_me_timeout' property
    var maxInactiveHours = gs.getProperty('glide.ui.remember_me_timeout');
    var sess = new GlideRecord('v_user_session');
    sess.addEncodedQuery('user!=guest^last_transaction_timeRELATIVELE@hour@ago@' + maxInactiveHours);
    sess.query();
    while(sess.next()){
        //Optionally test for user-specific criteria here. 'sess.user' contains the user_name so you can query on it.
        sess.locked = true;
        sess.update();
    }
    

If you’ve done all of the above steps correctly, you should end up with a simple-to-maintain mechanism for controlling the duration of those ‘Remember me’ sessions automatically.

The post Forcing a Session Timeout for the ‘Remember me’ Checkbox appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/forcing-session-timeout-remember-me-checkbox/feed/ 6
Find all System References to a Specific Record https://servicenowguru.com/system-definition/find-references-specific-record/ https://servicenowguru.com/system-definition/find-references-specific-record/#comments Mon, 29 Jul 2013 15:06:20 +0000 https://servicenowguru.wpengine.com/?p=4957 At Crossfuze, one of the areas we specialize in is helping struggling ServiceNow implementations get back on the right track. One type of issue that we encounter frequently is bad or redundant data that’s being used and needs to be deleted, de-activated, or cleaned up in some way. The best way to handle this issue

The post Find all System References to a Specific Record appeared first on ServiceNow Guru.

]]>
At Crossfuze, one of the areas we specialize in is helping struggling ServiceNow implementations get back on the right track. One type of issue that we encounter frequently is bad or redundant data that’s being used and needs to be deleted, de-activated, or cleaned up in some way. The best way to handle this issue is to keep it out of your system in the first place, but what do you do if it has been there for months or years and has been referenced in who knows how many places and ways? The options vary depending on the situation, but a common component of any potential solution is finding out just how much of a problem you’ve really got. How do you decide to replace or modify the bad data if you don’t even understand where or how that bad data is being used?

To help answer this question, we recently created a really useful admin utility to find all places where a record is referenced. In this article I’ll show you how you can set it up in your instance!

Find Record References UI Action

The script to produce the kind of data you need in this case could be run from a variety of places. We chose to make it a simple global UI action so that it would be easy to access and use on any record in the system. The UI action works by first querying the system dictionary for all reference, document_id, and condition fields that reference the table you initiate the action from. It filters out unnecessary system and log tables. Then it iterates through all of the remaining records, performing a table/sys_id query on each table where a match exists. The query results are then output to the browser in an information message.

Please note that depending on the record referenced, this script can end up doing a LOT of querying. Make sure you run this in your development or test system first, and be aware that the results may take a while to come back depending on the specific record.

You can set the UI action up in your instance by creating a new UI action with the following settings. Once set up, you’ll have a ‘Find Record References’ link at the bottom of each form in your system.

‘Find Record References’ UI Action
Name: Find Record References
Table: Global
Order: 500
Action name: find_references
Show insert/Show update: False/True
Form link: True
Client: True
Hint: Find and display all tables and records that reference this record
OnClick: confirmFindReferences()
Condition: gs.hasRole('admin')
Script:

//Client-side 'onclick' function
function confirmFindReferences() {
if (confirm('Performing this action will query multiple tables and records and may take a long time to complete. Are you sure you want to continue?') == false) {
return false; //Abort submission
}
//Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'find_references'); //MUST call the 'Action name' set in this UI Action
}//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if (typeof window == 'undefined')
findReferences();//Server-side function
function findReferences() {
var msg = '<b>Matching tables and columns where this record is referenced (if any) are displayed below...</b>
';
var refTable = new TableUtils(current.getTableName()).getTables();
gs.include("j2js");
refTable = j2js(refTable).join();
var refRecordID = current.sys_id;
//Query dictionary table for reference, document_id, and condition fields
var dict = new GlideRecord('sys_dictionary');
dict.addQuery('reference', 'IN', refTable).addOrCondition('internal_type', 'document_id').addOrCondition('internal_type', 'conditions');
//Do not query audit and log fields
dict.addQuery('name', 'DOES NOT CONTAIN', 'var__m_');
dict.addQuery('name', 'DOES NOT CONTAIN', 'ecc_');
dict.addQuery('name', 'DOES NOT CONTAIN', 'ha_');
dict.addQuery('name', 'DOES NOT CONTAIN', 'syslog');
dict.addQuery('name', 'DOES NOT CONTAIN', 'sys_history');
dict.addQuery('name', 'DOES NOT CONTAIN', '_log');
dict.addQuery('name', 'DOES NOT CONTAIN', 'text_search');
dict.addQuery('name', 'DOES NOT CONTAIN', 'ts_');
dict.addQuery('name', 'DOES NOT CONTAIN', 'sys_watermark');
dict.addQuery('name', 'DOES NOT CONTAIN', 'sys_audit');
dict.addQuery('name', 'NOT LIKE', 'v_%');
dict.orderBy('name');
dict.orderBy('element');
dict.query();
while (dict.next()) {
var tblName = dict.name.toString();
// Skip tables used for Table Rotation
var gr = new GlideRecord("sys_table_rotation_schedule");
gr.addQuery("name.name", '!=', tblName);
gr.addQuery("table_name", tblName);
gr.query();
if (!gr.hasNext()) {
var recMessage = ' records found';
var filterOperator = '=';
var refType = dict.internal_type;
if (refType == 'glide_list' || refType == 'conditions') {
filterOperator = 'LIKE';
}

//Query each table for matching records
var rec = new GlideRecord(tblName);
if (refType == 'glide_list' || refType == 'conditions') {
rec.addQuery(dict.element, 'CONTAINS', refRecordID);
} else {
rec.addQuery(dict.element, refRecordID);
}
rec.query();
if (rec.getRowCount() == 1) {
recMessage = ' record found';
}
if (rec.getRowCount() > 0) {
//Display table/column info
msg = msg + '<b>Table: </b><i>' + tblName + '</i>' + ' - <b>Column [Column type]: </b><i>' + dict.element + '</i> [' + dict.internal_type + ']' + ' --- ' + '<span style="color: #136fb0;">' + '<a href="' + dict.name + '_list.do?sysparm_query=' + dict.element + filterOperator + refRecordID + '" target="_blank" rel="noopener">' + rec.getRowCount() + recMessage + '</a></span>.
' + '';
}
}
}

//Query for workflow variable values
tblName = 'sys_variable_value';
var vVal = new GlideRecord(tblName);
vVal.addQuery('value', 'CONTAINS', refRecordID);
vVal.query();
if (vVal.getRowCount() == 1) {
recMessage = ' record found';
}

if (vVal.getRowCount() > 0) {
//Display table/column info
msg = msg + '<b>Table: </b><i>' + tblName + '</i>' + ' - <b>Column [Column type]: </b><i>' + 'value' + '</i> [' + 'string' + ']' + ' --- ' + '<span style="color: #136fb0;">' + '<a href="' + tblName + '_list.do?sysparm_query=' + 'valueLIKE' + refRecordID + '" target="_blank" rel="noopener">' + vVal.getRowCount() + recMessage + '</a></span>' + '.' + '';
}

gs.addInfoMessage(msg);
action.setRedirectURL(current);
}

The post Find all System References to a Specific Record appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/find-references-specific-record/feed/ 20
Delete or Update Activity log and Journal Field Entries https://servicenowguru.com/system-definition/remove-activity-log-journal-entries/ https://servicenowguru.com/system-definition/remove-activity-log-journal-entries/#comments Mon, 11 Feb 2013 16:20:18 +0000 https://servicenowguru.wpengine.com/?p=4729 ServiceNow includes the ability to provide a full audit and journal history of records in the system. This is an extremely useful feature, but there are times when you need to override this audit process. Some examples may include a technician accidentally entering IT-only work notes into the customer facing ‘Additional comments’ field on an

The post Delete or Update Activity log and Journal Field Entries appeared first on ServiceNow Guru.

]]>
ServiceNow includes the ability to provide a full audit and journal history of records in the system. This is an extremely useful feature, but there are times when you need to override this audit process. Some examples may include a technician accidentally entering IT-only work notes into the customer facing ‘Additional comments’ field on an incident, or an end user supplying confidential information such as a password or social security number in a ticket.

Unfortunately, the process of deleting or updating audit, activity, or journal entries is fairly difficult to perform, and even more difficult to remember. The customization shown here makes this process much simpler by leveraging UI actions in the standard ‘History -> List’ view from any audited record.

Update ServiceNow Audit History

First, a little technical perspective as to why this solution is helpful. Without this solution, you would need to go to two or three separate tables (sys_audit, sys_history_line, and sys_journal_field) and update or delete entries. While doing this, you would need to be extremely careful about how you query the information since all three tables can be very large and accessing them incorrectly could bring your system to its knees. You would also need to know exactly what you were looking for and be cautious about where you clicked so that you didn’t ruin audit entries in the process.

This solution provides a single, consistent UI action-driven method that keeps you out of the audit tables and updates all of the necessary places in one click. It also includes a confirmation dialog to prevent accidental updates.

WARNING: It should go without saying that you should exercise extreme care when dealing with audit or journal entries in the system. Only make modifications in these areas if it’s absolutely necessary, and only do so within your organization’s change management process.

 

Delete audit/journal entries

Deleting audit or journal entries can be accomplished by adding a new UI action with the following settings.

‘Delete History Line’ UI Action
Name: Delete History Line
Table: History [sys_history_line] Action name: delete_history_line
Show insert: false
Show update: true
Client: true
Form button: true
Onclick: confirmDelete()
Condition: gs.hasRole(‘admin’)
Script:

function confirmDelete(){
if(confirm('Are you sure you want to permanently delete this history line and all corresponding audit history?\n\nTHIS ACTION CANNOT BE UNDONE!')){
//Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'delete_history_line'); //MUST call the 'Action name' set in this UI Action
}
else{
return false;
}
}//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if(typeof window == 'undefined')
deleteHistoryLine();

function deleteHistoryLine(){
var fieldVal = current["new"];
var fieldName = current.field;

//Query for and delete the 'sys_audit' record
var aud = new GlideRecord('sys_audit');
aud.addQuery('documentkey', current.set.id);
aud.addQuery('fieldname', fieldName);
aud.addQuery('newvalue', fieldVal);
aud.query();
if(aud.next()){
aud.deleteRecord();
}

//Query for and delete the 'sys_journal_field' record (if applicable)
var je = new GlideRecord('sys_journal_field');
je.addQuery('element_id', current.set.id);
je.addQuery('element', fieldName);
je.addQuery('value', fieldVal);
je.query();
if(je.next()){
je.deleteRecord();
}

//Set redirect and info message for the parent record
gs.addInfoMessage(current.label + " entry '" + fieldVal + "' deleted.");
action.setRedirectURL(current.set.getRefRecord());

//Delete the 'sys_history_line' record
current.deleteRecord();
}

 

Update audit/journal entries

In order to update audit or journal entries through the ‘sys_history_line’ table, you need to open up security a bit so that you can change the ‘New’ field value. This can be easily accomplished by creating a new ‘write’ ACL on the ‘History [sys_history_line]’ table and the ‘New’ field. This ACL should limit the ‘write’ operation to the ‘admin’ role using the related list at the bottom of the ACL form.

Once you’ve opened up the security for the ‘New’ field, you can add the following UI action settings in the same way as the ‘Delete History Line’ UI action above.

‘Update History Line’ UI Action
Name: Update History Line
Table: History [sys_history_line] Action name: update_history_line
Show insert: false
Show update: true
Client: true
Form button: true
Onclick: confirmUpdate()
Condition: gs.hasRole(‘admin’) && current[“new”].canWrite()
Script:

function confirmUpdate(){
if(!g_form.getControl('new').changed){
alert("Please enter a new value into the 'New' field.");
return false;
}
if(confirm('Are you sure you want to permanently update this history line and all corresponding audit history?\n\nTHIS ACTION CANNOT BE UNDONE!')){
//Call the UI Action and skip the 'onclick' function
gsftSubmit(null, g_form.getFormElement(), 'update_history_line'); //MUST call the 'Action name' set in this UI Action
}
else{
return false;
}
}//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if(typeof window == 'undefined')
updateHistoryLine();

function updateHistoryLine(){
var fieldVal = current["new"];
var fieldName = current.field;
var fieldLabel = current.label.toString();
var setID = current.set.id.toString();

//Query for and update the 'sys_audit' record
var aud = new GlideRecord('sys_audit');
aud.addQuery('documentkey', current.set.id);
aud.addQuery('fieldname', fieldName);
aud.addQuery('internal_checkpoint', current.internal_checkpoint);
aud.query();
if(aud.next()){
aud.newvalue = fieldVal;
aud.update();
}

//Query for and update the 'sys_journal_field' record (if applicable)
var je = new GlideRecord('sys_journal_field');
je.addQuery('element_id', current.set.id);
je.addQuery('element', fieldName);
je.addQuery('sys_created_on', current.update_time);
je.query();
if(je.next()){
je.value = fieldVal;
je.update();
}

//Refresh the history set
if(typeof GlideHistorySet != 'undefined')
GlideHistorySet(current.set.id.getRefRecord()).refresh();
else
Packages.com.glide.audit.HistorySet(current.set.id.getRefRecord()).refresh();
//Set redirect and info message for the new set record
var newSet = new GlideRecord('sys_history_set');
newSet.get('id', setID);
gs.addInfoMessage(fieldLabel + " entry '" + fieldVal + "' updated.\nIf audit history list is empty, return to the parent record and select 'History -> List' to regenerate.");
action.setRedirectURL(newSet);
}

Once the configuration above has been applied, users with the ‘admin’ role can navigate to the history of the record by right-clicking the record form header and clicking ‘History -> List’. Then, simply open the history record to modify and delete or update accordingly!

The post Delete or Update Activity log and Journal Field Entries appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/remove-activity-log-journal-entries/feed/ 21