Contract Negotiation
This page aims to explain the process of automatic Contract negotiation within GAIA-X-Med and how it can be influenced by Providers.
Overview
A Contract goes through various steps during its formation: Based on a Contract Template, a Consumer creates a Contract Offer, which becomes a Notarized Contract Offer during negotiation and finally the Contract itself after a successful negotiation.
The latter three are all based on Verifiable Credentials and Verifiable Presentations, so a basic understanding of those is recommended when reading this page.
Contract Template
When a Provider wishes to publish a Service inside GAIA-X-Med, they have to create a Service Offering, which is metadata that describes the Service (also known as a Self-Description in Gaia-X terms).
Part of the Service Offering is the Contract Template, which defines the parameters upon which Contracts for this Service are based. It consists of the following properties:
The contract terms. This is static, free-form text that will be displayed to a Consumer before negotiation, and the Consumer is required to activate a checkbox stating that they agree to these.
The URL of the Contract Service that is responsible for handling negotiation requests for this Service.
The validity time of Contracts, starting from their creation. This can be set to indefinite to allow for non-expiring Contracts.
Finally, the contract’s Negotiable Terms and, optionally, a Consumer Filter. These will be explained in more detail below.
Negotiable Terms
The aforementioned terms inside the Contract Template are static, non-negotiable agreements that every Consumer has to accept if they want to use the Service. They are furthermore in plain text, i.e. not machine readable, meaning it is impossible for a service to parse and/or negotiate these terms.
As a compromise, we offer the machine-readable Negotiable Terms as part of a Contract Template. These are expressed as JSON Schema and describe the configurable or negotiable parts of a Contract. They can be automatically parsed and validated by the Contract Service, and it can be configured to automatically accept or deny them based on custom logic.
In the Catalog frontend, the Negotiable Terms will be parsed and presented to the Consumer as a form they can adjust. The resulting form data will become part of the negotiation, and can be used to configure the Service Offering for the Consumer, within limits defined by the Provider.
Furthermore, the Provider could use these Negotiable Terms to calculate e.g. pricing or resource limits.
Negotiable Terms Example
The Milestone 2 Demonstrator is an image gallery service. It can allow certain Consumers to upload a set number of images. Both the upload permission and the image capacity are negotiable terms for the Contract.
The Negotiable Terms JSON Schema, which is part of the Demonstrator’s Service Offering, therefore is as follows:
{
"type": "object",
"required": [
"enableUpload",
"maxImages"
],
"properties": {
"enableUpload": {
"type": "boolean",
"description": "Enable upload of images"
},
"maxImages": {
"type": "number",
"description": "Maximum number of images to upload",
"minimum": 0,
"maximum": 10
}
}
}
This schema mandates that a Consumer can decide whether or not to enable the image uploading capabilities (enableUpload
) as well as to choose a limit of how many images they are allowed to store, from 0 to 10 (maxImages
). If the Demonstrator was a paid service, the Consumer might be charged more depending on how many images they want to be able to store on the service.
In the Catalog, this will be rendered into a form. The Consumer might fill it out like this:
Their choices will be rendered into the following Consumer’s Terms, and sent as part of the negotiation:
{
"enableUpload": true,
"maxImages": 5
}
Note that the resulting object is based on the JSON Schema specified through the Negotiable Terms. This is important, as the Contract Service will later check whether this object validates against that schema.
Consumer Filter
The Consumer Filter is provided as a means to filter out potential Consumers before the negotiation even begins.
Similar to Negotiable Terms, the Consumer Filter is a JSON Schema object embedded in the Contract Template. The Claims of a Consumer’s Credential are validated against this schema, and if the validation fails, the Negotiation will not proceed.
Note
The GAIA-X-Med Catalog will also perform this check and give appropriate feedback to potential Consumers if Negotiation will not be possible. However, this check is done client-side only, so Negotiation requests might still be sent to (knowingly) oblivious Consumers. In any case, the Contract Service will check the Filter again during negotiation.
Consumer Filter Example
The following Consumer Filter will set a strict requirement of the Consumer’s headquarter address to be situated in DE-SH
(Schleswig-Holstein, Germany):
{
"properties": {
"gx:headquarterAddress": {
"type": "object",
"properties": {
"gx:countrySubdivisionCode": {
"type": "string",
"const": "DE-SH"
}
}
}
}
}
Consumer’s Contract Offer
A Contract Offer is a Verifiable Credential created by a Consumer. It is created based on the Contract Template of a Service Offering, and is what initiates the negotiation process. Essentially, it’s a Consumer’s formalized statement that they wish to request to sign a Contract for using a Service.
It contains the following information:
The identity (DID URL) of the Consumer,
The identity (DID URL) of the Service they wish to form a Contract about,
A Boolean value that specifies if they agree to the static Contract terms, and
The Consumer’s Terms, which is the data from the form created from the Negotiable Terms (see above).
This data is compiled into a Verifiable Credential, signed with the Consumer’s private key and then sent to the Negotiation Service, which continues with the negotiation process.
Notarized Contract Offer
After receiving a Contract Offer from an authorized Consumer, the Negotiation Service proceeds to wrap it inside a Notarized Contract Offer, but not before performing a few checks:
Is the Consumer authorized, compliant and does their identity match the one specified in the Contract Offer?
Is the Service Offering specified in the Contract Offer valid, compliant and does it have a valid entry in the Catalog?
Is the Contract Offer itself syntactically and authentically valid?
If all these checks pass, a Negotiation Credential is created with its state set to pending
, and both it and the Contract Offer is compiled into a Notarized Contract Offer Verifiable Presentations signed by the Negotiation Service.
The Negotiation Credential is a formal statement by the Negotiation Service that it has seen the Consumer’s Contract Offer in its current state. Furthermore, it effectively renders the contents immutable by adding its own signature. This basically makes the Negotiation Service act as a notary between the Consumer and the Provider during the negotiation process.
From the Service Offering Credential, the Negotiation Service reads the URL of the Contract Service that is responsible for handling negotiation for this Service, and subsequently sends it there.
Contract Service negotiation handling
The Contract Service that is hosted inside the Provider’s infrastructure receives incoming negotiation requests that carry a Notarized Contract Offer from the Negotiation Service.
It either accepts or rejects incoming Contract Offers by performing a series of steps, some of which can be configured by a Provider to implement their desired negotiation logic.
Sanity checks
Basic sanity checks come first, which are similar to those the Negotiation Service also performed:
Does this Notarized Contract Offer come from a trusted Negotiation Service instance?
Is the Consumer a valid and compliant Participant?
Is the requested Service valid and compliant?
Does the Consumer already have a Contract that is currently valid? (i.e., can the Consumer already use the Service at this point in time?)
The first step is necessary because the Contract Service endpoint receiving incoming Contract Offers is public, but not secured through authentication. Therefore, the Contract Service is configured to only accept signed requests from a whitelisted set of Negotiation Service identities, which can be securely verified through standard Verifiable Credential mechanisms.
Apply Consumer Filter
The Consumer’s Credentials will be validated against the Consumer Filter to prevent Consumers who are not authorized to form a Contract to proceed with the negotiation. The Consumer will be informed of any validation errors.
Validate Negotiable Terms
Next, the Consumer’s Terms are validated against the Negotiable Terms, i.e. if they match the JSON Schema. Even though the Catalog web app prevents invalid data from being entered, it can’t stop the Consumer from manipulating the form through e.g. DOM editing, or from submitting an invalid Contract Offer through the Catalog API.
Evaluate custom negotiation logic
Finally, the Contract Service executes the custom negotiation logic specified by the Provider. While all previous checks did not check the semantics of the Contract Offer, this is where the Provider can influence the negotiation process by implementing custom logic.
The Provider can write code that rejects or accepts the negotiation based on certain properties of either the Consumer’s Terms or the Consumer’s credentials.
For instance, following our example above, the Provider could mandate that only Consumers with an address in Germany are allowed to upload more than 5 images.
Respond to Contract Offer
At the end of the process, the Contract Service now decides whether to accept or reject the Contract Offer. In the latter case, there is also a distinction between a soft reject and a hard reject.
Accepting the Contract Offer
If the decision was made to accept the offer, the Contract Service creates a Contract Offer of its own, the contents of which match the Consumer’s Contract Offer, signaling that the Provider is accepting the terms contained within, and willing to form a Contract with the Consumer.
Soft rejecting the Contract Offer
A soft reject is reached when the Provider is generally willing to form a Contract with the Consumer, but finds their terms inagreeable. In this case, the Contract Service also creates a Contract Offer, but with slightly adjusted terms which will be presented to the Consumer. This conveys a message to the Consumer that if they would be to restart the negotiation process with these terms, it should be accepted by the Provider.
Hard rejecting the Contract Offer
If, on the other hand, the negotiation failed during one of the static checks (in case either Consumer or Service do not have a valid identity, the Consumer’s Terms fail validation against the Negotiable Terms schema, or the offer did not come from a trusted Negotiation Service), the outcome is a hard reject, which simply fails with an appropriate error message. The Consumer is expected to recognize that no Contract will be formed under these conditions, regardless of their Consumer’s Terms.
Contract formation
If the Contract Service responds to the negotiation request with an Accepted Contract Offer (carrying equal terms to the Consumer’s Contract Offer), the negotiation is deemed successful by the Negotiation Service.
It will create a new Negotiation Credential (this time, setting the state to finalized
) and bundle it together with the Consumer’s Contract Offer and the Contract Service’s Accepted Contract Offer into a signed Verifiable Presentation known as the finalized Contract.
Again, the Negotiation Service’s signature notarizes the terms and statements made by both Consumer and Provider, and renders them immutable.
Finishing the process
The finished Contract is then sent to both parties.
Consumer
The Consumer will receive it as a response to the negotiation request they started by submitting their initial Contract Offer, either through the Catalog web interface or via API, and are encouraged to store it.
From this point, the Consumer can expect that they are now allowed to consume the Service in accordance with the negotiated terms. The Catalog will present them with a link to the Service (as specified in the Service Offering Credential) for convenience.
Provider
The Negotiation Service will also send the Contract to the Provider’s Contract Store, which will automatically store it inside its database, allowing the Service Backend to query it upon incoming Consumer requests.
Service Backend hooks
Main article: Hosting your own Service#Service Backend
Furthermore, the Contract Store has the optional functionality of automatically notifying the appropriate Service Backend that a new Contract was formed, by sending the Contract data structure to a configured endpoint.
This feature allows the Service Backend to perform immediate onboarding steps even before the Consumer’s first request to the Service. This could be used, for example, to setup a local user account for the Consumer which stores additional run-time data.
The Consumer can be identified via their unique identity (i.e., their DID URL). It is recommended to use this identifier as a user ID or username, etc. Later, when the Consumer performs a request to the Service, the authentication layer will add this identifier to incoming requests as a request header, allowing the Service Backend to match it up with their local user account.