This page explains in detail how Authentication is done against your integration:
Explanation of the Request Signing process
The Manifold libraries supporting request verification
The Manifold Request signing Algorithm
Request verification guidelines
The Manifold Public Key
In order to provision, deprovision, or resize resources and credentials Manifold performs HTTP calls against the Provider's API implemented by your integration. All requests sent by Manifold are signed, allowing a Provider to validate that the requests were made by Manifold.
The signature of the request is relayed in the X-Signature
header. This header contains the signature of the request, the public key of the ed25519 keypair used to sign the request, and the signature of this public key signed by the Manifold master offline signing key.
This provides a complete chain of trust from the signature of the request all the way to the root signing key allowing a Provider to verify the integrity and authenticity of the request from Manifold.
Included in the signature is the request method, path, query parameters, various headers (including the Date and Host headers), and the request body.
Requests to GET /v1/sso
are not signed by Manifold. Instead, integrations must validate that the user has access to the resource by requesting GET /v1/resources/:id
from the Connector API using an authorization_code
granted access token.
Manifold provides the following SDKs, making it easy for a Provider to verify any incoming requests from Manifold:
Language | Support | URL |
Go | Manifold | |
Node.js | Manifold | |
Python | Manifold | ​https://github.com/manifoldco/python-manifoldco-signature​ |
Ruby | Manifold | ​https://github.com/manifoldco/ruby-manifoldco-signature​ |
Java | Manifold | |
C# | Manifold | |
Elixir | Manifold | ​https://github.com/manifoldco/elixir-manifoldco-signature​ |
PHP | Community |
Are we missing your language? Do you want us to list your library here? Please contact us.​
Manifold takes two steps to sign all outgoing requests to Provider's integrations:
Create the canonical form of the request.
Sign the request.
lower(METHOD) < space > PATH <'?'> canonical(QUERY)<newline>
Where canonical(QUERY)
contains the query parameters, lexicographically sorted in ascending order (including param name, =
sign, and value), and delimited by an &
. If no query params are set, the ?
after the PATH
is omitted.
Example:
PUT /v1/resources?foo=bar\n
These are the headers listed in the X-Signed-Headers
header, in the order they are listed, followed by the X-Signed-Headers
header itself.
Headers are written in the form:
lower(NAME) <colon> <space> VALUES <newline>
Where VALUES
have all optional whitespace removed. If the header occurs multiple times on the request, the values are included delimited by ,
(comma space), in the order they appear on the request.
The X-Signed-Headers
header includes the list of all headers included in the canonical request form, lowercased, and delimited by a space. Only one occurrence of X-Signed-Headers
should exist on a request. If more than one exists, The first is used.
Manifold includes all headers that are explicitly set on any request we send, including the callback related headers.
Example:
content-type: application/json\n
Append the bytes from the request into the canonical form.
The request signature is created by creating an ed25519 signature of the canonical request form, using a live signing key pair. This key pair's public key is signed by Manifold's offline master key, and the master key signature is included with each signature.
The signature is included in the X-Signature
header, which has the form:
X-Signature: <request_signature> <live_public_key> <master_key_signature>
Verifying a request follows similar steps to signing a request:
Verify the request age.
Create the canonical form of the request. This is identical to the request signing step.
Verify the signature.
To prevent replay attacks, all providers should verify that value relayed within the Date
(RFC3339 Format) header is within 5 minutes of the current time. If it is not, a 401 error should be returned to the caller.
Refer to the request signing step above on how to do this.
To verify a request signature, first verify that the signature of the public key included in the header is valid and signed by Manifold's offline signing key. Then verify that the signature of the request is a valid signature on the canonical form of the request, and that it was signed by the public key included in the X-Signature
header.
The following is the public key used for generating endorsements encoded in base64.
PtISNzqQmQPBxNlUw3CdxsWczXbIwyExxlkRqZ7E690
This key is already included in Manifold's signature checking SDKs.
The Manifold master key was generated using a high quality entropy source on an air-gapped system. Access to the private portion of the key is restricted; 3 of the 5 members of Manifold that have access to it must be present to unencrypt the key (portions of the key are distributed to each member through Shamir's Secret Sharing and uniquely encrypted for each member). The master key is only used to sign live signing keys, which will in turn be used to sign the requests made to provider's integrations.