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:

  1. Creation of a new contract.

  2. Receiving a signature or a rejection.

  3. 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 /
presence

description /
value example

field name

format /
presence

description /
value example

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

"https://company.atlassian.net/wiki"

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"
"signature"
"completion"

Type of this event. One of "creation", "signature" or "completion".

always

"signature"

Signer Object Fields

field name

format /
presence

description /
value example

field name

format /
presence

description /
value example

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

email address

Signer e-mail address.

optional

"richard.roe@gmail.com"

phone

E.164

SMS enable international phone number of a signer.

optional

"+33639987654"

Creation Event Specific Fields

field name

format /
presence

description /
value example

field name

format /
presence

description /
value example

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 /
presence

description /
value example

field name

format /
presence

description /
value example

signer

Signer Object

Signer data of who signed or rejected a contract.

always

 

decision

"signed"
"rejected"

Which decision the signer has made ?

always

"rejected"

Completion Event Specific Fields

field name

format /
presence

description /
value example

field name

format /
presence

description /
value example

decision

"signed"
"rejected"

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.