PDF Application Digital Signatures

Setting up the Signature Workflow Process

For the UXstorm PDF Signature Workflow Process to work, it must be started and the current “view” of the PDF must be created with button(s) to submit the PDF back into ServiceNow once the signature is signed. These buttons are a combination of an AcroForm Button and Annotations and use hidden annotation watermarks in the PDF, added by UXstorm PDF, to know the revisions, source instance, and data record, and UXstorm PDF form. The Buttons have to be added at the start of the workflow as adding them or modifying them after a field is signed with a certificate will invalidate the signature. This is also why some of the PDF generation capabilities are disabled when the Signature Workflow Process is started.

Setting up the UXstorm PDF Form

The first part of setting up the process is to configure when it starts and to set up the button(s) on the form to submit the PDF back to ServiceNow.

For the rest of this section, refer to this Figure.

Signature Workflow

Enable Signature Workflow

On the UXstorm PDF Form, check the Enable Signature Workflow check box (Flag #1). If a PDF Form doesn’t have an active Signature Workflow, then this flag will cause the check condition to happen on any update to the record. NOTE: By default, this happens on any Task or Task derived table. If the table is not a Task or does not inherit from the Task table, then check the UXstorm PDF Application setup on how to add the Business Rule PDF Condition Checker. This routine is what performs the check and, if not present, then the Signature Workflow will never start, regardless of the condition.

Starting the Process

Flag #2 shows the fields that determine when the Signature Workflow Process will start. Start Workflow can be either Condition or Script. When set to Condition, a condition query control is provided and when that condition is first met, then the Signature Workflow Process is started, and this condition is no longer used for that record.

Start Workflow can be set to Script to enable advanced/custom checking.

Start Workflow Script

This script will have a variable current provided that will be a GlideRecord of the record that the PDF is being generated from. You may use this to determine if the Signature Workflow Process should start or not. Set the variable answer to true to start the process and false if the process should not start.

Flag #3 shows the information to control the button(s) that will be placed on the PDF to submit the PDF back to ServiceNow when signed.

Signature Workflow Button Fields
Button Text This is the “Text” of the Button
Position Determines where to place each button on the page. Padding Width and Padding Height is used to pad the button from the top and sides of the page.

ValuePages
Top Left>Top left
First PageOnly the First Page
Last PageOnly the Last Page
All PagesEvery Page
Pages with SignaturesOnly pages that have a Signature Field on the page.
Specific PagesThis will cause a required field Pages to appear and enable specific pages to be specified for the buttons. NOTE: Do not use this in conjunction with Select Pages that limit the actual PDF Pages as the page numbers are dynamic and will not be what you expect. For instance, in a 5 page pdf if you set Specific Pages to 4, 5 and Select Pages is set to 3-5, then no buttons will appear as there is no page 4 or
Pages to Place Button Determines which pages in the PDF will have a button placed.

ValuePages
Top Left>Top left
First PageOnly the First Page
Last PageOnly the Last Page
All PagesEvery Page
Pages with SignaturesOnly pages that have a Signature Field on the page.
Specific PagesThis will cause a required field Pages to appear and enable specific pages to be specified for the buttons. NOTE: Do not use this in conjunction with Select Pages that limit the actual PDF Pages as the page numbers are dynamic and will not be what you expect. For instance, in a 5 page pdf if you set Specific Pages to 4, 5 and Select Pages is set to 3-5, then no buttons will appear as there is no page 4 or 5.
Pages* Only appears if Pages to Place Button is Specific Pages.

Use a “Print Range” to specify which pages and page ranges to have a submit button(s). For example, “1,3,6-10” would have pages on 1, 3, 6, 7, 8, 9, & 10 assuming there are at least 10 pages.
Padding Width Provides the padding from the left or right side of the page in points. If the button is aligned left, then it’s from the left side. If the button is aligned right, then it’s from the right side. If the button is centered, then this is ignored.
Padding Height Provides the padding from the top or bottom of the page in points. If the button is on the top, then it’s the top padding. If the button is on the bottom, then it’s the bottom padding.
Width Width of the button in points
Font The button text font
Font Size The button text font size
Color The button text color
Background Color The background color of the button
Border Color The border color of the button
Height The height of the button

Setting up the Process

After setting up when the Signature Workflow Process should start, the next step is setting up the process itself. The Signature Workflow Process is a serial process where each step is proceeded and succeeded by a single step. Only when a step is completed and the next start condition is met, is another step active. Since there must be a first step and an end step, two shadow steps are always implied with a Signature Workflow Process. These shadow steps are Start and End and are added automatically. The following is an example of a Signature Workflow Process with five defined steps and two shadow steps.

Workflow Chevron

See the section on what the Signature Widget does for the color definitions.

As mentioned earlier, the Signature Workflow Process is composed of Steps and Signatures. To set up the process, you need to provide a Workflow Definition for each step and one or more Signature Definitions per step. When a Signature Workflow Process is started, Signature Workflow Instances are created for each step and linked to their appropriate Workflow Definition. When a signature is detected during the step, a Signature Instance is created and linked to its appropriate Signature Definition.

Workflow Step

To add a step to the Signature Workflow Process, click New on the Workflow Definitions tab on the UXstorm PDF Form and submit a new Workflow Definition. Here is an example of the first step in the above process:

Workflow Definition Step

Each step will start in the order of Start, then the lowest Order, then the next lowest Order, until there are no more steps and then End is completed:

Workflow Definition Fields
Name Name of the step. This will be what is shown on the Chevron workflow visualization.
Order The order of the step. This is in ascending order.
When to Start Determines when the step should start. This is evaluated when the previous step is complete or when this is the first step after Start and the workflow is started.

ValueWhen the Step Starts
ImmediatelyStart immediately when the previous step is complete
ConditionOnly when the provided condition is true
ScriptOnly when the evaluation of the start script returns an answer = true
Condition* Only visible when When to Start is Condition. Provides the condition to match to determine that the step is complete.
Script*

Only visible when When to Start is script.

This script provides a variable current that is a GlideRecord of the record that the PDF is attached to.

Step Completed When Evaluate when this step is complete:

ValueStep Completed When
All Signatures are ValidatedWhen all Signatures that have a Signature Definition for this step is received and validated
Any Signature is ValidatedWhen any Signatures that have a Signature Definition for this step is received and validated
ScriptOnly when the evaluation of the Completion Script returns an answer = true
Completion Script* Only visible when Step Completed When is Script.

This script should set the variable answer = true if the step is complete or answer = false if it is not complete.

To assist in determining if the step should be completed, several variables are provided to the script:

VariableDescription
numSINumber of Signature Instances on the current Workflow Instance
numSDNumber of Signature Definitions on the current workflow Instance
workflow_instanceA GlideRecord object for the current Workflow Instance
workflow_defintionA GlideRecord object for the current workflow Definition
Run Revision Validation Script When this field is checked the Revision Validation Script will be ran to validate the revisions for this workflow step.
Revision Validation Script* Only visible when Step Completed When is Script.

This script should set the variable answer = true if the revision is valid or answer = false if it is not valid. Additionally, if answer is set to false, the variable reason can be set to a string containing the rease on the revision was rejected.

To assist in determining if the step should be completed, several variables are provided to the script:

VariableDescription
revisionA GlideRecord object for the current Revision record
signaturesAn Array of object containing information about all signatures on the revision
fieldsThis is a hash of all the internal_field_name and the value each field is set to
rejectedTrue if the revision has already been rejected by a previous step. False otherwise.

Signatures

Each step can have one or more signatures that are valid during the step. They are defined by providing a Signature Definition under each Step. To add a Signature Definition, click New under a Workflow Definition form’s Signature Definitions related list.

Here is an example of the Requestor’s/User’s Signature Signature Definition in the previous example.

Requestor's Signature

Each Signature Definition is only valid when the Workflow Definition is active, and each definition defines how strict or loose to validate the signature. Each signature has three items to help determine validity.

  1. The Signature Field
  2. The Certificate used to Sign the Signature Field
  3. User Mapping of the Certificate to a ServiceNow user and using that information to determine if the user who signed the field is acceptable

When the user submits a PDF Form back to ServiceNow with the Submit Button on the PDF, all the fields are read, and any Signature Fields processed, and the PDF and information is stored in a Revision Record with a reference to the current record. This is what the PDF Signature Widget shows as Revisions. If a new Signature Field or Fields are signed, they are processed and matched to an appropriate Signature Definition for the current active workflow Stage. If there is no Signature Definition or no active workflow Stage, then the signature is immediately rejected, otherwise the rules on the signature are evaluated using the Certificate. If the validation fails or the signature is rejected immediately, then the entire revision is rejected as there is no way to separate a single signature out of the PDF Document.

Setup the processing of the Signature by adjusting the following fields appropriately for the desired result:

Signature Definition Fields
Name Name of the Signature. This will be what is shown on the workflow visualization as the Signature Buttons.
Signature Field The Signature Field on the PDF form. This field must be defined by Adobe as a Signature field.
Allow Self Signed Certificates Check this if you want the user to be able to use Self Signed Certificates. These are Certificates created by the user and can be anything they choose. Because of this, they cannot be validated and should only be accepted on a per need basis. An example would be if a form needs to go out of the organization and there is no guarantee or way to require authorized certificates, you can allow Self Signed Certificates so that the user can always be able to sign the document.
Accept Signatures From If the user is mapped, then the user must comply to this rule. If the user’s ServiceNow Record is used, their groups, and roles are matched to the following table:

ValueMatch By
AnyoneAny user in ServiceNow
User Specified on FormThe user must match the specified user field on the form. When selected, a required field will be presented that enables you to select the field with the User Record. If that User field is blank or doesn’t match to the user mapped by the certificate, then the match is false.
Group Specified on FormThe user must be a member of the specified group designated by a field on the form. When selected, a required field will be presented that enables you to select the field with the Group Record. If that Group field is blank or the user mapped by the certificate is not a member of the group, then the match is false.
Specific UsersWhen selected, a field will be presented enabling you to select one or more users. The user mapped by the certificate must be one of these users to have the match be true.
Specific GroupsWhen selected, a field will be presented, enabling you to select one or more groups. The user mapped by the certificate must be a member of one of these groups to have the match be true.
Specific RolesWhen selected, a field will be presented enabling you to select one or more roles. The user mapped by the certificate must have of one of these roles to have the match be true.
Allow Invalid Certificates If the Validate Certificate fails, checking this option will still allow the signature.
Determine User Default is Use Information on Certificate. This checks the certificate for an email address. If one is found, then it’s used to look up the user. If no email is found, then the user is looked up using their first name, last name, and middle name. If the certificate does not contain a middle name, then only the first and last names are used.

The other option is Script and additional searching can be done by JavaScript.
User Validation Script* Only visible when Determine User is Script.

This script should set the variable answer to the GlideRecord of the determined user. If no user can be determined, then answer should be set to undefined and the variable reason should contain the reason the user cannot be determined. This information will appear in the PDF Signature Widget.

The following variables are provided to the script to assist in determining the user:

VariableDescription
userIf the normal method of finding a user worked, then this will be the user record for that user
signatureThis is a JavaScript object containing the following information:

See section Signature Data for details.
Reject if no User Mapped If checked, then a user must be mapped and must meet Accept Signatures From criteria.
Validate Certificate This can be either Managed Certificates or Script.

Managed Certificates is the default certificate management provided by UXstorm PDF. When selected, the Issuer Certificate Chain is validated by looking for the Certificates in UXstorm PDF Forms -> Certificates -> All Certificates, this is the x_uxs_pdf_certificate table. If any of the certificates are not found or they are found but not validated, then the certificate is invalid. Note, if the certificate is not in the table, then it will be added so that it may be validated without having to key in all the data.

Script will show the Signature Validation Script.
Signature Validation Script* Only visible when Validate Certificate is Script.

Validate the Certificate/Signature and set variable answer = true if the certificate/signature is valid. Otherwise set answer = false and variable reason to the reason it is invalid.

To assist, the following variables are available to the script:
>
>
VariableDescription
userIf the normal method of finding a user worked, then this will be the user record for that user
signatureThis is a JavaScript object containing the following information:

See section Signature Data for details.
validatedCAThis is set to true if the normal Manage Certificate routine passes. This means that the Issuer Chain was found and validated in the UXstorm Certificates. This can be used to accept any certificates that are managed and do something else if they are not.

This is the script that you will need to change if you want to validate the certificate against another Certificate of Authority and/or handle Certificate Revocation Lists.

Signature Data

To assist in Determine User Script and Signature Validation Script, the signature data is passed to the script through the variable signature. This is a complex object and should only be used if you know the aspects of digital signatures. Here is an example of this object for a signature:

{
      "revisionNumber": 1,
      "signatureCoversWholeDocument": false,
      "signaturePosition": {
        "x": 232.871,
        "y": 432.778,
        "width": 192.393,
        "height": 22.17398
      },
      "digestAlgorithm": "SHA256",
      "encryptionAlgorithm": "RSA",
      "filterSubtype": "/adbe.pkcs7.detached",
      "signerName": "FIRST.MIDDLE.LAST.0001111117",
      "alternativeSignerName": "FIRST.MIDDLE.LAST.0001111117",
      "signDate": "2018-09-18 13:48:19",
      "selfSigned": false,
      "isVerificationGood": true,
      "isCertification": false,
      "isFieldsFillAllowed": true,
      "isAddingAnnotationsAllowed": true,
      "fieldsLocks": [],
      "certificateInfos": [
        {
          "validFrom": "2017-08-28 20:00:00",
          "validTo": "2020-08-28 19:59:59",
          "PEM": "...",
          "issuerString": "C=US,O=U.S. Government,OU=DoD,OU=PKI,CN=DOD ID CA-44",
          "subjectString": "C=US,O=U.S. Government,OU=DoD,OU=PKI,OU=USN,CN=FIRST.MIDDLE.LAST.0001111117",
          "selfSigned": false
        },
        {
          "validFrom": "2015-11-09 11:18:14",
          "validTo": "2021-11-09 11:18:14",
          "PEM": "...",
          "issuerString": "C=US,O=U.S. Government,OU=DoD,OU=PKI,CN=DoD Root CA 3",
          "subjectString": "C=US,O=U.S. Government,OU=DoD,OU=PKI,CN=DOD ID CA-44",
          "selfSigned": false
        },
        {
          "validFrom": "2012-03-20 14:46:41",
          "validTo": "2029-12-30 13:46:41",
          "PEM": "...",
          "issuerString": "C=US,O=U.S. Government,OU=DoD,OU=PKI,CN=DoD Root CA 3",
          "subjectString": "C=US,O=U.S. Government,OU=DoD,OU=PKI,CN=DoD Root CA 3",
          "selfSigned": true
        }
      ],
      "signatureName": "usersign",
      "subject": "C=US,O=U.S. Government,OU=DoD,OU=PKI,OU=USN,CN=FIRST.MIDDLE.LAST.0001111117",
      "issuer": "C=US,O=U.S. Government,OU=DoD,OU=PKI,CN=DOD ID CA-44",
      "CRLValidOnSign": false,
      "CRLValidToday": false
    }

Reverting to previous Steps

Most of the time, the signature process will be linear and one step succeeds the next. However, there may be a time in which you will want to “send” back the form to be filled out differently and resigned. To accommodate this need, two methods have been provided to revert to a previous step.

NOTE: Reverting to a pervious stage will discard all form and signature changes that occurred on or after the reverted stage.

Both methods are part of the x_uxs_pdf.PDFSignatureWorkflow Script Include.

revertToStage

revertToStage will revert the Signature Workflow process on a record for a specific UXstorm PDF Form. The method takes three parameters:

revertToStage(current, form, order)
current A GlideRecord for the “current” record that derives the PDF Form
form The sys_id of the UXstorm PDF Form to revert the Signature Workflow
Order This is a number of the Stage order to revert to. This should correspond to the Workflow Definition to revert to

Example use in a UI Action

var wf = new x_uxs_pdf.PDFSignatureWorkflow();

wf.revertToStage(current, 'cc2fea872fe590100824fe1df699b630', 100);
action.setRedirectURL(current);
revertToFirstStep

revertToFirstStep will revert the Signature Workflow process on a record for a specific UXstorm PDF Form to the first step in the Signature Workflow Process.. The method takes two parameters:

revertToFirstStep(current, form)
current A GlideRecord for the “current” record that derives the PDF Form
form The sys_id of the UXstorm PDF Form to revert the Signature Workflow

Example use in a UI Action

var wf = new x_uxs_pdf.PDFSignatureWorkflow();

wf.revertToFirstStep(current, 'cc2fea872fe590100824fe1df699b630');
action.setRedirectURL(current);

Setting up the Adobe PDF Form

To use the Signature Workflow Process, requires that there are Signature Fields on the PDF Form. If there are areas to “Sign” the PDF but are not Signature Fields, you must use Adobe DC or equivalent to add the Signature Fields.

Here is an example of a PDF in Adobe DC with a Signature Field:

Adobe Signature Field

A new Signature field can be added by clicking on the Add New Signature Field Button and placing the field on the form.

You can modify the Signature Field by double clicking on the field or right click and select properties. This is where the ToolTip, name, etc. can be modified/entered. One adjustment you may want to do as part of your process is “lock” fields after a Signature is added by the user. For instance, in the above example, all the fields before the Signature of User should be locked after the User signs the document so they cannot be changed. To do this go to Signed tab in the Signature Field Properties.

Adobe Signature Field Read-Only Properties

Choose Mark as read-only to one of the choices and the appropriate fields per the choice. This action will take place when the user signs the document in Adobe. Note that if you want the User to sign and date the form, then either instruct them to date first or do not lock the date field after the signing.

Events

There are numerous Events sent during the Signature Workflow Process to enable inter-process communications between the Signature Workflow Process and normal ServiceNow forms processes. Here is a table of all the Events sent to the ServiceNow event queue:

Events (all are prefixed with x_uxs_pdf) GlideRecord Param1 Param2
created PDF is created and attached to a record Current Name
created_on_revision PDF is created and attached to a Revision record Revision Name
PDFWorkflow_created The workflow is started Current UXstorm PDF Form sys_id
PDFWorkflow_completed The workflow has successfully reached the end of its workflow Current Form Name
pdfWorkflow.revision_received A PDF Revision was received on the workflow Revision
PDFWorkflow_revision_rejected A PDF Revision was rejected on the workflow Revision
PDFWorkflow_revision_processed A PDF Revision was processed on the workflow Revision
PDFWorkflow_revision_reset The PDF Workflow was reset Current Form Name
PDFWorkflow_revision_received A revision was received and is being processed. Not all PDF Submits will be received. If the submit is from the wrong revision or there is a revision already being processed, then the submit is rejected and this event will not fire. Revision
PDFWorkflow_signature_received A signature was receded and processed on a Revision Signature Instance
PDFWorkflow_signature_rejected A signature was receded and rejected on a Revision Signature Instance
PDFWorkflow_step_started A step in the PDF Workflow has started Workflow Instance
PDFWorkflow_step_completed A step in the PDF Workflow has completed Workflow Instance

Hooking into all Events

When every event is sent to the ServiceNow Event Queue, an additional routine in the global scope is called if it exists. To hook into this call, create a new Script Include in the Global scope (MUST be in Global). Use the following information to create the Script Include:

Name: PDFCustomerEvent

Application: Global

Accessible from: All application scopes

The basis for the script is as follows:

var PDFCustomerEvent = Class.create();
PDFCustomerEvent.prototype = {
    initialize: function() {
    },
    send: function(name, table, sys_id, param1, param2) {
        // Add your code here    
    },
    type: 'PDFCustomerEvent'
};

If this Script Include is defined and the send() function is provided, it will be called every time an event is sent to the ServiceNow Event Queue in the UXstorm PDF Form application. You can then use the information provided to do what you need to do for automation without listening to an event.

ServiceNow Workflow Events

If you want to watch for events in a ServiceNow Workflow, then you will need to implement hooking into all events in the previous section and broadcast the event to the workflows from Global.

Here is an example of a PDFCustomerEvent Script Include that will broadcast the name of the event to any workflows running on the “current” record:

var PDFCustomerEvent = Class.create();
PDFCustomerEvent.prototype = {
    initialize: function() {},
    send: function(name, table, sys_id, param1, param2) {
        var current = new GlideRecord(table);
        current.get(sys_id);
        var wf = new Workflow().getRunningFlows(current);

        while (wf.next()) {
            new Workflow().broadcastEvent(wf.sys_id, name);
        }
    },
    type: 'PDFCustomerEvent'
};