GRC Rest Api
GRC Rest Api
These examples have not been thoroughly tested under all conditions. IBM,
therefore, cannot guarantee or imply reliability, serviceability, or function of
these programs. You may copy, modify, and distribute these sample programs
in any form without payment to IBM for the purposes of developing, using,
marketing, or distributing application programs conforming to IBM's
application programming interfaces.
Trademark Information
IBM, the IBM logo and ibm.com are trademarks or registered trademarks of
International Business Machines Corp., registered in many jurisdictions
worldwide.
The following terms are trademarks or registered trademarks of other
companies:
• Adobe, the Adobe logo, PostScript, and the PostScript logo are either
registered trademarks or trademarks of Adobe Systems Incorporated in
the United States, and/or other countries.
• Microsoft, Windows, Windows NT, and the Windows logo are trademarks of
Microsoft Corporation in the United States, other countries, or both.
• The registered trademark Linux is used pursuant to a sublicense from the
Linux Foundation, the exclusive licensee of Linus Torvalds, owner of the
mark on a worldwide basis.
• UNIX is a registered trademark of The Open Group in the United States
and other countries.
• Java and all Java-based trademarks and logos are trademarks or
registered trademarks of Oracle and/or its affiliates.
Other product and service names might be trademarks of IBM or other
companies. A current list of IBM trademarks is available on the Web at
"Copyright and trademark information" at www.ibm.com/legal/copytrade.shtml.
2
Disclaimer
Although every precaution has been taken in the preparation of this document,
IBM assumes no responsibility for errors or omissions. No liability is assumed
for damages resulting from the use of the information contained herein.
3
Contents
Contents ............................................................................................................................. 4
Introduction ........................................................................................................................ 6
Audience ......................................................................................................................... 6
Finding information .......................................................................................................... 6
RESTful systems .............................................................................................................. 6
Addressability .............................................................................................................. 6
Statelessness ............................................................................................................... 7
Addressable space / URI design..................................................................................... 7
Filter capability ................................................................................................................ 8
Service document............................................................................................................. 9
Headers .......................................................................................................................... 9
Paths and parameters .......................................................................................................... 9
/types ........................................................................................................................... 11
/contents ....................................................................................................................... 15
Uploading a document .................................................................................................... 23
Working with existing document data .............................................................................. 23
/folders ......................................................................................................................... 29
Deleted resources .......................................................................................................... 33
/query ........................................................................................................................... 33
/configuration ................................................................................................................ 37
/adminMode .............................................................................................................. 37
/currencies ................................................................................................................ 38
/reportingPeriods ....................................................................................................... 39
/text ......................................................................................................................... 40
/profiles..................................................................................................................... 41
/security ........................................................................................................................ 47
/groups ..................................................................................................................... 47
/permissions .............................................................................................................. 51
/roles ........................................................................................................................ 52
/users ....................................................................................................................... 53
/search.......................................................................................................................... 56
Range headers ........................................................................................................... 58
/processes ..................................................................................................................... 59
/rules ............................................................................................................................ 62
4
Return codes and errors ..................................................................................................... 64
Error responses .............................................................................................................. 67
Security............................................................................................................................. 68
Basic authentication ....................................................................................................... 68
Client certificate authentication ....................................................................................... 68
Prerequisites .............................................................................................................. 68
Setup steps ............................................................................................................... 69
Testing client certificate authentication ........................................................................ 70
Regular expressions ................................................................................................... 71
Token authentication ...................................................................................................... 71
Client-server interactions .................................................................................................... 73
REST samples .................................................................................................................... 74
AnonLossEventFormREST ............................................................................................... 74
TivoliDirectoryIntegratorConnector .................................................................................. 74
Performance tips ................................................................................................................ 75
Known limitations ............................................................................................................... 75
Extend GRC API with custom REST services ......................................................................... 76
Assumptions .................................................................................................................. 76
Extension framework ...................................................................................................... 76
Developing extensions .................................................................................................... 77
Dependencies ............................................................................................................ 77
Implementing a simple extension framework RestController ........................................... 78
Implementing RestControllers with JSON methods ........................................................ 79
Implementing RestControllers with error handling ......................................................... 81
Deploying RestControllers to the extension framework .................................................. 82
Testing deployed RestControllers ................................................................................. 82
Administering extension framework ............................................................................. 82
5
Introduction
The IBM OpenPages® GRC REST API provides access to IBM OpenPages® data and metadata.
This data-centric API is specified in terms of resources, their URIs, and actions that can be
performed on these URIs. This document describes typical interactions and ways to publish the
API in conformance with the Content Management Interoperability Services (CMIS) specification.
Audience
To use the OpenPages GRC REST API guide effectively, you should be familiar with the following:
• OpenPages
• Web services such as ASDL and REST
• HTML and the JavaScript scripting language (JSON)
• Programming languages and integrated development environments (IDEs), such as the
Java™ programming language and the Eclipse IDE, or the C# programming language
and the Microsoft Visual Studio IDE.
Finding information
To find IBM OpenPages product documentation on the web, including all translated
documentation, go to IBM Documentation. Release Notes are published directly to the site and
include links to the latest technotes and APARs.
RESTful systems
There is abundant literature on REST technology, its core principles, and what makes a system
RESTful. Additional reference information is provided at the end of this document. This section
provides basic information on RESTful systems.
A resource consists of any application data (or operation data) or metadata that makes up a
system and is exposed to the Web as a URI. The URI is the name and address of a resource. If
the information doesn’t have a URI, it’s not a Web resource. The API of a RESTful system is
articulated around resources and their URI.
The IBM OpenPages GRC REST API implements a RESTful style server that supports interaction
with the client over the HTTP standard protocol. The client-server interaction takes place when
the client makes an HTTP request to a URL and provides additional parameters or data in the
request’s header fields and body. The REST API which will handle and process the request and
return an appropriate HTTP response which contains a Status-Code indicating successful
operation or failure and optionally some data to be returned to the client in the response body.
Addressability
Addressability is the idea that every object and resource in your system is reachable through a
unique identifier. In a RESTful system, addressability is managed through the use of URIs. An
application is addressable if it exposes relevant aspects of its dataset as resources. Since
resources are exposed through URIs, an addressable application exposes a URI for every piece of
information it may serve, including application domain concepts, server operation states, or
services.
6
Statelessness
Another feature of RESTful systems is statelessness, where HTTP requests occur in complete
isolation. When the client makes an HTTP request, it includes all the information necessary for
the server to fulfill that request. The server never relies on information from previous requests. If
that information is important, the client must include it in the request. Statelessness does not
mean that the server cannot have state (in fact a server's state should be maintained as
resources), rather it means that there is no client state maintained on the server. The client is
responsible for maintaining state information relative to its interaction and the server provides
state transition information, when required. This principle helps achieve the scalability expected
from Web applications.
The URL character set is limited to US-ASCII, which includes a number of reserved characters.
URL designers have incorporated escape sequences to allow the encoding of arbitrary character
values or data using a restricted subset of the US-ASCII character set. The encoding simply
represents unsupported characters by an escape notation consisting of a percent sign (%)
followed by two hexadecimal characters that represent the ASCII code equivalent. For instance, if
the requested resource has an identifier that contains one of the reserved characters, it must be
URL encoded to escape them.
This section describes the addressable space of an OpenPages application in terms of its URI
paths and parameters.
7
• OpenPages (traditional on premises) and OpenPages on Cloud:
The root of an OpenPages application as deployed on an application server is
configurable. By default, /grc/api is used as the root of every path. The specification
of the URI address and the naming of path segments is not arbitrary.
Examples of URI paths for OpenPages GRC REST API using the external Cloud Pak for
Data URL:
https://<cloudpak_url>/openpages- openpagesinstance1-grc/api
https://<cloudpak_url>/openpages- openpagesinstance1-grc/api/types
When you call the OpenPages REST API from inside the cluster you might need to access
OpenPages by using its internal service name and port, instead of the external URL. Use
the internal URL, for example, if your environment has network restrictions that prevent
the use of the external URL.
Example URI paths for the OpenPages GRC REST API using the internal URL for
OpenPages:
https://openpages-openpagesinstance1-svc:10111/openpages-openpagesinstance1-
grc/api
https://openpages-openpagesinstance1-svc:10111/openpages-openpagesinstance1-
grc/api/types
Filter capability
The OpenPages GRC REST API supports retrieving resources using simple filters specified as
properties to retrieve, date and time ranges or whether parent-child relationships should be
included in the response. Refer to the individual paths described in the Paths and Parameters
section for supported filters.
8
Service document
Deprecated since 8.3.0.1
A WADL Service document, which describes all the possible paths supported for the OpenPages
GRC REST API is provided from the URL http://<SERVER_NAME>:<PORT>/grc/api/?_wadl.
Notice this WADL was previously available via GET or OPTIONS requests to the root URL path
/grc/api.
Headers
The OpenPages GRC REST API supports standard HTTP header fields in the request for certain
methods.
9
API Path Segment HTTP Method
GET PUT POST DELETE
/grc/api/contents/{contentId}/action/removeAllLocks X
/grc/api/contents/{contentId}/associations X X X
/grc/api/contents/{contentId}/associations/parents X X X
/grc/api/contents/{contentId}/associations/parents/{parentId} X
/grc/api/contents/{contentId}/associations/children X X X
/grc/api/contents/{contentId}/associations/children/{childId} X
/grc/api/contents/{contentId}/auditlogs/associations X
/grc/api/contents/{contentId}/auditlogs/fields X
/grc/api/contents/{contentId}/permissions/cancreate/{childtype} X
/grc/api/contents/{contentId}/permissions/effective X
/grc/api/contents/{contentId}/permissions/allowedtocreatetypes X
/grc/api/contents/{contentId}/report/{fieldName} X
/grc/api/folders X X
/grc/api/folders/{folderId} X X X
/grc/api/folders/{folderId}/containees X
/grc/api/folders/template X
/grc/api/folders/{folderId}/permissions/effective X
/grc/api/configuration/adminMode X X
/grc/api/configuration/currrencies X
/grc/api/configuration/currencies/base X
/grc/api/configuration/currencies/{code} X X
/grc/api/configuration/currencies/{code}/exchangeRates X X
/grc/api/configuration/currencies/exchangeRates X
/grc/api/configuration/reportingPeriods X
/grc/api/configuration/reportingPeriods/{reportingPeriods} X
/grc/api/configuration/reportingPeriods/current X
/grc/api/configuration/text/{textKey} X
/grc/api/configuration/settings/{settingPath} X
/grc/api/configuration/profiles X
/grc/api/configuration/profiles/{profile} X
/grc/api/configuration/profiles/{profile}/definition X
/grc/api/configuration/profiles/fields X
/grc/api/security/groups X X
/grc/api/security/groups/{groupId} X
/grc/api/security/groups/{groupId}/subgroups X X X
/grc/api/security/groups/{groupId}/users X X X
/grc/api/security/groups/{groupId}/permissions X
/grc/api/security/groups/{groupId}/roles X X X
/grc/api/security/users X
/grc/api/security/users/{userId} X X
/grc/api/security/users/{userId}/groups X
/grc/api/security/users/{userId}/permissions X
/grc/api/security/users/{userId}/roles X X X
/grc/api/security/users/{userId}/password X
/grc/api/security/users/{userId}/action/anonymize X
/grc/api/security/permissions X
/grc/api/security/permissions/{permissionId} X
/grc/api/security/roles X
/grc/api/security/roles/{roleId} X
10
API Path Segment HTTP Method
GET PUT POST DELETE
/grc/api/security/roles/{rolesId}/access X
/grc/api/security/roles/{roleId}/permissions X
/grc/api/query/ X X
/grc/api/search X X
/grc/api/processes X
/grc/api/processes/{processId} X X
/grc/api/processes/{processId}/logs X
/grc/api/processes/types X
/grc/api/processes/latest/{processTypeId} X
/types
Used to interact with OpenPages metadata. Object Types are the resources provided by /types
path and are identified by either name or Id.
• /grc/api/types: a GET operation with this path retrieves a list of Object Types for a
deployment and their URIs. An individual type could be considered a valid resource
accessible through a URI. Use optional parameter includeFieldDefinitions (value is true or
false) to specify whether or not field definitions should be included in the resource for a
type definition. Returns an array of types.
[
{
"name": "SOXDocument",
"localizedLabel": "File",
"localizedPluralLabel": "Files",
"description": "OpenPages GRC Object Type",
"id": "42",
"rootFolderPath": "/_op_sox_documents/Files and Forms",
"rootFolderId": "66"
},
{
"name": "SOXExternalDocument",
"localizedLabel": "Link",
"localizedPluralLabel": "Links",
"description": "OpenPages GRC Object Type",
"jspPath": "/propertyForm/renderProperties.jsp",
"id": "46",
"rootFolderPath": "/_op_sox_documents/Files and Forms",
"rootFolderId": "66"
},
{
"name": "SOXIssue",
"localizedLabel": "Issue",
"localizedPluralLabel": "Issues",
"description": "OpenPages GRC Object Type",
"jspPath": "/propertyForm/renderProperties.jsp",
"id": "44",
11
"rootFolderPath": "/_op_sox/Project/Default/Issue",
"rootFolderId": "28"
}
]
Returns:
[
{
"name": "SOXDocument",
"localizedLabel": "File",
"localizedLabels":
{
"localizedLabel":
[
{
"localeISOCode": "en_US",
"localizedLabel": "File"
},
{
"localeISOCode": "es_ES",
"localizedLabel": "archivo"
},
{
"localeISOCode": "it_IT",
"localizedLabel": "File"
}
]
},
"localizedPluralLabel": "Files",
"localizedPluralLabels":
{
"localizedPluralLabel":
[
{
"localeISOCode": "en_US",
"localizedLabel": "Files"
},
{
"localeISOCode": "es_ES",
"localizedLabel": "Archivos"
},
{
"localeISOCode": "it_IT",
"localizedLabel": "File"
12
}
]
},
"description": "OpenPages GRC Object Type",
"id": "42",
"rootFolderPath": "/_op_sox_documents/Files and Forms",
"rootFolderId": "66"
},
]
• /grc/api/types/{id}: this URI refers to a specific Object Type uniquely identified by id.
A GET with this URI returns a representation of the Object Type including fields.
{
"name": "SOXTask",
"localizedLabel": "Action Item",
"localizedPluralLabel": "Action Items",
"description": "OpenPages GRC Object Type",
"jspPath": "/propertyForm/renderProperties.jsp",
"id": "7",
"rootFolderPath": "/_op_sox/Project/Default/IssueActionItems",
"rootFolderId": "18",
"fieldDefinitions":
{
"fieldDefinition":
[
{
"id": "28",
"name": "Resource ID",
"localizedLabel": "Resource ID",
"dataType": "ID_TYPE",
"required": true,
"description": "Resource ID",
"computed": false,
"readOnly": true,
"dependencies":
{
"dependency":
[
]
},
"enumValues":
{
"enumValue":
[
]
}
},
{
"id": "59",
"name": "Created By",
"localizedLabel": "Created By",
"dataType": "INTEGER_TYPE",
"required": true,
13
"description": "The name of the user who created this object. It is set by the
application and cannot be edited.",
"computed": false,
"readOnly": true,
"dependencies":
{
"dependency":
[
]
},
"enumValues":
{
"enumValue":
[
]
}
}
]
[
{
"id": "6",
"name": "SOXIssue",
"localizedLabel": "Issue",
"associationDefinitionId": "9",
"max": 2147483647,
"min": 1,
"enabled": true,
"relationship": "Parent"
},
{
"id": "4",
"name": "SOXDocument",
"localizedLabel": "File",
"associationDefinitionId": "13",
"max": 2147483647,
"min": 0,
"enabled": true,
"relationship": "Child"
},
{
"id": "8",
"name": "SOXExternalDocument",
"localizedLabel": "Link",
14
"associationDefinitionId": "14",
"max": 2147483647,
"min": 0,
"enabled": true,
"relationship": "Child"
},
]
/contents
Used to interact with OpenPages instance data such as GRC Objects. The GRC Objects can be
referenced by their Id, or path. The path may be either relative or full path. The path must be
URL encoded as it may contain ‘/’ reserved character.
• /grc/api/contents/: A POST to this URL containing the entry representing the object
to be created will create the GRC Object. The entry can be constructed from the
template returned from /grc/api/contents/template for the type of object being created.
Example: Creating Action Item POST this body to /grc/api/contents with header Content-
Type: application/json
{
"fields":
{
},
"typeDefinitionId": "45",
"primaryParentId": "3954",
"name": "testActionItem01",
"description": "Action Item description"
}
The POST request body attributes will specify identifiers that determine how the Content
resource is created in the OpenPages application.
• typeDefinitionId could be either the Action Item Object Type's Id: 45 or it's system
name SOXTask. Note that Object Type label, “Action Item” is not supported.
• primaryParentId could be either another GRC Object Type's Id: 3954 or it's full path:
/op_sox/Project/Default/Issue/Parent-Issue.txt
• For every field in the fields the field must be identified uniquely by either the field's id
attribute or "id": "456" or name attribute "name": "OPSS-Iss:Status". See
“Updating a GRC Object” on page 17 for more details.
Example: For referencing an instance of an Issue using different options for the “contentId”
Id: 3954
Relative Path: Issue/Test 01/Issue 1
Full Path: /_op_sox/Project/Default/Issue/Test 01/Issue 1.txt
15
• /grc/api/contents/{id}: A GET operation on such a path would return a representation
of the OpenPages resource. Given the restrictions on the characters within a URI, the path
must be URL-encoded.
Example:
{
"name": "Issue 1",
"id": "3954",
"path": "/_op_sox/Project/Default/Issue/Test 01/Issue 1.txt",
"description": "This is an example of free text.",
"parentFolderId": "1969",
"fields":
{
"field":
[
{
"id": "28",
"dataType": "ID_TYPE",
"name": "Resource ID",
"value": "3954"
},
{
"id": "295",
"dataType": "ENUM_TYPE",
"name": "OPSS-Issue:Conclusion",
"enumValue":
{
"id": "380",
"name": "Deficiency",
"localizedLabel": "Deficiency",
"index": 1
}
},
{
"id": "288",
"dataType": "MULTI_VALUE_ENUM",
"name": "OPSS-Issue:Domain",
"multiEnumValue":
{
"enumValue":
[
{
"id": "354",
"name": "Operational",
"localizedLabel": "Operational",
"index": 2
},
{
"id": "355",
"name": "Technology",
"localizedLabel": "Technology",
"index": 3
16
}
]
}
},
{
"id": "284",
"dataType": "DATE_TYPE",
"name": "OPSS-Issue:Due Date",
"value":
{
}
},
{
"id": "291",
"dataType": "STRING_TYPE",
"name": "OPSS-Issue:Identified By Individual",
"value": "OpenPagesAdministrator"
},
]
},
"typeDefinitionId": "44",
"primaryParentId": "3049"
}
If the GRC Object referenced by the Id is a SOXDocument type, there will be additional
information about the file attachment.
"fileTypeDefinition":
{
"fileExtension": "xls",
"mimeType": "application/vnd.ms-excel",
"id": "46"
},
"contentDefinition":
{
"attribute":
{
"type": "application/vnd.ms-excel",
"src": "http://localost/grc/api/contents/131/document/DefaultTemplate.xls"
}
}
17
"fields":{
"field":[
{
"name":"objFieldString",
"dataType":"STRING_TYPE",
"value":"{STRING_VALUE}"
},
{
"name":"objFieldInteger",
"dataType":"INTEGER_TYPE",
"value":"{INTEGER_VALUE}"
},
{
"name":"objFieldDecimal",
"dataType":"FLOAT_TYPE",
"value":"{FLOAT_VALUE}"
},
{
"name":"objFieldBoolean",
"dataType":"BOOLEAN_TYPE",
"value":"{TRUE_OR_FALSE}"
},
{
"name":"objFieldDate",
"dataType":"DATE_TYPE",
"value":"{DATE_VALUE}"
},
{
"name":"objFieldCurrency",
"dataType":"CURRENCY_TYPE",
"baseAmount":"{NUMERIC_BASE_AMOUNT}",
"localAmount":"{NUMERIC_LOCAL_AMOUNT}",
"exchangeRate":"{NUMERIC_EXCHANGE_RATE}",
"baseCurrency":{
"isoCode":"{BASE_ISO}"
},
"localCurrency":{
"isoCode":"{LOCAL_ISO}"
}
},
{
"name":"objFieldEnum",
"dataType":"ENUM_TYPE",
"enumValue":{
"name":"{ENUM_VALUE}",
"localizedLabel":"{ENUM_LABEL}",
"index":"{NUMERIC_ENUM_INDEX}"
}
},
{
"name":"objFieldMulValEnum",
"dataType":"MULTI_VALUE_ENUM",
"multiEnumValue":{
18
"enumValue":[
{
"name":"{ENUM_VALUE_1}"
},
{
"name":"{ENUM_VALUE_2}"
}
]
}
}
]
},
"typeDefinitionId":"5",
"primaryParentId":"20",
"name":"testObj5",
"description":"test object description"
}
When you update a GRC Object, you might also want to set fields with an empty value (blank).
For each data type, there can be a different approach to setting the field value to empty. See the
example request body for how to set each type of field to empty.
{
"fields":{
"field":[
{
"name":"objFieldString",
"dataType":"STRING_TYPE",
"value":null
},
{
"name":"objFieldInteger",
"dataType":"INTEGER_TYPE",
"value":null
},
{
"name":"objFieldDecimal",
"dataType":"FLOAT_TYPE",
"value":null
},
{
"name":"objFieldBoolean",
"dataType":"BOOLEAN_TYPE",
"value":null
},
{
"name":"objFieldDate",
"dataType":"DATE_TYPE",
"value":null
},
{
"name":"objFieldCurrency",
"dataType":"CURRENCY_TYPE",
19
"isAmountNull":true
},
{
"name":"objFieldEnum",
"dataType":"ENUM_TYPE",
"enumValue":{
}
},
{
"name":"objFieldMulValEnum",
"dataType":"MULTI_VALUE_ENUM",
"multiEnumValue":{
"enumValue":[
]
}
}
]
},
"typeDefinitionId":"5",
"primaryParentId":"20",
"name":"testObj5",
"description":"test object description"
}
{
id:[{id}],
options:{
includeChildren: true,
conflictBehavior: "CREATECOPYOF",
typeDefinitions:["SOXBusEntity"],
typeAssociations:[
{
parentObjectType: "SOXProcess",
childObjectType: "SOXBusEntity"
}
],
autoNameChildren:false
}
}
conflictBehavior specifies the desired behavior when a GRCObject with the same name
already exists in the target location of a copy.
20
There are 4 supported behaviors:
1. CREATECOPYOF: Performs the copy. This operation will prefix the name of the copy
in the target location with 'Copy of' for the first instance of a conflict, or 'Copy (n) of'
for the nth instance of a conflict.
2. OVERWRITE: Overwrites the GRCObject at the destination with the GRCObject from
the source.
3. USEEXISTING: Keeps the GRCObject at the destination and associates it to the
source objects being copied.
4. ERROR: Throws OpenPagesException if a conflict exists.
typeAssociations specifies the list of object type associations that need to be honored
during the copy operation. This class enables the copy operation to look up the non-primary
parent relationships from the descendants of source GRCObject and associate the parent to
corresponding copied GRCObject.
{
id:[ "7920"],
options:{
includeChildren : true,
conflictBehavior: "OVERWRITE",
typeDefinitions:["SOXBusEntity"]
}
}
21
• /grc/api/contents/{id}/action/lock: A PUT operation to this URL will lock the GRC
Object specified by the id.
Example: A PUT operation to the following URL will lock the GRC object with id =5220.
http://localhost/grc/api/contents/5220/action/lock
• /grc/api/contents/{id}/action/overwriteproperties?fields={fieldIds}&value={
newValue}: A PUT operation to this URL will overwrite specific text field values and also
overwrite references to those fields on the Activity tab of the GRC Object specified by the
id.
Example: A PUT operation to the following URL will overwrite fields ‘Description (56)’ and
‘Comments(62)’ with value ‘abc’ for the GRC object with id =5220.
http://localhost/grc/api/contents/5220/action/overwriteproperties?fields=56,62&value=abc
Limitations:
The data type of specific fields must one of:
STRING_TYPE
MEDIUM_STRING_TYPE
LARGE_STRING_TYPE
UNLIMITED_STRING_TYPE
The display type of specific fields in any profile must be one of:
Automatic
On Demand
On Demand Rich Text
Rich Text
Text
Text Area
For system fields, only the description field and the comment field are allowed.
Encrypted fields are not allowed.
Example: A DELETE operation to the following URL will purge the GRC object with id
=5220.
http://localhost/grc/api/contents/5220/action/purge
Permissions: The operation can only be performed by a super user.
Example: A PUT operation to the following URL will unlock the GRC object with id =5220.
http://localhost/grc/api/contents/5220/action/unlock
22
• /grc/api/contents/{id}/action/removeAllLock: A PUT operation to this URL will
remove all the locks from the GRC Object specified by the id as well as the hierarchy of
children below this GRC Object
Uploading a document
To create (POST) or update (PUT) a new Document object, you must specify the
contentDefinition, the attribute which has a type for file mime Type and a children attribute
whose value is the contents of the file attachment. For plain text files this would be plain String
value representing the contents of the text file being uploaded. For other file types, that are
binary. The binary data for the file must be encoded in Base64 and the resulting Base64 string
will be the value for the "children" attribute. When updating an existing Document you may use
a more efficient /grc/api/contents/{id}/document PUT method which does not require
encoding binary data to Base64.
• /grc/api/contents: A POST operation to this URL containing the entry representing the
object to be created will create a document.
{
"contentDefinition":
{
"attribute":
{
"type": "text/plain" },
"children": "Updated this document using json put upateDocumentContent API"
},
"fileTypeDefinition":
{
"id": "9",
"mimeType": "text/plain",
"fileExtension": "txt"
},
"fields":
{
},
"typeDefinitionId": "4",
"name": "MytestDoc1.txt",
"description": "TestDocument created using json"
}
23
• /grc/api/contents/{id}/document: A PUT operation containing the document’s
content to update the existing document. There is no encoding required, only the actual
document content should be sent in the request body. For example, when sending an
image file to update a document, you would read the binary data from the image file
locally, and then send the binary data as the request body.
o Header Content-Type is required and should match the content-type of the file
in OpenPages, e.g. for a PDF it should be application/pdf, see Note below for
special cases.
o Header Content-Length is required and should be the length of the provided
file attachment contents. Without sending this would receive a 400 BAD
REQUEST type response
o How your REST client software provides the binary file attachment data to the
request depends on your client. Please consult your client’s documentation for
the method that is supported.
Note: Use "application/xml" as the content type if the file's MIME type is "text/xml", and
use "application/xhtml+xml" as the content type if the file's MIME type is "text/html".
[
{
"id": "3049",
"typeDefinitionId": "43",
"path": "/_op_sox/Project/Default/BusinessEntity/Test 01/Test 01.txt",
"associationDefinitionId": "5",
"type": "PARENT"
},
{
"id": "4134",
"typeDefinitionId": "45",
"path": "/_op_sox/Project/Default/IssueActionItems/Test 01/Issue Action Item 1.txt",
"associationDefinitionId": "9",
"type": "CHILD"
},
{
"id": "32902",
"typeDefinitionId": "45",
"path": "/_op_sox/Project/Default/IssueActionItems/Test 01/testActionItem01.txt",
"associationDefinitionId": "9",
"type": "CHILD"
}
]
24
• /grc/api/contents/{id}/associations?children={id},{id}…;parents={id},{id}
…: A DELETE operation will remove parent and/or child associations for the given
resource. The list of parents or children Ids can be of any length. Separate parent and child
associations with a semi-colon.
Start date and end date are provided in the ISO8601 date format. “yyyMMdd'T'HHmmssZ"
Start date and end date are provided in the ISO8601 date format yyyyMMdd'T'HHmmssZ
Returns:
[
{
"name": "Name",
"id": "55",
"newValue": "testObject1updated.txt",
"oldValue": "testObject1.txt",
"modifiedBy": "OpenPagesAdministrator",
"modifiedDate": "2013-09-10T11:52:27.000-04:00"
},
{
"name": "Description",
"id": "56",
"newValue": "updated test object description",
"oldValue": "test object description",
"modifiedBy": "OpenPagesAdministrator",
"modifiedDate": "2013-09-10T11:52:25.000-04:00"
}
]
• /grc/api/contents/{contentId}/permissions/cancreate/{typeId}?folder={fold
erId}: A GET operation to this URL returns “true” if the authenticated user making the
request can create a child of typeId for the parent identified by contentId. A value of
“false” is returned if the user doesn’t have the required security permissions. The optional
folderId parameter specifies the parent folder to contain the instance being created. A
25
default folder for the parent context and child type is determined if folderId is not
specified.
Returns:
true
• /grc/api/contents/{contentId}/permissions/allowedtocreatetypes
?types={typeIds}: A GET operation to this URL returns a list of child types that the
authenticated user making the request can create for the parent identified by contentId.
The optional typeIds parameter lists the metadata type names or Ids of types in the
environment to check against. If typeIds is not specified, all types in the environment are
checked, which may impact performance.
Returns:
[“ LossEvent”,”LossImpact”,”LossRecovery”]
• /grc/api/contents/{contentId}/permissions/effective?user={userId}: A GET
operation to this URL returns a JSON response with the effective permissions for the parent
identified by contentId. The userId query parameter is optional; if not provided, the service
returns results for the authenticated user making this request. Only Security Administrators
can make this request for a user other than themselves.
Returns:
{
"folderId":"1234",
"securityPrincipal":"bill",
"canRead":false,
"canWrite":false,
"canDelete":false,
"canAssociate":false
}
Note: The folderId returned in this JSON represents the parent folder Id for the GRCObject
identified by contentId. In OpenPages, effective permissions are defined at the folder level.
{
"fields":
26
{
"field":
[
{
"id": "90",
"dataType": "DATE_TYPE"
},
{
"id": "300",
"dataType": "DATE_TYPE"
},
{
"id": "297",
"dataType": "STRING_TYPE"
},
{
"id": "301",
"dataType": "STRING_TYPE"
},
{
"id": "299",
"dataType": "DATE_TYPE"
},
{
"id": "302",
"dataType": "INTEGER_TYPE"
},
{
"id": "298",
"dataType": "DATE_TYPE"
}
]
},
"typeDefinitionId": "45"
}
• /grc/api/contents/template?typeId={TypeID}&fileTypeId={FileTypeId}: For
document attachment File Types in addition to the Type Definition Id for the
SOXDocument or other type, you must specify a FileTypeId for desired File content type.
These file type ids are available in /grc/api/types/{TypeID} for document types.
{
"fields":
{
"field":
[
]
},
"typeDefinitionId": "42",
"fileTypeDefinition":
{
27
"fileExtension": "xls",
"mimeType": "application/vnd.ms-excel",
"id": "46"
},
"contentDefinition":
{
"attribute":
{
"type": "application/vnd.ms-excel"
}
}
}
• /grc/api/contents/permissions/allowedtocreatetypes?
?user={userId}&types={typeIds}: A GET operation to this URL returns the object
types that the user can create, based on security roles, groups and security rules. The
userId query parameter is optional; if not provided, the service returns results for the
authenticated user making this request. The optional typeIds parameter is lists the
metadata type names or Ids of types in the environment to check against. If not
provided, all types in the environment are checked, which may impact performance. Only
Security Administrators can make this request for a user other than themselves.
Returns: an array of type names that the user ‘bill’ can create:
[“ LossEvent”,”LossImpact”,”LossRecovery”]
Note: Due to the expensive nature of this request on both the OpenPages and Cognos
servers, it is recommended that clients do not request this frequently, and client
applications should display report fragment fields on demand only.
Example: A GET operation to the following URL (field group: OPSS-BE, field name: RF)
http://localhost/grc/api/contents/3009/report/OPSS-BE%3ARF
28
"value": "<div><div><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"
id=\"List1\" style=\"font-family:Arial Unicode MS; font-size:10.000000pt; \"><tr><td
style=\"font-family:Arial Unicode MS; font-size:10.000000pt; \">…."
}
/folders
• /grc/api/folders: A GET operation returns the root folder “/”. The folder information is in
the op:folder extension. To view the items contained by this folder, perform a GET
operation on the containees. For example, /grc/api/folders/1/containees
[
{
"name": "_cw_channels",
"id": "7",
"path": "/_cw_channels",
"description": "Channels Folder",
"parentFolderId": "1"
},
{
"name": "_cw_destination",
"id": "8",
"path": "/_cw_destination",
"description": "Destination Folder",
"parentFolderId": "1"
},
{
"name": "_op_sox",
"id": "21",
"path": "/_op_sox",
"description": "OpenPages Compliance Objects Folder",
"parentFolderId": "1"
},
{
"name": "_op_sox_documents",
"id": "22",
"path": "/_op_sox_documents",
"description": "OpenPages Compliance Documents Folder",
"parentFolderId": "1"
},
{
"name": "Migration Documents",
"id": "206",
"path": "/Migration Documents",
"description": "Contains a history of migration files on this machine",
"parentFolderId": "1"
},
{
"name": "Reports",
"id": "30",
"path": "/Reports",
29
"description": "Reporting Component JSPs",
"parentFolderId": "1"
},
{
"name": "System",
"id": "9",
"path": "/System",
"description": "System Folder",
"parentFolderId": "1"
},
{
"name": "Templates",
"id": "128",
"path": "/Templates",
"description": "Application Template Files",
"parentFolderId": "1"
},
{
"name": "_trigger_config_.xml",
"id": "41",
"path": "/_trigger_config_.xml",
"description": "Trigger Configurations",
"parentFolderId": "1",
"fields":
{
"field":
[
{
"id": "28",
"dataType": "ID_TYPE",
"name": "Resource ID",
"value": "41"
},
{
"id": "59",
"dataType": "INTEGER_TYPE",
"name": "Created By",
"value": 2
},
{
"id": "58",
"dataType": "DATE_TYPE",
"name": "Creation Date",
"value":
{
}
},
{
"id": "60",
"dataType": "DATE_TYPE",
"name": "Last Modification Date",
"value":
30
{
}
},
{
"id": "61",
"dataType": "INTEGER_TYPE",
"name": "Last Modified By",
"value": 6
},
{
"id": "57",
"dataType": "STRING_TYPE",
"name": "Location",
"value": "/_trigger_config_.xml"
},
{
"id": "55",
"dataType": "STRING_TYPE",
"name": "Name",
"value": "_trigger_config_.xml"
}
]
},
"typeDefinitionId": "1"
}
]
• /grc/api/folder: A POST operation to this URL containing the entry representing a folder
object to be created will create the folder.
{
"name": "testFolder",
"path": "/testFolder",
"description": "TestFolder",
"parentFolderId": "1"
}
• /grc/api/folders/{id}: A GET operation returns an entry for the specified folder by its
id. A PUT operation to this URL containing the entry representing the folder object will
update the folder with the specified id. A DELETE operation will delete the folder with the
specified id.
Returns:
{
"name": "testFolder",
"id": "7914",
"path": "/testFolder",
"description": "TestFolder",
"parentFolderId": "1",
"links":
[
31
{
"href": "7914",
"rel": "self"
},
{
"type": "application/json",
"href": "7914?alt=application%2Fjson",
"rel": "alternate"
},
{
"href": "7914",
"rel": "edit"
},
{
"type": "application/json",
"href": "7914?alt=application%2Fjson",
"rel": "describedby"
},
{
"type": "application/json",
"href": "1?alt=application%2Fjson",
"rel": "up"
},
{
"type": "application/json",
"href": "7914/containees?alt=application%2Fjson",
"rel": "down"
}
]
}
Returns:
{
"folderId":"1234",
"securityPrincipal":"bill",
"canRead":false,
"canWrite":false,
"canDelete":false,
"canAssociate":false
}
32
Deleted resources
• /grc/api/contents/deletedresources?filter={condition}&startRow={paging
start row index}&endRow={paging end row index}: A GET operation to this URL
will get soft deleted GRC objects with specific filter conditions.
Example: A GET operation to the following URL will get soft deleted GRC objects which
location like ‘%Business%’ and type is ‘SOXBusEntity(5)’.
http://localhost/grc/api/contents/deletedresources?filter=Location+Like
%25Business%25&filter1=Content+Type+Id=5
Notes:
The parameter ‘filter’ supports multiple conditions with a continued index, for example
filter, filter1, filter2…
The filter operation can be one of: "=", "!=", "<", "<=", ">", ">=", "LIKE", "NOT LIKE".
Operations “LIKE” and “NOT LIKE” support to use the percent ('%') matches any group of
characters, and use the underscore ('_') matches any single character.
Use the filter “Purgeable Resource” to get only the deleted resources that can be purged.
This filter does not take in a condition, it has only a value.
Example: /grc/api/contents/deletedresources?filter=Purgeable+Resource
/query
• /grc/api/query?{query specification}: A GET operation using this URI performs a
query using the query service syntax call on the OpenPages model and pages through the
result set. The result contains a JSON object with a set of links and an array of rows. Each
row contains an object that includes all the fields for each row that was returned from the
query. This resource URI supports two query parameters, one for the query string and the
other for result pagination support. Query string can be specified using the “q” parameter,
the query string syntax that can be used is documented in the IBM OpenPages GRC
Platform API Javadoc. Pagination is supported using the “skipCount” parameter, which
specifies the starting result row. For the first row, “skipCount=0” should be used. For
33
results greater than the default page size of 50, use href URL with attribute rel=”next” link
to execute the query for the next page. The default page size can be changed with the
/OpenPages/Platform/API/Query/Default PageSize registry setting. Setting the page size to
0 will return all results. Other optional parameters for query include:
o caseInsensitive – string-type conditions are case-insensitive or not. Default is false.
o pageSize – number of rows per page
o maxRows – total number of rows returned by the query
o honorPrimary – only include primary associations
Example: A GET operation on the following URL (For unescaped query string: SELECT
[Name],[Shared:Shared Integer] FROM [LevelOne] )
http://localhost/grc/api/query?skipCount=0&pageSize=50&maxRows=2&caseInsensitive=f
alse&honorPrimary=false&q=SELECT+%5BName%5D,+%5BShared:Shared+Integer%5D
+FROM+%5BLevelOne%5D
Returns:
{
"links":
[
{
"rel": "self“,
href":
"http://localhost/grc/api/query?skipCount=0&q=SELECT+%5BName%5D,+%5BShared:Sh
ared+Integer%5D+FROM+%5BLevelOne%5D"
},
{
"rel": "alternate",
"href":
”http://localhost/grc/api/query?skipCount=0&q=SELECT+%5BName%5D,+%5BShared:Sh
ared+Integer%5D+FROM+%5BLevelOne%5D&alt=application%2Fjson",
"type": "application/json"
},
{
"rel": "alternate",
"href":
“http://localhost/grc/api/query?skipCount=0&q=SELECT+%5BName%5D,+%5BShared:Sh
ared+Integer%5D+FROM+%5BLevelOne%5D&alt=application%2Fatom%2Bxml",
"type": "application/atom+xml"
},
{
"rel": "first",
"href":
"http://localhost/grc/api/query?skipCount=0&q=SELECT+%5BName%5D,+%5BShared:Sh
ared+Integer%5D+FROM+%5BLevelOne%5D&alt=application%2Fjson",
"type": "application/json"
},
{
"rel": "next",
"href":
"http://localhost/grc/api/query?skipCount=50&q=SELECT+%5BName%5D,+%5BShared:S
hared+Integer%5D+FROM+%5BLevelOne%5D&alt=application%2Fjson",
"type": "application/json"
34
}
],
"rows":
[
{
"fields":
{
"field":
[
{
"id": "55",
"dataType": "STRING_TYPE",
"name": "Name",
"value": "Level One 1"
},
{
"id": "142",
"dataType": "INTEGER_TYPE",
"name": "Shared:Shared Integer",
"value": 31
}
]
}
},
{
"fields":
{
"field":
[
{
"id": "55",
"dataType": "STRING_TYPE",
"name": "Name",
"value": "Level One 2"
},
{
"id": "142",
"dataType": "INTEGER_TYPE",
"name": "Shared:Shared Integer",
"value": 17
}
]
}
}
]
}
• /grc/api/query A POST operation using this URI with the query statement and skip
count being specified in the body of the request in JSON format performs a query the same
as the GET method.
35
With JSON Body to define the query:
{
"statement": " SELECT [Resource ID] FROM [SOXDocument] ",
"skipCount": 0,
"maxRows": 0,
"pageSize": 50,
"caseInsensitive": false,
"honorPrimary": false
}
Returns:
{
"links": [
{
"rel": "self",
"href":
"query?skipCount=0&q=SELECT+%5BResource+ID%5D+FROM+%5BSOXDocument%5D"
},
{
"rel": "alternate",
"href":
"query?skipCount=0&q=SELECT+%5BResource+ID%5D+FROM+%5BSOXDocument%5D
&alt=application%2Fjson",
"type": "application/json"
},
{
"rel": "first",
"href":
"query?skipCount=0&q=SELECT+%5BResource+ID%5D+FROM+%5BSOXDocument%5D
&alt=application%2Fjson",
"type": "application/json"
}
],
"rows": [
{
"fields": {
"field": [
{
"dataType": "ID_TYPE",
"id": "28",
"name": "Resource ID",
"value": "80"
}
]
}
}
]
}
36
/configuration
/adminMode
• /grc/api/configuration/adminMode: A GET operation returns true or false depending
on whether the administrator mode is enabled or disabled.
37
/currencies
• /grc/api/configuration/currencies/base: A GET operation to this URL will return the
OpenPages base currency information.
{
"name": "United States of America, Dollars",
"id": "10",
"symbol": "$",
"precision": 2,
"isEnabled": true,
"isoCode": "USD",
"isBaseCurrency": true
}
Returns:
{
"name": "Euro",
"id": "300",
"symbol": "€",
"precision": 2,
"isEnabled": true,
"isoCode": "EUR",
"isBaseCurrency": false
}
• grc/api/configuration/currencies/{code}?enable={true|false}: A PUT operation
to this URL sets the status of the Currency specified by the ISO currency code. The status
is set to enabled when the enable query parameter is set to true. It is disabled when
enable is set to false.
• grc/api/configuration/currencies/{code}/exchangeRates?date={As of Date}:
A GET operation to this URL will return exchange rates for a currency for a specified ISO
currency code. The default path returns the current exchange rate. Optionally, to get the
exchange rate as of a particular date, use the date parameter. The expected As of Date
format is ISO 8601 'yyyyMMdd'T'HHmmssZ. To retrieve all historical exchange rates for this
currency code, omit the date parameter and use parameter ‘history=true’.
A POST operation to this URL will set a specific exchange rate. When startDate is not
provided, the default value will be the current date.
38
Example: A POST operation to the following URL
http://localhost/grc/api/configuration/currencies/CAD/exchangeRates
{
"rate":0.8636,
"startDate":"2015-05-20"
}
/reportingPeriods
• grc/api/configuration/reportingPeriods : A GET operation to this URL will return all
the reporting periods.
[
{
"id": "1",
"description": "Finalized reporting period description",
"creationDate": "2013-08-02T01:14:27.000-04:00",
"label": "Finalized reporting period name:2013-08-02T01:08:20-04:00",
"modifiedDate": "2013-08-02T01:14:27.513-04:00",
"finalizedDate": "2013-08-02T01:14:34.888-04:00"
},
{
"id": "-1",
"description": "Current Reporting Period",
"creationDate": "2013-08-01T21:52:26.000-04:00",
"label": "Current Reporting Period",
"modifiedDate": "2013-08-01T21:52:26.997-04:00",
"finalizedDate": "2013-08-01T21:52:26.997-04:00"
}
]
39
{
"id": "-1",
"description": "Current Reporting Period",
"creationDate": "2013-08-01T21:52:26.000-04:00",
"label": "Current Reporting Period",
"modifiedDate": "2013-08-01T21:52:26.997-04:00",
"finalizedDate": "2013-08-01T21:52:26.997-04:00"
}
/text
grc/api/configuration/text: A GET operation to this URL returns all the application text
for the user’s locale. Optionally use parameter categoryFilters to filter application texts by
category names. Also use optional parameter includeLocalizedLabels to include localized
labels for all the locales.
[
{
"name": "button.copy",
"category": "Buttons",
"localizedLabel": "Copy"
},
{
"name": "com.title.group.associate.subgroups",
"category": "Titles",
"localizedLabel": "Associate Groups"
},
{
"name": "com.title.guidedaction.add.dependency",
"category": "Titles",
"localizedLabel": "Add Field Dependency"
}
]
• grc/api/configuration/text/{textKey}: A GET operation to this URL will return
application text value for the user’s locale. The text key is the application text key as defined
in the Administration > Application Text menu.
Returns:
Rendered As JSON:
[
"D",
"e",
"t",
"a",
"i",
40
"l",
" ",
"V",
"i",
"e",
"w"
]
/profiles
• grc/api/configuration/profiles: A GET operation to this URL will return the profile
summary information of all the profiles.
[
{
"name": "Default",
"id": "1",
"description": "Default Profile",
"isEnabled": true,
"isDefault": false,
"isFallback": false,
"isDeleted": false
},
{
"name": "OpenPages Platform",
"id": "2",
"description": "OpenPages Platform Profile",
"isEnabled": true,
"isDefault": false,
"isFallback": false,
"isDeleted": false
},
{
"name": "Testing",
"id": "3",
"description": "Generated by AFCON 6.1",
"isEnabled": true,
"isDefault": true,
"isFallback": true,
"isDeleted": false
}
]
Returns:
{
"name": "OpenPages Platform",
"id": "2",
"description": "OpenPages Platform Profile",
"isDefault": false,
41
"isFallback": false,
"isEnabled": true,
"isDeleted": false
}
Returns:
{
"name": "OpenPages Platform",
"id": "2",
"description": "OpenPages Platform Profile",
"isDefault": false,
"isFallback": false,
"objectTypes":
{
"objectType"
[
{
"name": "SOXBusEntity",
"id": "43",
"typeDefinition": "SOXBusEntity",
"order": 1,
"fields":
{
"field":
[
{
"fieldSystemName": "Name",
"id": "55",
"displayType":
{
"name": "Text",
"id": "4",
"maxLength": 4000,
"columns": 30
},
"isRequired": true,
"isReadOnly": false
},
{
"fieldSystemName": "Description",
"id": "56",
"displayType":
{
"name": "TextArea",
"id": "8",
"columns": 60,
"rows": 5
42
},
"isRequired": false,
"isReadOnly": false
}
]
},
"views":
{
"view":
[
{
"id": "34",
"viewTypeName": "Folder",
"name": "ID=34 OP=2 AT=43 VT=12",
"showDescription": true,
"isDefault": false,
"isDisabled": false,
"attributes":
{
"attribute":
[
]
},
"rootView": "34",
"childViews":
{
"childView":
[
]
},
"fields":
{
"field":
[
{
"id": "1",
"order": 1
},
{
"id": "2",
"order": 2
}
]
},
"sections":
{
"section":
[
]
}
},
{
43
"id": "1",
"viewTypeName": "Overview",
"showDescription": true,
"isDefault": false,
"isDisabled": false,
"attributes":
{
"attribute":
[
]
},
"types":
[
{
"type":
[
{
"id": "43"
},
{
"id": "46"
},
{
"id": "42"
}
]
}
]
},
]
}
},
]
• grc/api/configuration/profiles/fields?profile={profileName}&type={objectTyp
e}: A GET operation to this URL will return the field definitions from a specified profile and
object type.
e.g., Fields from the OpenPages Modules Master for SOXBusEntity.
Returns:
[
{
"id": "24158",
"name": "Name",
"groupName": "System Fields",
"localizedLabel": "Name",
"dataType": "STRING_TYPE",
"required": true,
"displayType": "Text"
},
{
44
"id": "24159",
"name": "Description",
"groupName": "System Fields",
"localizedLabel": "Description",
"dataType": "STRING_TYPE",
"required": false,
"displayType": "Text Area"
},
{
"id": "24160",
"name": "Location",
"groupName": "System Fields",
"localizedLabel": "Folder",
"dataType": "STRING_TYPE",
"required": true,
"displayType": "Text"
},
{
"id": "24161",
"name": "Creation Date",
"groupName": "System Fields",
"localizedLabel": "Creation Date",
"dataType": "DATE_TYPE",
"required": true,
"displayType": "Date"
},
{
"id": "24162",
"name": "Created By",
"groupName": "System Fields",
"localizedLabel": "Created By",
"dataType": "INTEGER_TYPE",
"required": true,
"displayType": "Integer"
},
{
"id": "24163",
"name": "Last Modification Date",
"groupName": "System Fields",
"localizedLabel": "Last Modification Date",
"dataType": "DATE_TYPE",
"required": true,
"displayType": "Date"
},
{
"id": "24164",
"name": "Last Modified By",
"groupName": "System Fields",
"localizedLabel": "Last Modified By",
"dataType": "INTEGER_TYPE",
"required": true,
"displayType": "Integer"
},
45
{
"id": "24165",
"name": "Business Entity Structure",
"groupName": "System Fields",
"localizedLabel": "Business Entity Hierarchy",
"dataType": "STRING_TYPE",
"required": false,
"displayType": "Text"
},
{
"id": "24166",
"name": "Primary Association Path",
"groupName": "System Fields",
"localizedLabel": "Primary Parent Hierarchy",
"dataType": "STRING_TYPE",
"required": false,
"displayType": "Text"
},
{
"id": "24167",
"name": "Shared Text Area",
"groupName": "Shared",
"localizedLabel": "Shared Text Area",
"dataType": "STRING_TYPE",
"required": false,
"displayType": "Text Area"
},
{
"id": "24168",
"name": "Shared Text Box",
"groupName": "Shared",
"localizedLabel": "Shared Text Box",
"dataType": "STRING_TYPE",
"required": false,
"displayType": "Text"
},
{
"id": "24169",
"name": "Shared Rich Text",
"groupName": "Shared",
"localizedLabel": "Shared Rich Text",
"dataType": "STRING_TYPE",
"required": false,
"displayType": "Rich Text"
},
{
"id": "24170",
"name": "Shared Drop Down",
"groupName": "Shared",
"localizedLabel": "Shared Drop Down",
"dataType": "ENUM_TYPE",
"required": false,
"displayType": "List"
46
}
]
Note: please note that the old iteration of this endpoint that takes a view name as a
parameter (that is:
grc/api/configuration/profiles/fields?profile={profileName}&type={objectType}&view={viewN
ame} ) has been deprecated.
A call to this endpoint will result in a 400 error
Returns
{
"value": "false",
"key": "/OpenPages/Applications/GRCM/Audit Trail/Show Audit Trail For Custom
Forms"
}
/security
/groups
Some of the URLs related to groups expect a group id. This {id} can be either the group’s
name or the group’s OpenPages Id. If the group’s name is numeric – e.g. ‘12345’ - then add
the following parameter to the url: isName=[true | false]. If the parameter isName is not
specified, it is the same as if ‘isName=false’ was used.
Note: The isName parameter is applicable only to the group’s identifier in the URL path and
not applicable to any parameters in the URL query string.
47
"adminLevel": 2,
"isEditable": false,
"isLocked": false,
"isDeleted": false,
"emailAddress": "others@openpages.local",
"parentId":"11"
• /grc/api/security/groups: A GET operation on such a path would return the list of top-
level groups.
{
"id": "1019",
"description": "Rest API test group",
"groupName": "TestGroup20",
"isHidden": false,
"adminLevel": 0,
"isEnabled": true,
"isEditable": true,
"isLocked": false,
"isDeleted": false,
"emailAddress": "others@openpages.local",
"hasMembers": false,
"links":
[
{
"href": "1019",
"rel": "self"
},
{
"type": "application/json",
"href": "1019?alt=application%2Fjson",
"rel": "alternate"
},
{
"href": "1019",
"rel": "edit"
},
{
"type": "application/json",
"href": "1019?alt=application%2Fjson",
"rel": "describedby"
},
{
"type": "application/json",
"href": "11?alt=application%2Fjson",
48
"rel": "up"
},
{
"type": "application/json",
"href": "1019/subgroups?alt=application%2Fjson",
"rel": "down"
}
]
}
[
{
id:"1024"
},
{
id:"1025"
}
]
A GET operation to this URL will return the list of subgroups of the group with specified id.
Returns:
[
{
"links":
[
{
"rel": "alternate",
"href": "../300?alt=application%2Fjson",
"type": "application/json"
},
{
"rel": "self",
"href": "../300"
},
{
"rel": "edit",
49
"href": "../300"
},
{
"rel": "describedby",
"href": "../300?alt=application%2Fjson",
"type": "application/json"
},
{
"rel": "up",
"href": "../299?alt=application%2Fjson",
"type": "application/json"
},
{
"rel": "down",
"href": "../300/subgroups?alt=application%2Fjson",
"type": "application/json"
}
],
"groupName": "API_Sub_Group75bc19db-6150-44a7-92e6-ef21d12f26b4",
"id": "300",
"description": "Sub group created for CRUD test through API - updated",
"isLocked": false,
"isHidden": false,
"isDeleted": false,
"isEnabled": false,
"isEditable": true,
"hasMembers": false,
"emailAddress": "foo@ibm.com",
"adminLevel": 0
}
]
• /grc/api/security/groups/{id}/subgroups?subgroups={subgroupId}: A DELETE
operation would remove specified subgroups from the group with the specified id.
Example: A DELETE operation to the following URL will remove the subgroups with ids
1024 and 1025 from the group with id 1020.
http://localhost/grc/api/security/groups/1020/subgroups?subgroups=1024,1025
Optionally, subgroups ids can be provided in request body as {"value":"1024,1025"}.
[
{
id:"2012"
},
50
{
id:"2008",
userName:"RESTUSER2",
firstName:"user2",
lastName:"test",
"localeISOCode": "en_us",
"availableProfileNames": [ "ORM Profile", “ITG Profile”],
"preferredProfileName": "ORM Profile"
"displayName": " RESTUSER2 [user2 test] user2@openpages.local"
}
]
A DELETE operation would delete the specified users from the group with the specified Id.
Example: A DELETE operation to the following URL will remove the users with id 1021 and
1022 from the group with id 1020.
http://localhost/grc/api/security/groups/1020/users?users=1021,1022
Optionally, user ids can be provided in request body as {"value":"1021,1022"}.
• /grc/api/security/groups/{Id}/roles?role={roleId}&context={grcObjectId}:
A POST operation to this URL will assign the roles to the specified group id.
Example:
http://localhost/grc/api/security/groups/2010/roles?role=2033&context=14601
A DELETE operation to this will revoke the specified roles of the group with the specified
Id.
/permissions
• /grc/api/security/permissions: A GET operation to this URL returns a list of all the
application permissions.
Returns:
{
"name": "System Administration Mode",
"id": "3",
"description": "System administration mode functions",
"fullName": "All/Administration/System Administration Mode"
}
51
/roles
• /grc/api/security/roles: A GET operation to this URL returns the list of all role
templates.
Returns:
[
{
"id": "241",
"description": "used in role template related automation tests for REST API. ",
"roleName": "RiskApiTestRoleTemplate_1",
"isEnabled": true,
"isLocked": false,
"grcObjectType": "SOXBusEntity",
"dateCreated": "2013-09-23T12:19:03.680-04:00",
"dateChanged": "2013-09-25T22:49:52.285-04:00"
}
]
Returns:
[
{
"id": "1",
"canRead": true,
"canWrite": false,
"canDelete": false,
"canAssociate": false,
"rootFolderId": "14",
"objectTypeId": "5"
},
{
"id": "2",
"canRead": true,
"canWrite": false,
"canDelete": false,
"canAssociate": false,
"rootFolderId": "17",
"objectTypeId": "5"
}
]
• /grc/api/security/roles/{roleId}/permissions: A GET operation to this URL returns
the list of all the permissions associated with the specified role.
[
{
"name": "All Permissions",
52
"id": "1",
"fullName": "All"
},
{
"name": "Administration",
"id": "2",
"description": "Access all administrative functions",
"fullName": "All/Administration"
},
{
"name": "System Administration Mode",
"id": "3",
“description": "System administration mode functions",
"fullName": "All/Administration/System Administration Mode"
},
{
"name": "Files",
"id": "4",
"fullName": "All/Files"
}
]
/users
• Some of the URL’s related to users expect a user id. This {userId} can be either the user’s
name or the user’s OpenPages Id. If the user’s name is numeric – e.g. ‘12345’ - then add
the following parameter to the url: isName=[true | false]. If the parameter isName is
not specified it is the same as if ‘isName=false’ was used.
Note: The isName parameter is applicable only to the user’s identifier in the URL path
and not applicable to any parameters in the URL query string.
{
userName:"RESTUSER1",
firstName:"user1",
lastName:"test",
localeISOCode: "en_us",
emailAddress: "others@openpages.local",
availableProfileNames: [ "ORM Profile", “ITG Profile”],
preferredProfileName: "ORM Profile",
53
password: "password",
"displayName": " RESTUSER1 [user1 test] others@openpages.local"
groups:
{
group:
[
{
id :"2003"
groupName:"RestTestGroup1"
},
{
id :"2004" ,
groupName:"RestTestGroup2"
}
]
}
54
{
"id": "1021",
"userName": "RUSER1",
"description":"Rest API test user 1"
}
Returns:
{
"id": "1021",
"description": "Rest API test user 1",
"userName": "RUSER1",
"adminLevel": 0,
"isEnabled": false,
"isHidden": false,
"isEditable": true,
"firstName": "Ruser1",
"lastName": "Rtest",
"passwordExpiresInDays": 0,
"isTemporaryPassword": false,
"isPasswordChangeFromAdmin": false,
"isLocked": false,
"isDeleted": false,
"emailAddress": "others@openpages.local",
"localeISOCode": "en_us",
"canChangePassword": false,
"passwordCreationDate": "2013-09-25T22:04:44.744-04:00",
"isSecurityAdministrator": true,
"availableProfileNames": [ "ORM Profile", “ITG Profile”],
"preferredProfileName": "ORM Profile"
"displayName": " RUSER1 [Ruser1 Rtest] others@openpages.local"
}
Returns:
[
{
"id": "1020",
"description": "Rest API test group",
"groupName": "Group1",
"adminLevel": 0,
"isEnabled": true,
"isHidden": false,
"isEditable": true,
"isLocked": false,
"isDeleted": false,
"emailAddress": "others@openpages.local",
"hasMembers": false
},
{
"id": "3",
55
"description": "All OpenPages Users",
"groupName": "OpenPages",
"adminLevel": 2,
"isEnabled": true,
"isHidden": false,
"isEditable": false,
"isLocked": false,
"isDeleted": false,
"emailAddress": "AllOpenPagesUsers@openpages.local",
"hasMembers": false
}
]
• /grc/api/security/users/{userId}/roles?role={roleId}&context={grcObjectId
or objectTypeName}: A POST operation to this URL assigns the roles to the specified
user id for the specified object folder. A DELETE operation revokes the specified roles of
the user id for the specified object folder. If the parameter ‘context’ is an object type
name, the assign/revoke operations will act on the root folder of the object type.
• /grc/api/security/users/{userId}/action/anonymize?text={anonymizedText}:
A PUT operation to this URL containing the entry representing the object to be updated will
anonymize attributes (first name, middle name, last name, description, email address) of the
specified user id.
The parameter “text” is optional, default is "Anonymous", the maximum length of the value
is 64.
The first name, last name and description of the user will be the anonymized text.
Permissions:
The operation can only be performed by a super user.
Note: please make sure that the given user's activity in the system has
terminated/quiesced before anonymizing them.
/search
• /grc/api/search: A GET operation using this URI performs a search across all OpenPages
56
data using a search index; configured by system administrators. The search is performed
by matching search terms across any field in the current user’s profile and returns a list of
results based on a search ranking (most relevant first). A specific range can be requested,
and separate requests are used to retrieve subsequent ranges. The results are limited to
the setting ‘Platform / Search / Request / Result Cache Size’; ranges beyond this size are
not allowed. The search may be scoped by a list of Types, or all Types if not specified.
Optional Parameters:
o fot – a comma-delimited list of Object Type names or IDs. When two or more Object
Types names or IDs are used, the search is OR’ed.
o fur – a search syntax representing one or more Users facets to search on, use
semicolon to represent more than one user facet.
Syntax: {!T A}[DATA];{!T A}[DATA]
T == Type of user facet
• !c = creator
• !l = last modified by
• !o = names on object
When two or more types are used, the search is AND’ed.
A == Action on user facet
• m = me
• o = others
DATA = Data of user facet
• Comma delimited list of user IDs; if a user ID has a comma, it must
be escaped using “\”.
o fdt – a search syntax representing one or more Dates facets to search on, use
semicolon to represent more than one date facet.
Syntax: {!T A}[DATA];{!T A}[DATA]
T == Type of date facet
• !c = creation date
• !l = last modified date
• !o = other date
When two or more types are used, the search is AND’ed.
A == Action on date facet
• o = on date
• r = range date
• p = previous days
• n = next days
DATA = Data of date facet
• YYYY-MM-DD = a specific date
• YYYY-MM-DD TO YYYY-MM-DD = for range date
• # = for previous or next days
o ffp – a string representing the Folder Path facet to search on
o range – a range of results to return in format [start]-[end]
Example: range=0-49. Default, if not specified, is a range of 0-9.
o types – (deprecated, use “fot”) a comma-delimited list of object type names or Ids
o fmt – a comma-delimited list of MIME types for faceted search of file attachments
(global search) by MIME Media type.
Example: "application/pdf"
Facet searching is available on fot (Object Types), fdt (Dates), & ffp (Folder Path). Two or
more facets can be combined. For example,
fot – &fot=SOXBusEntity,SOXIssue,SOXTask
57
fur – &fur={!c m}[orm];{!l o}[ alaudit,sueaudit,charlieaudit]
fdt – &fdt={!c o}[2015-06-01];{!l r}[2016-01-01 TO 2016-06-31];{!o n}[7]
ffp – &ffp=/Test 273/Level One 84/Issue 84
Returns:
A search results list containing one page of matching results from the search index, based
on result rankings. The search results contain summary information of GRC Objects only.
Note: the matching search field may not necessarily be present in the response data as the
match may have been from another field that is not returned.
[
{
"id":"4029",
"name":"Test 132.txt",
"description":"This is an example of free text.",
"path":"BusinessEntity / Test 131 / Test 132 / Test 132",
"title":"Example title",
"objectTypeId":"5",
"objectTypeName":"SOXBusEntity",
"objectTypeLabel":"Business Entity",
"parentFolderId":"1480"
},
{
"id": "1242",
"name": "Global Financial Services",
"path": " / Global Financial Services",
"objectTypeId": "43",
"objectTypeName": "SOXBusEntity",
"objectTypeLabel": "Business Entity",
"parentFolderId": "1241"
}
]
Range headers
The Search API supports an optional alternative method for specifying ranges of results. The
Search API will support HTTP’s Range header to perform paging as well as the range query
parameter. The Range Header is defined by RFC 2616 as a header with the format of:
Range: items=0-9
The Search REST API responds with another HTTP header to indicate the range that the server
was able to respond with.
Content-Range: items 0-9/100
The number following the range of items represents the total number of items available on the
server for that search. Clients may request any range up to that total amount.
58
/processes
Used to interact with OpenPages long running processes for query a process information
operations and other related features.
• /grc/api/processes/types: A GET operation to this URL retrieves a list of all process type
information.
Returns:
[
{
"processTypeId": "12",
"name": "Create Reporting Schema",
"description": "Create Reporting Schema",
"defaultTimeSeconds": 3600,
"isMultipleInstance": false,
"isTerminateUponStart": true
},
...
{
"processTypeId": "36",
"name": "Reporting Framework Generation",
"description": "Reporting Framework Generation",
"defaultTimeSeconds": 3600,
"isMultipleInstance": false,
"isTerminateUponStart": true
}
]
59
o createdOnEnd - the end of the created time of queried processes, in
XMLGregorianCalendar pattern "yyyy-MM-dd'T'HH:mm:ss'Z'", for example:
"2001-01-31", "2001-01-31T01:59:59", "2001-01-31T01:59:59+01:00"
o createdBy – the process creator (user) name of queried processes.
Returns:
[
{
"processId": "2",
"name": "Reporting Framework Generation",
"description": "Generating Framework Model, Labels, Custom Query Subjects.",
"processTypeId": "36",
"finished": true,
"createdOn": "2017-07-03T16:37:06.857+08:00",
"createdBy": "OpenPagesAdministrator",
"status": "STATUS_FINISHED_SUCCESS",
"percentComplete": 100,
"childProcesses":
[
]
},
{
"processId": "1",
"name": "Create Reporting Schema",
"description": "Create Reporting Schema",
"processTypeId": "12",
"finished": true,
"createdOn": "2017-07-03T16:36:50.716+08:00",
"createdBy": "OpenPagesAdministrator",
"status": "STATUS_FINISHED_SUCCESS",
"percentComplete": 100,
"childProcesses":
[
]
}
]
Returns:
{
"processId": "1",
"name": "Create Reporting Schema",
"description": "Create Reporting Schema",
"processTypeId": "12",
"finished": true,
60
"createdOn": "2017-07-03T16:36:50.716+08:00",
"createdBy": "OpenPagesAdministrator",
"status": "STATUS_FINISHED_SUCCESS",
"percentComplete": 100,
"childProcesses":
[
]
}
Returns:
{
"processId": "1",
"name": "Create Reporting Schema",
"description": "Create Reporting Schema",
"processTypeId": "12",
"finished": true,
"createdOn": "2017-07-03T16:36:50.716+08:00",
"createdBy": "OpenPagesAdministrator",
"status": "STATUS_FINISHED_SUCCESS",
"percentComplete": 100,
"childProcesses":
[
]
}
• /grc/api/processes/{processId}/logs?includeLocalizedStatus={true|false}&st
artRow={paging start row index}&endRow={paging end row index}: A GET
operation to this URL retrieves a list of logs for a specific process information.
Example: GET operation with process id of 1 with localized status and return process logs
from the 10001 item to the 20000 item.
http://localhost/grc/api/processes/1/logs?
includeLocalizedStatus=true&startRow=10001&endRow=20000
Returns:
[
{
"processLogId": "172",
"processId": "1",
"status": "STATUS_FINISHED_SUCCESS",
"statusMessage": "Create Reporting Schema: completed",
"endTime": "2017-07-03T16:37:06.236+08:00"
},
{
61
"processLogId": "171",
"processId": "1",
"status": "STATUS_RUNNING",
"statusMessage": "Creation of Real-Time Reporting Schema: completed",
"endTime": "2017-07-03T16:37:06.233+08:00"
},
...
{
"processLogId": "1",
"processId": "1",
"status": "STATUS_STARTED",
"statusMessage": "Create Reporting Schema: Started",
"startTime": "2017-07-03T16:36:50.752+08:00"
}
]
http://www.ietf.org/rfc/rfc2616.txt
Returns: None
/rules
Used to interact with OpenPages regulatory events rules.
• /grc/api/rules/run: A POST operation to this URL will run any defined rules that may be
applicable to the object IDs passed in. If there are no rules applicable for an object passed
in, this will still be considered a successful run. The objects are passed in as an array of GRC
Object Id or path in the body of the request. The path may be a relative or a full path.
Example: Run the rules for the provided regulatory event objects
http://localhost/grc/api/rules/run
with body:
{
"objectIds": [
"12155",
"3164",
"/_op_sox/Project/Default/ICDocumentation/Regulatory
Events/Library/RCM/RegEvents/TRRIRegEvents/I7D8E68203DD311EAA9C9B
7A1807E26E0.txt",
"34333333"
]
}
Returns:
62
{
"failedObjects": [
{
"objectId": "3164"
},
{
"failureReason": "OP-03100: Resource \"34333333\"
was not found. [VYJBHNQMP0XE]",
"objectId": "34333333"
}
],
"successfulObjects": [
"12155",
"/_op_sox/Project/Default/ICDocumentation/Regulatory
Events/Library/RCM/RegEvents/TRRIRegEvents/I7D8E68203DD311EAA9C9B7A1
807E26E0.txt"
]
}
63
Return codes and errors
This section documents high-level guidelines for interpreting HTTP return status codes:
In most cases, 200 is the code the client hopes to see. It indicates that the REST API
successfully carried out whatever action the client requested, and that no more specific
code in the 2xx series is appropriate. Unlike the 204 status code, a 200 response
should include a response body.
2. 200 (“OK”) must not be used to communicate errors in the response body.
Always make proper use of the HTTP response status codes as specified by the rules in
this section. In particular, a REST API must not be compromised in an effort to
accommodate less sophisticated HTTP clients.
A REST API responds with the 201 status code whenever a collection creates, or a store
adds, a new resource at the client’s request. There may also be times when a new
resource is created as a result of some controller action, in which case 201 would also
be an appropriate response.
A 202 response indicates that the client’s request will be handled asynchronously. This
response status code tells the client that the request appears valid, but it still may have
problems once it’s finally processed. A 202 response is typically used for actions that
take a long while to process.
Controller resources may send 202 responses, but other resource types should not.
5. 204 (“No Content”) should be used when the response body is intentionally empty.
The 204 status code is usually sent out in response to a PUT, POST, or DELETE
request, when the REST API declines to send back any status message or representation
in the response message’s body. An API may also send 204 in conjunction with a GET
request to indicate that the requested resource exists but has no state representation to
include in the body.
The 301 status code indicates that the REST API’s resource model has been significantly
redesigned and a new permanent URI has been assigned to the client’s requested
resource. The REST API should specify the new URI in the response’s Location
header.
64
7. 302 (“Found”) should not be used.
The intended semantics of the 302 response code have been misunderstood by
programmers and incorrectly implemented in programs since version 1.0 of the HTTP
protocol. The confusion centers on whether it is appropriate for a client to always
automatically issue a follow-up GET request to the URI in response’s Location
header, regardless of the original request’s method. For the record, the intent of 302 is
that this automatic redirect behavior only applies if the client’s original request used
either the GET or HEAD method.
To clear things up, HTTP 1.1 introduced status codes 303 (“See Other”) and 307
(“Temporary Redirect”), either of which should be used instead of 302.
8. 303 (“See Other”) should be used to refer the client to a different URI.
A 303 response indicates that a controller resource has finished its work, but instead of
sending a potentially unwanted response body, it sends the client the URI of a response
resource. This can be the URI of a temporary status message, or the URI to some
already existing, more permanent, resource.
Generally speaking, the 303 status code allows a REST API to send a reference to a
resource without forcing the client to download its state. Instead, the client may send a
GET request to the value of the Location header.
This status code is similar to 204 (“No Content”) in that the response body must be
empty. The key distinction is that 204 is used when there is nothing to send in the
body, whereas 304 is used when there is state information associated with a resource
but the client already has the most recent version of the representation.
10. 307 (“Temporary Redirect”) should be used to tell clients to resubmit the request to
another URI.
HTTP/1.1 introduced the 307 status code to reiterate the originally intended semantics
of the 302 (“Found”) status code. A 307 response indicates that the REST API is not
going to process the client’s request. Instead, the client should resubmit the request to
the URI specified by the response message’s Location header.
A REST API can use this status code to assign a temporary URI to the client’s requested
resource. For example, a 307 response can be used to shift a client request over to
another host.
400 is the generic client-side error status, used when no other 4xx error code is
appropriate.
65
For errors in the 4xx category, the response body can contain a document describing
the client’s error (unless the request method was HEAD).
12. 401 (“Unauthorized”) must be used when there is a problem with the client’s credentials.
A 401 error response indicates that the client tried to operate on a protected resource
without providing the proper authentication. It may have provided the wrong credentials
or none at all.
13. 403 (“Forbidden”) should be used to forbid access regardless of authentication state.
A 403 error response indicates that the client’s request is formed correctly, but the
REST API refuses to honor it. A 403 response is not a case of insufficient client
credentials; that would be 401 (“Unauthorized”).
REST APIs use 403 to enforce application-level permissions. For example, a client may
be authorized to interact with some, but not all of a REST API’s resources. If the client
attempts a resource interaction that is outside of its permitted scope, the REST API
should respond with 403.
14. 404 (“Not Found”) must be used when a client’s URI cannot be mapped to a resource.
The 404 error status code indicates that the REST API can’t map the client’s URI to a
resource.
15. 405 (“Method Not Allowed”) must be used when the HTTP method is not supported.
The API responds with a 405 error to indicate that the client tried to use an HTTP
method that the resource does not allow. For instance, a read-only resource could
support only GET and HEAD, while a controller resource might allow GET and POST,
but not PUT or DELETE.
A 405 response must include the Allow header, which lists the HTTP methods that
the resource supports. For example: Allow: GET, POST.
16. 406 (“Not Acceptable”) must be used when the requested media type cannot be served.
The 406 error response indicates that the API is not able to generate any of the client’s
preferred media types, as indicated by the Accept request header. For example, a
client request for data formatted as application/xml will receive a 406 response if the
API is only willing to format data as application/json.
The 409 error response tells the client that they tried to put the REST API’s resources
into an impossible or inconsistent state. For example, a REST API may return this
response code when a client tries to delete a non-empty store resource.
66
18. 412 (“Precondition Failed”) should be used to support conditional operations.
The 412 error response indicates that the client specified one or more preconditions in
its request headers, effectively telling the REST API to carry out its request only if certain
conditions were met. A 412 response indicates that those conditions were not met, so
instead of carrying out the request, the API sends this status code.
19. 415 (“Unsupported Media Type”) must be used when the media type of a request’s
payload cannot be processed.
The 415 error response indicates that the API is not able to process the client’s supplied
media type, as indicated by the Content-Type request header. For example, a
client request including data formatted as application/xml will receive a 415 response if
the API is only willing to process data formatted as application/json.
20. 500 (“Internal Server Error”) should be used to indicate API malfunction.
500 is the generic REST API error response. Most web frameworks automatically
respond with this response status code whenever they execute some request handler
code that raises an exception.
Error responses
In cases of an Error generated from the API from either user input or server errors, the response
body should contain a standardized error response object consisting of two required attributes
and an optional errorCode.
Example:
{
"code": "404",
"message": "Not Found - OP-01024: The requested Object Type was
not found. [T1ITFG2RR5J9]",
"errorCode": "-1024"
}
Note: This behavior has changed in v8.0.0.3 and later. Previously the legacy behavior was to
put a Java level stack trace in the response body. Should you need this information it will be
logged in the application server logs. Additionally, you can change the registry setting
/OpenPages/Platform/API/Error Responses value to “detailed” to restore the legacy behavior.
67
Security
Authentication is delegated to the WebSphere application server, so each entry point should not
have to verify the authentication token. There are three authentication mechanisms available out
of the box: Basic authentication, Client Certificate authentication (since 8.0.0) and Token-based
authentication (as of OpenPages on Cloud Pak for Data 4.0).
Basic authentication
HTTP Basic authentication is configured by default through your OpenPages application server.
Basic authorization schema is defined by RFC 2617, and is implemented by the client sending an
HTTP request header. Basic authorization contains the text “Basic” followed by the username and
password separated by colon ‘:’ and encoded in Base64. For example, if the client wishes to send
the username "Aladdin" and password "open sesame", it would use the following HTTP header
field:
The OpenPages GRC REST API adheres to the RESTful systems principle of statelessness, so each
request made must provide the credentials of the user. Basic authentication is not considered
secure unless used with some external secure system such as SSL. For greatest security the
clients should avoid sending unencrypted credentials and requests should be performed over
HTTPS.
Client Certificate authentication is a method where the server allows requests only after
authenticating the client. The client must provide a public key certificate that identifies who the
client is, and that certificate must be trusted by the server (or signed by a trusted certificate)
client authentication. This traffic is over SSL (HTTPS), which ensures the security of the
connection and encryption. The control at the API level over which client certificates you trust
also provides an option to configure your security model to allow only certain pre-approved
clients to make requests to the REST API. For the OpenPages GRC REST API to use client
authentication instead of basic authentication, you must do some additional configuration in
Liberty.
For the official Liberty documentation about client authentication see “How to Setup Liberty to
Use Certificate-Based Authentication,” which goes into the general steps for configuring any
application in Liberty to use this method. For OpenPages, our integration with Liberty security
requires some additional configuration changes.
Prerequisites
68
the name 'brianl'. These usernames must exist as user accounts within OpenPages
before you begin.
Note: Creating a valid certificate yourself is beyond the scope of this document. But you
can read about how to do it using open source tools. For example:
http://veewee.github.io/blog/authenticating-with-x509-client-certificates/
• Access to the OpenPages application server and permission to modify the server
configuration.
Setup steps
Note: These steps guide you from taking a newly installed 8.2 or later environment and
configuring it to allow client certificate authentication for the REST API. If you've already
modified the Global Security configuration or GRC Security Domains (for instance for using SSO),
you might need to adjust these steps for your environment.
2. Create a new .xml file (for example OP_client_cert_config.xml) and add the following
elements:
<server>
<feature>transportSecurity-1.0</feature>
<sslDefault sslRef="defaultSSLConfig" />
<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" sslProtocol="SSL_TLSv2"
trustStoreRef="defaultTrustStore" clientAuthenticationSupported="true"/>
<keyStore id="defaultTrustStore" password="defaultPWD" />
<webAppSecurity allowFailOverToBasicAuth="true" />
</server>
Note: All elements for this configuration must go within the <server>
element.
• The keyStore element must specify a valid trust store to use (e.g. defaultTrustStore)
and its password (e.g. defaultPWD) as attributes.
keytool -keystore
<WLP_HOME>/usr/servers/<OP_SERVER>/resources/security/key.p12 -
storepass <password> -importcert -alias <Certificate alias> -file
<Path to CA certificate> -storetype PKCS12
69
4. In the newly created .xml file, create an <openpagesUserRegistry /> element (still within
the <server> element).
For example:
<openpagesUserRegistry
com.ibm.openpages.security.entry.user.regex="(?:CN=)([^,]+),?"
com.ibm.openpages.security.cert.regex="true"/>
These properties inform the OpenPages custom user registry how to parse a username
from the Subject entry in the client certificate. The first option is a simpler approach that
looks for the first occurrence of the CN= within a subject. The second approach uses a
regular expression to parse a username from the Subject with additional rules.
7. Next, modify REST API application's web.xml files for each server--both web.xml AND
web_merged.xml (if present). The files are under the path:
<WLP_HOME>/usr/shared/apps/op-apps.ear/com.ibm.openpages.api.rest.war/WEB-INF
Change:
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>OpenPagesRealm</realm-name>
</login-config>
To:
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>OpenPagesRealm</realm-name>
</login-config>
70
This should be expected to return some results that include a lot of output related to the SSL
handshake (thanks to --verbose), and the end result should be a response body containing JSON
describing the OpenPages metadata schema (since we are requesting everything from
/grc/api/types). You can play around using other API end-points.
Note: if your server is not using a valid SSL certificate, you can add the --insecure parameter to
the command for testing purposes. curl command's --no-alpn has been introduced in 7.36.0. If
your curl version is lesser than 7.36.0, remove the --no-alpn option while running the curl
command.
You can test this with other REST clients as well. For example, one popular client is PostMan,
which also supports client certificates through an additional configuration:
https://www.getpostman.com/docs/v6/postman/sending_api_requests/certificates
Regular expressions
The usage of regular expressions enables you to perform more granular logic for parsing out a
username from the larger Subject element of a certificate, which can contain many parts. The
example above shows how we might extract a username from a case where a Subject has the
form of "/C=US/O=IBM/OU=WFSS/CN=brianl".
Regex: (?:CN=)([^,]+),?
Essentially what this does is it looks for a non-capturing group that matches occurrences of
"CN=" and captures the text after that until the delimiter of ",". This is because when Liberty
interprets the Subject from the client certificate, the format in which the Subject is represented
looks like: "CN=brianl, OU=WFSS, O=IBM, C=US"
The Regex will match with "CN=brianl", and the username we take from the match will be the
capture group #1 identified by the regular expression as "brianl" in this case.
Here’s another example. Suppose that the CN= is not a simple username but an email address
and you need to map it to an OpenPages username.
In this case, the text we get from the Subject might be:
Text "CN=brianl@us.ibm.com, OU=WFSS, O=IBM, C=US"
Again, this matches the username from the CN= until the @ symbol, which parses just the part
we want from Subject.
This gives you more flexibility to handle different formats of Subjects in client certificates
depending on your organization’s policies and practices.
Token authentication
Token authentication is configured by default through your OpenPages application server under
Cloud Pak for Data as of version 4.0. The token is a Microprofile Json Web Token (MP-JWT) as
described in https://download.eclipse.org/microprofile/microprofile-jwt-auth-1.2/microprofile-jwt-
auth-spec-1.2.html. It is implemented by the client sending an HTTP request Authorization
71
header that starts with the text “Bearer ” followed by a valid MP-JWT token. For example:
To get a valid token to use with the GRC REST API on Cloud Pak for Data, use one of the
authentication APIs described here on the system on which OpenPages is installed:
https://www.ibm.com/docs/en/SSQNUZ_4.6.x/dev/generate-token.html.
The OpenPages GRC REST API adheres to the RESTful systems principle of statelessness, so each
request made must provide the credentials of the user. All communications under Cloud Pak for
Data enforce SSL by default.
72
Client-server interactions
Client interaction with the OpenPages GRC REST API, including sequence of events, depends on
the design of the client and the interaction objectives. Typically, an interaction will retrieve
Metadata, and/or Configuration information, and then make further requests to the server to
gather more data or perform updates.
Example: Diagram of the interaction to create a new GRC Object of type LossEvent
73
REST samples
The GRC API includes samples which demonstrate client-code which uses the REST APIs.
Samples are located in the grc_api/samples installation directory. The provided samples
demonstrate common use cases and offer developers a starting point for developing new
applications.
AnonLossEventFormREST
This demo illustrates using the Remote REST APIs to fulfill a use case for anonymous data entry.
The following provides an overview of this sample:
TivoliDirectoryIntegratorConnector
IBM Security Directory Integrator (SDI) is an integration framework Graphical Development
Environment to build and test solutions Web-based Administration and Monitoring Console for
management (AMC). It has connectors for many common protocols and systems. It also has
plugin architecture for making custom connectors/adapters. It allows for data transformation,
mapping for data from multiple systems in a defined flow called an "Assembly Line".
Note: SDI is the latest name for IBM Tivoli Directory Integrator (TDI).
This sample creates a very basic Assembly Line with an OpenPages connector written against the
OpenPages GRC REST API. The sample will pull LossEvents from OpenPages based on a Query
that is written in the QueryService syntax. The LossEvents are then mapped to a database table
called "Losses" that represents an external system.
Prerequisite: OpenPages 8.1 and later requires IBM Security Directory Integrator 7.2.0.3 to be
installed.
74
Performance tips
You may add indexes to improve the performance of running a query. For more information,
please see Viewing the Configuration and Settings page > Platform folder settings >
Reporting Schema folder settings in the OpenPages Administrator's Guide.
Known limitations
If a field has been excluded from the reporting schema, it cannot be referenced via the API.
If you exclude a field from the reporting schema and the reporting framework. you might need to
update some of the select statements when using the IBM® OpenPages® REST API.
Look for any select * statements in your code that are referencing object types with excluded
fields.
Using the * is not supported in combination with excluded fields. Instead, define those select
statements so that they explicitly return the subset of fields that are available and necessary to
satisfy your requirements.
75
Extend GRC API with custom REST services
Starting with version 8.0 (Fix Pack 2 or later) there is a feature in the GRC REST API which
supports extending the available REST API with custom services built according to the customer’s
needs. This provides the flexibility to create any business logic using the OpenPages GRC
Platform API and expose them in a convenient service that can be used by remote clients for
integrations or other automation purposes. Extensions to the REST API may be developed with
Java using the Spring Framework® and are deployed to the OpenPages application server as a
jar file package. On server startup the classpath will be scanned and any RestController classes
will be automatically loaded and ready to be used by your clients.
Assumptions
To use the extension feature effectively, you should have familiarity with the following
• OpenPages application and usage
• OpenPages GRC Platform API and OpenPages Legacy SDK*
• Programming languages and integrated development environments (IDEs), such as the
Java programming language and the Eclipse IDE
• Spring MVC and/or Spring-Rest frameworks
• Conventions and best practices for development of RESTful web services, including
secure engineering
The following requirements should be considered as you begin developing custom REST
extensions.
• Access is required to OpenPages application server file system to deploy files. Service
restarts are required to deploy new or updated extensions.
• Extensions could potentially expose the platform to risk based on the combination of
custom business logic code and execution of an platform APIs causing overhead on the
server. As with any custom development, this needs to be carefully designed,
implemented and tested before use in a production setting.
Extension framework
The Custom REST Services are built using an extension framework that has been added to the
standard GRC REST API web application deployed as part of the OpenPages Enterprise
Application on WebSphere Application Server. Please refer to the high-level diagram for the
architecture for the extension framework.
76
The custom code extensions will be introduced using classes which are annotated with Spring’s
@RestController annotation.
Unlike the Public GRC APIs, which are under the URI context of /grc/api/*, all of the extension
API’s will be under the /grc/ext/* context. Otherwise the Public and Extension APIs will both
share the same security mechanism, as configured in WebSphere Application Server. By default,
this will be BASIC authentication and it will function the same between the two kinds of APIs in
this web application.
Developing extensions
Dependencies
1. You must have a Java 8 JDK to compile and build your source code.
2. The following IBM and third-party libraries are the minimum required dependencies.
• com.ibm.openpages.api.jar
• slf4j-api-1.6.1.jar
• jackson-core-asl-1.9.11.jar
• jackson-mapper-asl-1.9.11.jar
• jackson-core-2.9.7.jar
• jackson-databind-2.9.7.jar
• jackson-annotations-2.9.0.jar
• spring-aop-5.1.3.RELEASE.jar
• spring-aspects-5.1.3.RELEASE.jar
• spring-beans-5.1.3.RELEASE.jar
• spring-context-5.1.3.RELEASE.jar
• spring-core-5.1.3.RELEASE.jar
• spring-expression-5.1.3.RELEASE.jar
• spring-oxm-5.1.3.RELEASE.jar
• spring-web-5.1.3.RELEASE.jar
• spring-webmvc-5.1.3.RELEASE.jar
77
Implementing a simple extension framework RestController
This example illustrates the required aspects for implementing a new custom RestController
class. The examples used are based on the available API Samples ‘CustomRESTService’.
1. Create a Java class. The class must be located in the Java package
com.ibm.openpages.ext.rest
Example:
com.ibm.openpages.ext.HelloController.java
2. The new class must extend from the
com.ibm.openpages.ext.rest.BaseExtController, which is now included in the
com.ibm.openpages.api.jar
Example:
public class HelloController extends BaseExtController {
}
3. Add Spring @RestController and annotations to identify your class as a RestController,
and @RequestMapping give it a URL mapping of your choice
Example:
@RestController
@RequestMapping(value="sample1")
public class HelloController extends BaseExtController {
}
Spring will map this controller will now be mapped to /grc/ext/sample1/* URL patterns
4. Now implement a method in your class that will perform the business logic you need
leveraging the OpenPages GRC Platform API, the method will also be annotated with
Spring’s @RequestMapping annotation to specify how this method should handle
requests
5. Once you have implemented your Java class, you can export it as a jar from your IDE or
use your preferred Java build tools to create the jar containing your class file.
78
Example:
Export from Eclipse as sample-rest.jar
Package com.ibm.openpage.ext.rest
Subclass of BaseExtController
Class Annotation @RestController, @RequestMapping
Method Annotation @RequestMapping
In this example we write a controller method that will use JSON to serialize a simple Java bean
object to JSON.
1. The response content-type is specified in the method’s @RequestMapping annotation
through the produces=MediaType.APPLICATION_JSON_VALUE
Example:
@RequestMapping (value="checkUser", method = RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
2. Listing 1: Ex am ple user m ethod w ith JSON response
@RequestMapping (value="checkUser", method = RequestMethod.GET
, produces=MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public UserBean checkUserApi(
Model model,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
The response content-type is specified in the method’s @RequestMapping annotation through the
produces=MediaType.APPLICATION_JSON_VALUE.
In this example the return object is type “UserBean” which is a plain Java object with several
getter/setter fields for user information.
79
Listing 2: UserBean Java class
public class UserBean {
public UserBean(){
actorId = null;
name = null;
displayName = null;
email = null;
}
Spring will automatically convert this to the Response Body as JSON using Jackson’s
ObjectMapper. The resulting JSON response body may look like in Listing 3:
80
Listing 3: JSON representation of UserBean
{
"actorId":123,
"name":"OpenPagesAdministrator",
"displayName":"System Administrator",
"email":"admin@youremail.com"
}
You have the flexibility to control the representation format for your responses by creating your
own objects. You can further control the JSON format through Jackson annotations.
@ResponseStatus declares what HTTP status and message are sent in response when the
exception is thrown
@ExceptionHandler declares what Java Exceptions will be mapped to the response status.
Security Best Practice: Per weakness CWE-209: Information Exposure Through an Error
Message ensure that error messages only contain minimal details that are useful to the intended
81
audience, and nobody else. In practice this means you typically do not want to include in an error
response any details that give away implementation details of your system to any potential
attackers. Sending a brief user readable reason for an error in your response and logging the full
details to a server-side log.
Tip: Look for messages in the WebSphere server’s SystemOut.log for messages to know whether
the RestController was loaded:
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
registerHandlerMethod Mapped
"{[/sample1/hello],methods=[GET],params=[],headers=[],consumes=[],pr
oduces=[text/plain],custom=[]}"
So for example if you had a RestController with a mapping to /sample1/hello and the method of
GET, then using a preferred HTTP client you could send a GET request /grc/ext/sample1/hello
and receive back in response:
“Hello <your username>”
Disabling extensions
The OpenPages Administration Settings menu item: Platform/API/Custom/Enable Custom
REST Service key is set to true by default. Setting value to false will globally disable all
deployed RestControllers. When disabled an Error 503: Service Unavailable response is always
returned.
82
log4j.logger.com.ibm.openpages.ext.rest=TRACE#com.openpages.aurora.comm
on.logging.Log4jEventLoggerLevel, rest
Once enabled logging will go to the <OP Home>/aurora/logs/opapp-*-rest.log
Typical log messages will include what RestControllers are being invoked, and elapsed duration of
request handling. Errors will also be written to aurora.log
83