External Service Provider Reference

The first step in providing external services on 3DIAX is to register a user account. You can do so at https://app.authentise.com/#/register

Once that’s done you will need to send an email to info@authentise.com requesting creation of a provider account. Include your name, company, and the email address you registered your Authentise account with if you are not sending the request from the same email address. This is a manual step we have intentionally included for now so that we can screen new signups - eventually this will be totally automated.

In response to the email you will be given a ‘Group URI’. You’ll use this to register your service.

Registration

Once you have your ‘Provider URI’ you can register your service.

POST https://integrations.authentise.com/service/

Register a new service

Request JSON Object:
 
  • name (string) – Required. The name of the service being provided, such as ‘FixMyPrint magic model healing’. This will be user visible in the services registry.
  • description (string) – A detailed description of the service. This may include brief marketing materials. This will be user visible in the services registry.
  • type – The type of service being provided. Must be one of model-healing, support-generation, slicing, packing, nesting or estimation. New service type will be added as 3DIAX expands.
  • group_uri – This should be the group URI that you were provided with for your organization.
  • service_url – The URL where 3DIAX will POST requests that users make to use the service. The payload will depend on the type of service being registered.
  • service_method – The method that should be used to send the request. This should be the string POST.

Example request

{
    "name"          : "FixMyPrint Magic Model Healing",
    "description"   : "The best model healing you've ever seen. Seriously.",
    "type"          : "model-healing",
    "group_uri"     : "https://users.authentise.com/group/123-abc/",
    "service_url"   : "https://fixmyprint.com/service/repair/?source=3diax",
    "service_method": "POST"
}
Response Headers:
 
  • Location – The URI for the registration where changes can be made. Ex: https://integrations.authentise.com/service/abc-123.
Response JSON Object:
 
  • secret – The shared secret to be used in signing communications between 3DIAX and the provider. Keep it secret. Keep it safe.

The response from the registration will include a Location header for the URI of the service registration along with a shared secret to sign JSON web tokens for communication between 3DIAX and the provider’s service API. The provider should save this secret and protect it.

Listing services

GET https://integrations.authentise.com/service/

List all services. The results returned can be filtered by type by including a filter parameter such as https://integrations.authentise.com/service/filter[type]=model-healing. This will return a list of services that provide model-healing service. The response will be a JSON object with a resources property that contains the list of matching resources.

Response JSON Object:
 
  • resources (jsonlist) – The resources that matched the request.
  • resources.0.uri (string) – The URI of the service resource. This can be used in requests to POST https://integrations.authentise.com/operation/.
  • resources.0.name (string) – The name of the service.
  • resources.0.description (string) – A description of the service. null if none is provided.
  • resources.0.type (string) – The type of service. Will be one of model-healing, support-generation, slicing, packing, nesting, or estimation. New service types will be added as 3DIAX expands.
  • resources.0.service_url (string) – The URL that is used when requests are made to this service by 3DIAX.

User Binding

Some services are free. Some are paid. Whenever 3DIAX makes a request to a service on behalf of a user it will include information about that user. If a user has bound a services’s account information that information will also be included. This can be used to handle billing and access control on the service. Binding a service’s account data to a 3DIAX user’s account is done through this endpoint.

POST https://integrations.authentise.com/bind/
Request JSON Object:
 
  • token (string) – Required. The token that has been generated by the service and given to the user.

The token should be a JSON Web Token https://tools.ietf.org/html/rfc7519. As such, the token value will be three base64-encoded values separated by periods (.). The token should be signed by the service using the shared secret received in the response to the GET https://integrations.authentise.com/service/ endpoint.

A JSON Web Token that is provided to this endpoint should contain a jti field which is just an identifier for the token and has no specific meaning beyond that. The token’s subject (sub) will be a unique ID for the user from the service. We recommend using URIs for this purpose, but it is not required. The token must also contain an issuer field (iss) that will be used to validate the signature. This value should be equal to the service_url provided during registration. Here is an example web token body:

{
    "jti"   : "33bcda06-db84-4aea-8afe-3340ee332342",
    "iss"   : "https://users.authentise.com/group/abc-123/",
    "sub"   : "https://fixmyprint.com/users/42/",
}

Once 3DIAX receives this token from the user to the bind URL above, 3DIAX will ensure the token is valid by verifying its signature. This will use the iss field in the token to look up a shared secret in the database and verify that the signature came from the entity claimed.

Invalid tokens will receive a 403 response with a body that will indicate the exact nature of the failure. On success 3DIAX will store the provided identifier in its user database and supply the identifier for any requests to the service that come from the bound user.

Using a service

In order to start an operation that uses a service from a provider, a user must make a POST request to https://integrations.authentise.com/operation/. The request will include the URI of a service to use for the operation. The request will also include an inputs field that indicates the inputs to the operation that 3DIAX should provide. Each different type of service expects different values for these inputs and will validate them. The request will also include a parameters field that indicates parameters to pass along to the service and are service-specific. 3DIAX will not validate these fields but will return validation errors from the service provider.

POST https://integrations.authentise.com/operation/
Request JSON Object:
 
  • inputs (object) – Required. Input parameters for the job.
  • service (string) – Required. The URI of the service to use for the operation.
  • parameters (object) – Required. Parameters to pass to the service performing the job.
  • callback (object) – Information on where to send HTTP requests when status updates occur.
  • callback.method (string) – The method to use when making the callback request. Should be one of GET or POST
  • callback.url (string) – The URL to use in making the callback request.
Response Headers:
 
  • Location – The URI for the specific service. the user may poll this endpoint for information on the operation as it progresses or to look at historical information on an operation.

An example request may be as follows for the :http:post:`https://integrations.authentise.com/service/model-healing/` endpoint.

POST https://integrations.authentise.com/service/model-healing/
{
    "service"       : "https://users.authentise.com/group/abc-123/",
    "inputs"        : {
        "model"     : "https://models.authentise.com/model/xyz-pdq/",
    },
    "parameters"    : {...imagine service specific paramters here...},
    "callback"      : {
        "method"    : "POST",
        "url"       : "https://my.domain.name/some/url/",
    }
}

Location: https://integrations.authentise.com/operation/111-222/

Any time 3DIAX receives a request from a user to perform an operation via a third-party service 3DIAX will make a signed request to that service. The request will look like the following:

POST https://fixmyprint.com/service/repair/?source=3diax
Content-Type: application/json
Authentication: Bearer <JWT token>
{
    "inputs"        : {
        "model"     : "https://models.authentise.com/model/xyz-pdq/"
    },
    "parameters"    : {...service specific paramters are here...},
    "callback"      : {
        "method"    : "PUT",
        "url"       : "https://integrations.authentise.com/operation/222-333/"
    }
}

The inputs field will be the same inputs provided by the user where the URL will contain HTTP Basic Auth credentials in the URL that should be used to retrieve the contents. The parameters are the same as passed in by the user. The callback is used to indicate how the service should update 3DIAX with any status information about the progress of the operation and will be discussed below.

Like all interactions between 3DIAX and services, the request to perform an operation will include a JSON Web Token (JWT). In this request the JWT will be composed of the following header:

{
    "typ": "JWT",
    "alg": "HS256"
}

This indicates a JWT with an HMAC SHA-256. The body of the token will be as follows:

{
    "jti"   : "a90da99b-c4a5-42f1-97c2-b6e6168b8b6a",
    "iss"   : "https://integrations.authentise.com/",
    "sub"   : "https://fixmyprint.com/users/42/",
    "typ"   : "model-healing",
    "bdy"   : <SHA-256 of the body>,
}

The jti field should be an identifier for the token such as a UUID. The service should use this to ensure a token is not re-used multiple times. The iss field will always be https://integrations.authentise.com/ and identifies the issuer of the token. The sub field will be the user account identifier for the service if one has been bound to the user account via the POST https://integrations.authentise.com/bind/ endpoint. The service can use this for billing, user tracking or other purposes. The typ field identifies the operation to be performed. This is to prevent an attacker from taking a token meant to perform one action and replaying it to perform another. The bdy field is used to validate that the body of the request has not been modified independent of the token. It should contain the SHA-256 hash of the request body.

The body of this token will be signed using the shared secret that was established between 3DIAX and the service via POST https://integrations.authentise.com/service/ request.

The JWT token will be provided in the JWT header. In this case, assuming the shared secret is secret the full request would be:

POST https://fixmyprint.com/service/repair/?source=3diax
Content-Type: application/json
JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhOTBkYTk5Yi1jNGE1LTQyZjEtOTdjMi1iNmU2MTY4YjhiNmEiLCJpc3MiOiJodHRwczovL2ludGVncmF0aW9ucy5hdXRoZW50aXNlLmNvbS8iLCJzdWIiOiJodHRwczovL2ZpeG15cHJpbnQuY29tL3VzZXJzLzQyLyIsInR5cCI6Im1vZGVsLWhlYWxpbmciLCJiZHkiOiJiYTljODZjZDg2NzVlZDg5MmQ4MzI4ZDY5ZWVjZTI0MTI4NTIxZDIxOWU3NmFkODcyZmVkNGJiMTAwYjExNDBiIn0.3jXj1hLDNxJ8kgRPkLJxmo54ofD7d2CL1E5KsprDyQQ
{
    "inputs"        : {
        "model"     : "https://models.authentise.com/model/xyz-pdq/"
    },
    "parameters"    : {
        "strength"  : "maximum"
    },
    "callback"      : {
        "method"    : "POST",
        "url"       : "https://integrations.authentise.com/operation/1f5d384c-1ed1-4da2-bab7-74d556639200/"
    }
}

This was done by taking the body of the request and performing a SHA-256 hash on it. That produced the value ba9c86cd8675ed892d8328d69eece24128521d219e76ad872fed4bb100b1140b. We then create a JWT with the following body:

{
    "jti": "a90da99b-c4a5-42f1-97c2-b6e6168b8b6a",
    "iss": "https://integrations.authentise.com/",
    "sub": "https://fixmyprint.com/users/42/",
    "typ": "model-healing",
    "bdy": "ba9c86cd8675ed892d8328d69eece24128521d219e76ad872fed4bb100b1140b"
}

The JWT signature uses the value secret as the secret to produce the signature. That JWT is then added to the Authentication header.

The service should validate the JWT using the shared secret and validate any inputs and parameters that are provided. They should also validate the SHA-256 of the request body against the value in the JWT token. Any response from the service in the 200 http status code range will indicate success and 3DIAX will pass along a successful message to the user. Reasonable 300-level responses will be honored. 400 and 500 level reponses will be treated as errors and passed back to the user. The following are some guidelines we recommend in these responses:

  • Respond with valid JSON. Include an errors field that is a list of all errors that were encountered. For each error include a machine-readable, stable code and a user-readable title. This is based on recommendations from http://jsonapi.org/, and 3DIAX follows these recommendations in its errors, so keeping your errors consistent will make for a better experience for other developers.
  • Use 400 to indicate the parameters provided are in some way invalid.
  • Use 402 to indicate the user needs to somehow provide payment.
  • Use 401 or 403 to indicate that the user is not authorized to perform the action.

As the service works on the operation it make make various status updates. Only one status update is mandatory. When the operation is complete the service must make a PUT request to the callback URL with a valid JSON body that contains a status property with the value complete. Other properties may be present. This indicates to 3DIAX that the operation is complete and the user will be notified of the same. Any time a service makes a status update to 3DIAX the user who requested the operation will also be notified via their own callback, if they provided one.

Status updates must includes a valid JWT. These tokens should include the standard header:

{
    "typ": "JWT",
    "alg": "HS256"
}

And should also contain a body of the following form:

{
    "jti"   : "edbb698c-92b7-4f17-b73e-bc7f1cf340a6",
    "sub"   : "https://integrations.authentise.com/operation/1f5d384c-1ed1-4da2-bab7-74d556639200/"
    "bdy"   : <SHA-256 of the body>,
}

The jti field is a UUID for the JWT. The sub field identifies the subject of the JWT, in this case the operation that is being updated. The bdy field is the SHA-256 hash of the body of the request. Assuming the shared secret is secret an example callback request would be:

PUT https://integrations.authentise.com/operation/1f5d384c-1ed1-4da2-bab7-74d556639200/
Content-Type: application/json
JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlZGJiNjk4Yy05MmI3LTRmMTctYjczZS1iYzdmMWNmMzQwYTYiLCJzdWIiOiJodHRwczovL2ZpeG15cHJpbnQuY29tL3VzZXJzLzQyLyIsImJkeSI6IjNjNWNkNGFmYjY0YTk3YjgzZmMyMDUxZWE2N2JjZTZiM2M2Mjc0N2M3N2QxNjAxNzQzZDYxNjY0ZTdjZGQyYmUifQ.T7koC7riRLpEOkTDsUnMZ4jjxXcVfSod-padml66NMo

{
    "status": "in-progress"
}

This was calculated with the standard JWT header indicating an HMAC with SHA-256 and a JWT payload of:

{
    "jti"   : "edbb698c-92b7-4f17-b73e-bc7f1cf340a6",
    "sub"   : "https://integrations.authentise.com/operation/1f5d384c-1ed1-4da2-bab7-74d556639200/",
    "bdy"   : "3c5cd4afb64a97b83fc2051ea67bce6b3c62747c77d1601743d61664e7cdd2be"
}

Where 3c5cd4afb64a97b83fc2051ea67bce6b3c62747c77d1601743d61664e7cdd2be is the SHA-256 hash of the body of the request. In this case the callback is specifying that the operation is in the in-progress status. If this value were complete then the operation would be complete.