Webhooks
Definition
From Wikipedia:
A webhook in web development is a method of augmenting or altering the behavior of a web page or web application with custom callbacks. These callbacks may be maintained, modified, and managed by third-party users and developers who may not necessarily be affiliated with the originating website or application.
Configuration
Administrators may define webhook URLs which will be called for three types of events:
Creation of a new contract.
Receiving a signature or a rejection.
Contract signing completion either due to all signatures collected or due to a rejection.
Defined endpoints will receive HTTP POST messages with JSON body defined below. Endpoints should return 201 Created or 202 Accepted or 204 No Content HTTP response.
Only endpoints with secured HTTP protocol (https://) are accepted in order to be complaint with a personal data protection regulations like GDPR, CCPA, LGPD or alike.
Messages
Common Fields to All Messages
field name | format / | description / |
---|---|---|
eventUuid | Canonical UUID | Unique identifier of this event. |
always | "76d7f54d-8678-423f-86fc-8d84bd9c33f7" | |
eventTimestamp | ISO 8601 | Time when the event has been triggered. |
always | "2022-09-29T13:10:47.476Z" | |
hostUrl | URI | Atlassian Jira or Confluence URL. |
always | ||
collectionId | JSON ASCII String | Jira Project or Confluence Space identifier |
always | "654321" | |
templateId | JSON ASCII String | Jira Issue or Confluence Page identifier |
always | "654321" | |
contractId | Canonical UUID | Unique identifier of a contract to which this event occurred. |
always | "7b527a58-8ef6-45b8-a3af-a917052b76d7" | |
contractName | JSON UTF-8 String | Name given to the contract. |
always | "Some Name of the Contract" | |
eventType | "creation" | Type of this event. One of "creation", "signature" or "completion". |
always | "signature" |
Signer Object Fields
field name | format / | description / |
---|---|---|
ordinal | JSON Integer | Signer index on the list. Value from 0 to 25. |
always | 1 | |
fullName | JSON UTF-8 String | Signer full name. |
always | "Richard Roe" | |
email address | Signer e-mail address. | |
optional | ||
phone | E.164 | SMS enable international phone number of a signer. |
optional | "+33639987654" |
Creation Event Specific Fields
field name | format / | description / |
---|---|---|
creatorId | JSON ASCII String | Atlassian user identifier. |
always | "324566:b84aeffd-32e5-4b4b-a012-89bf06cae06e" | |
creatorIp | IP address | IPv4 or IPv6 address from which contract creation request has come. |
always | "198.51.100.123" | |
signingDeadline | ISO 8601 | Time after which contract will become unsignable. |
always | "2022-10-06T13:10:47.476Z" | |
signInOrder | JSON Boolean | Determine if signatures must be put in the definition order. |
always | false | |
signers | JSON Array of Signer Objects | List of Signer Objects. |
always | Â |
Signature or Rejection Event Specific Fields
field name | format / | description / |
---|---|---|
signer | Signer Object | Signer data of who signed or rejected a contract. |
always | Â | |
decision | "signed" | Which decision the signer has made ? |
always | "rejected" |
Completion Event Specific Fields
field name | format / | description / |
---|---|---|
decision | "signed" | Is contract signed by all signers or the contract has been rejected by some signer ? |
always | "signed" | |
attachmentId | JSON ASCII String | Atlassian attachment identifier present for signed documents only. The attachment is a signed contract in a .pdf format. |
optional | "att87654321" | |
attachmentVersion | JSON Integer | Confluence attachment version. |
optional | 1 |
Creation Event Message Example
{
"eventUuid": "99fb897e-f83b-4e2f-a410-aa56194ae13e",
"eventTimestamp": "2022-09-29T13:00:48.273Z",
"hostUrl": "https://company.atlassian.net/wiki",
"collectionId": "654321",
"templateId": "123456",
"contractId": "19134d39-80ba-46ef-a757-0fec0aca006c",
"contractName": "NDA",
"eventType": "creation",
"creatorId": "78a48184-f840-4d9d-af70-85ceb7013f81",
"creatorIp": "198.51.100.210",
"signingDeadline": "2022-10-06T13:00:48.273Z",
"signInOrder": false,
"signers": [
{
"ordinal": 0,
"fullName": "Richard Roe",
"email": "richard.roe@gmail.com",
"phone": "+33639987654"
},
{
"ordinal": 1,
"fullName": "Janie Doe",
"email": "janie.doe@hotmail.com",
}
]
}
Authentication
Although confidentiality, integrity and recipient authenticity are assured by the https protocol itself, guaranteeing sender (Contract Signatures Application) authenticity requires additional consideration. For this we are digitally signing the entire body of the message and put a signature in the Signature
HTTP header Base64 encoded. We use P-384/secp384r1
elliptic curve with SHA-384
algorithm. Key used for signing is unique per Confluence/Jira instance and is rotated every 13 weeks. Private key stored in our database is encrypted by a symmetric-key stored in the Atlassian App Properties. To obtain a public key used for sign the message you need to download it from the URL provided in the Webhooks Configuration:
Every signed message contains Signature-Key-Timestamp
HTTP header which value should replace the timestamp
parameter in the URL to the public key. The key timestamp has to be verified: It may not be older than 13 weeks plus one hour buffer. Exemplary server which validates those signatures is available here.