Proving compliance requires keeping a record of all the evidence you may need. Therefore, Nuxeo Server allows you to define in the most flexible way what should constitute a record.
By default, Nuxeo Server will always protect the main file of the document when putting a document under retention and the document remains editable. Should you wish to put under retention additional files from the document and prevent certain properties from being edited, you need to configure a list of properties to be protected.
In this tutorial, you will learn how to leverage this configuration to retain multiple document properties securely, including how to retain additional files in WORM storage. This helps proving that no metadata has been tampered with in case of an audit. If you wish to go further, a high level understanding of how to store additional elements like comments will also be provided.
Prerequisites
This feature is available starting from:
- Nuxeo Server
LTS 2021 HF33
- Nuxeo Retention
2021.4.5
This how-to requires:
- Being familiar with the base concepts of Nuxeo and Nuxeo Studio.
- Knowing how to use Nuxeo Web UI for standard actions like navigating and creating a document.
Define Properties to Retain
Properties to retain are defined through Nuxeo Studio configuration.
First, we need to declare the dependency on the addon.
In Nuxeo Studio Modeler:
- Go to the
Application Definition
screen, and addNuxeo Retention
to the list of packages to install. - Save your configuration
Now, let's configure a custom document type containing additional properties we want to retain.
In Nuxeo Studio Modeler:
- Go to
Content Model > Document Types
- Create a new document type
- Name it
MyClaim
- Make it extend
File
- Name it
- In the
Schema
tab, add the following custom properties:amountRefunded
: floating pointexpertReport
: blobincidentDate
: dateincidentDescription
: stringrepairQuotes
: blob (multi-valued)
We need to display these properties during creation, edit and view.
- Go to Nuxeo Studio Designer
- Go to
Layouts > Local Document Types > MyClaim
and click on theConfigure Missing Layouts
button. - In the different layouts, drag and drop the
myclaim
schema to add the missing properties to the form and save your configuration.
Next step is to configure which of these properties we want to retain.
In Nuxeo Studio Modeler:
- Go to
Advanced Settings > XML Extensions
- Create a new XML extension and give it a name, e.g.
retainMyClaimProperties
- Paste the following code
<require>org.nuxeo.ecm.core.CoreExtensions</require>
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
<!-- Setting properties like text, date, numbers as retainable will protect them from being edited once the document goes under retention. -->
<property schema="myclaim" name="amountRefunded" retainable="true" />
<property schema="myclaim" name="incidentDate" retainable="true" />
<!-- Files held in blob properties set as retainable will be sent to the dedicated bucket for records if it exists. If this bucket uses WORM storage, these files will be stored in WORM storage as well. -->
<property schema="myclaim" name="expertReport" retainable="true" />
<property schema="myclaim" name="repairQuotes" retainable="true" />
<!-- You can also use configuration to retain only specific parts of complex or multivalued complex properties. Here, we retain all the files held in the files schema (i.e., the attachments from a default File document) but do not protect the other parts of this complex multivalued property. -->
<property schema="files" name="files/*/file" retainable="true" />
<!-- Note that we do not retain the incident description, so this property can still be edited after the document is put under retention. -->
</extension>
- Save your configuration and deploy it
That's it! Let's take a look at the result and explain what we did.
Checking the Result
In Nuxeo Server:
- Create a retention rule with immediate retention and a duration of 1 day
- Create a document of type
MyClaim
inside a workspace and fill in its properties - Put the document under retention
Your document is now under retention, and the additional properties you configured are protected too. In our example:
- Trying to edit properties like the amount refunded will fail while the document is under retention.
- Editing properties like the document title will be allowed because they are not explicitly protected in our configuration.
How are Properties Protected?
Text, dates, numbers properties defined as retainable are protected by our low level APIs. Someone with direct access to the database could still edit them. Consider this when planning for compliance. Further security can be added for them by exporting their value inside a file at the time the document is declared a record and storing this file in WORM storage, as explained in the "Going Further" section below.
Files are protected by our low level APIs too. If you leverage WORM storage, the files configured as retainable will also be sent to WORM storage, providing an additional protection layer.
Going Further: Retain Comments in WORM storage when Declaring a Record
In some cases, you may wish to store additional information securely while declaring a record. Comments or annotations could be important evidence to keep in case of an audit. Let's see how we could store this information in WORM storage to prove that it has not been tampered with.
Prerequisites
This section requires:
- Being familiar with Java development, and developing on top of Nuxeo.
- The Nuxeo Retention addon must be configured to support WORM storage.
High Level Principles
The high level principles are the following:
- Create a property of type
blob
to store additional information. - Configure this property to be retainable when the document becomes a record.
- Create a custom operation to export the values of the properties, the comments of the documents, or anything else into a file.
- Create an event handler that will be triggered when the document is about to become a record and integrate your logic.
- Populate your new property with the file we generated.
The file will then be stored in WORM storage along with others, allowing you to prove that the information held cannot have been tampered with.
dc:title
property as retainable to prevent it from being edited.
Create a Property to Store Exported Information
First step is to create a new property to store the information we will export.
In Nuxeo Studio Modeler:
- Go to
Content Model > Document Types > MyClaim
- In the
Schema
tab, add the following custom properties:recordStorage
: blob
Make this Property Retainable
Update the retainMyProperties
XML extension to retain the new property. Code should look like this:
<extension target="org.nuxeo.ecm.core.schema.TypeService" point="schema">
[...]
<!-- Retain an additional property for information we want to export and store in WORM storage -->
<property schema="myclaim" name="recordStorage" retainable="true" />
[...]
</extension>
Create a Custom Operation to Export Your Information
At this stage, you need to create a custom operation and reference it in Nuxeo Studio. This operation should take a document as input, export the information you require (like document metadata or comments) and return it as a blob.
We are not providing a specific example here as you will need to create one adapted to your needs.
Integrate the Export and Storage Logic
Once the operation is ready, we need to integrate it in our logic.
In Nuxeo Studio Modeler:
- Go to
Registries > Core Events
- Add the following code to reference the event we need:
{
"events": {
"beforeMakeRecord": "Before Declaring a Record"
}
}
- Save your configuration
- Go to
Automation > Automation Chains
- Create a new chain called
exportRecordInfoChain
- Define your logic as follows, replacing the
Document.GetBlobs
operation with your own custom operation:
- Context.FetchDocument
- Context.SetInputAsVar:
name: recordDocument
- Document.GetBlobs
- Blob.CreateZip:
filename: recordInformation.zip
- Blob.AttachOnDocument:
document: recordDocument
save: "true"
xpath: "myclaim:recordStorage"
- Save your configuration
Switch editor
button and saving this configuration to go faster.
Create a Trigger for Your Logic
We now need to trigger the logic we created when a record is about to be declared.
In Nuxeo Studio Modeler:
- Go to
Automation > Event Handlers
- Create a new event handler and name it
exportRecordInfoHandler
- Associate it to:
- The
Before Declaring a Record
event - On the
MyClaim
document type - The
exportRecordInfoChain
automation chain
- The
- Save your configuration
We're all set! Let's check the result.
Checking the Result
In Nuxeo Server:
- Create a retention rule with immediate retention and a duration of 1 day.
- Create a document of type
MyClaim
inside a workspace and fill in its properties. - Put the document under retention.
Compared to our previous example, you should be able to export the document as JSON or XML and notice that our new property claim:recordStorage
is now populated with the exported information.
What happens exactly?
- When the document is about to be declared as a record, our event handler is triggered.
- This launches our export logic that populates the
myclaim:recordStorage
property with the information we want. - Since our
myclaim:recordStorage
property is of typeblob
and configured asretainable
, it is sent into secure storage as otherretainable
files.
As a result, this additional information is now stored in WORM storage and can be used as a proof in case of an audit.