-
Notifications
You must be signed in to change notification settings - Fork 11
KDS Rest API
This page describes how applications can communicate with the Key Derivation Service (KDS). The KDS exposes an HTTP REST API for deriving public and private keys.
The Key Derivation Service (KDS) supports two endpoints.
You can find the request & response parameters and other details for these endpoints below.
The /public
endpoint accepts a key specification and returns a Curve25519
public key.
PUT /public
Content-Type: application/json
API-VERSION: 1
Request body
{
"name": string,
"masterKeyType": string,
"policyConstraint": string
}
Field | Description |
---|---|
name | A name for the key. The KDS uses the name field to generate unique keys with the same master key and constraint configuration. |
masterKeyType | The type of master key the KDS should use to source the master key. |
policyConstraint | The constraint policy to apply to the key. The KDS will reveal the corresponding private key only to an enclave that meets these constraints. |
Response body
{
"publicKey": string,
"signature": string,
"kdsAttestationReport": string
}
Field | Description |
---|---|
publicKey | A Base64 encoded public key. |
kdsAttestationReport | The EnclaveInstanceInfo of the KDS enclave in Base64. The client should check this to verify the KDS instance that the key came from. |
signature | A signature in Base64 that the caller can use with the kdsAttestationReport to verify that the public key came from the verified KDS instance. This verification is crucial for security reasons. |
curl --location --request POST 'localhost:8090/public' \
--header 'API-version: 1' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "MasterKeyForTesting",
"masterKeyType": "development",
"policyConstraint":"S:4924CA3A9C8241A3C0AA1A24A407AA86401D2B79FA9FF84932DA798A942166D4 PROD:1 SEC:INSECURE"
}'
{
"publicKey": "oCBCwBelzlEOPskvmSF/Dy8uZLPRmssAyjFAXlg4a1I=",
"signature": "8pOGWHJOPJcnE0xO7A4Gf38/b5W1ndlmjpx/nIM8zIG1TNcsn7Es1ZEcSa914SfR1O2aHuv+6LjzfP/dUP0MAA==",
"kdsAttestationReport": "RUlJAAAALDAqMAUGAytlcAMhAOONDzHLUMilE8HfIDnIU6+3iO+x24l29LxuzVyd+RKtAAAAIHHHePxfmrr5h1brrQZQN5+3qkuk4y+LxU3pX5cEsP11AgAAAY0AAAAAYgOK2Sw4VK5IIPM3auay8gNNO3pLSKd4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAcAAAAAAAAA46JQJHO6suPiR3b0zz2/68OefYXXgaKx7MdLexDi9GUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkkyjqcgkGjwKoaJKQHqoZAHSt5+p/4STLaeYqUIWbUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcd1TchJASf1ztwUwtw1fIUL4HgBw6OYCP0nXg8LIBw7KTOCDG8PefON6lPrJ3WrIbJ1WCzE2eqHC2OODODGZMB"
}
!!!Warning
It's critical to ensure the message's integrity and authenticity. You can verify the message by validating the
`kdsAttestationReport` and the signature of the message.
The /private
endpoint retrieves the private key defined by a key specification. It always returns a 32-byte array
that forms the raw key material. You can use this key material directly as an AES256 key or as an input to a
Curve25519 private key generation function.
The KDS enclave returns the private key only if the calling enclave meets the policy requirements defined in the key specification.
Note that the key specification is not encrypted or authenticated. However, if a malicious host modifies the key specification or the constraints, it creates a different derived key. So, any data encrypted by a client using the correct constraint can't be accessed using a tampered key specification.
POST /private
Content-Type: application/json
API-VERSION: 1
Request body
{
"appAttestationReport": string,
"name": string,
"masterKeyType": string,
"policyConstraint": string
}
Field | Description |
---|---|
appAttestationReport | The EnclaveInstanceInfo in Base64 of the application enclave requesting access to the private key. The KDS validates this field against the policy given in the key specification. The KDS returns the private key only if the policy check passes. |
name | A name for the key. The KDS uses the name field to generate unique keys with the same master key and constraint configuration. |
masterKeyType | The type of master key the KDS should use to source the master key. |
policyConstraint | The constraint policy to apply to the key. The KDS will reveal the keys only to an enclave that meets these constraints. |
Response body
{
"kdsAttestationReport": string,
"encryptedPrivateKey": string
}
Field | Description |
---|---|
kdsAttestationReport | The EnclaveInstanceInfo in Base64 of the KDS enclave. The application enclave should validate this report before trusting the private key returned by the KDS enclave. |
encryptedPrivateKey | A Base64 field that contains the private key packaged as a Mail object encrypted using the application enclave's key. The application enclave decrypts the Mail object to extract the private key. The envelope in the Mail object contains the name, masterKeyType, and policyConstraint parameters of the KDS request. These parameters must be checked against the parameters in the original request to verify that the KDS derived the keys correctly. See below for how to deserialize the envelope. |
The envelope in the private key Mail is a byte array structured as below.
[API version] [Name] [Master key type] [Policy constraint]
| | | |
+-------+ +------------------+ +-------+ +------------------+
v v v v v v v v
+---------+--------+-----------+---------+--------+-----------+
| version | length |UTF-8 bytes| type | length |UTF-8 bytes|
+---------+--------+-----------+---------+--------+-----------+
1 byte 4 bytes variable 1 byte 4 bytes variable
(BE) sized field (BE) sized field
The API version field contains the API version used for the request.
The master key type field contains the type ID of the master key used for derivation.
Type ID | Master Key Type |
---|---|
0 | Development |
1 | Cluster |
2 | Azure Key Vault |
curl --location --request POST 'localhost:8090/private' \
--header 'API-VERSION: 1' \
--header 'Content-Type: application/json' \
--data-raw '{
"appAttestationReport": "RUlJAAAALDAqMAUGAytlcAMhAINkJMp+IBZSnSWEY1ux0z/HRfpzllu1I2oT0R6zl82MAAAAIARTUJux1z0gV889af4tL3iOAM300VuZbWppAZLZ/QwzAgAAAY0AAAAAYfK2fykTkGBIIPM3auay8gNNO3pLSKd4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAcAAAAAAAAAWN4G6qxjHqRGYJjDJViSVwClv6xlhw5HtR26hr1swdoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkkyjqcgkGjwKoaJKQHqoZAHSt5+p/4STLaeYqUIWbUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIczKEHJt2DTFS6SfYsgVDWPAMMgy6wnPBhVHs8tfNiZevzUaW2+1dYfm62aUeGmAOI24vKtY++UV6nkTWYWRXcB",
"name": "MasterKeyForTesting",
"masterKeyType": "development",
"policyConstraint": "S:4924CA3A9C8241A3C0AA1A24A407AA86401D2B79FA9FF84932DA798A942166D4 PROD:1 SEC:INSECURE"
}'
{
"kdsAttestationReport": "RUlJAAAALDAqMAUGAytlcAMhAOONDzHLUMilE8HfIDnIU6+3iO+x24l29LxuzVyd+RKtAAAAIHHHePxfmrr5h1brrQZQN5+3qkuk4y+LxU3pX5cEsP11AgAAAY0AAAAAYgOK2Sw4VK5IIPM3auay8gNNO3pLSKd4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAcAAAAAAAAA46JQJHO6suPiR3b0zz2/68OefYXXgaKx7MdLexDi9GUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEkkyjqcgkGjwKoaJKQHqoZAHSt5+p/4STLaeYqUIWbUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcd1TchJASf1ztwUwtw1fIUL4HgBw6OYCP0nXg8LIBw7KTOCDG8PefON6lPrJ3WrIbJ1WCzE2eqHC2OODODGZMB",
"encryptedPrivateKey": "ALcBAAAAAAAAAAAAJDFiNTM5ZmU1LTEwM2ItNGU3Ni04MjA3LTBiMjNmNmZlZjg2YwByAAAAE01hc3RlcktleUZvclRlc3RpbmcBAAAAVlM6NDkyNENBM0E5QzgyNDFBM0MwQUExQTI0QTQwN0FBODY0MDFEMkI3OUZBOUZGODQ5MzJEQTc5OEE5NDIxNjZENCBQUk9EOjEgU0VDOklOU0VDVVJFABJIIPM3auay8gNNO3pLSKd4AAFcCteYfWjtqXiY5X59P7ZeUzAU2plPazMtWQHRDxAIb06QhAIUFdgiCpcj3+3Qhj+lAxtxY0BeWqB6LEhCcaiWlXBzRVgIPhqMCbghpIR2ozj02XlKbqoqT62VvwtJyA2HAFbXt5t8MtPvtIKnQNzahkbcrFtc83TQa9j4zUH+uLfgM69Pb1Lg10VR9V1bwfWYgZ40IrybQkMtFDd132nW8PkIzgDw1xj/uasOMpOZLbdA5xj4w0zT/AASmfjJMsJ+qye6AjAkJllBW7Ow"
}
The endpoints send error responses in the below format:
{
"reason": "The application enclave does not meet the required key policy"
}
Field | Description |
---|---|
reason | Error message. |
Error Response | Reason |
---|---|
400 Bad Request | The request is not formatted correctly. |
404 Not Found | The master key for the given configuration could not be retrieved. |
You can verify the integrity of the public key present in the response as follows:
Create a byte array as described in the diagram below:
[API version] [Name] [Master key type] [Policy constraint] [Public key]
| | | | |
+-------+ +------------------+ +-------+ +------------------+ +--------------------+
v v v v v v v v v v
+---------+--------+-----------+---------+--------+-----------+----------+-----------+
| version | length |UTF-8 bytes| type | length |UTF-8 bytes| length | key bytes |
+---------+--------+-----------+---------+--------+-----------+----------+-----------+
1 byte 4 bytes variable 1 byte 4 bytes variable 2 bytes variable
(BE) sized field (BE) sized field (BE) sized field
The request includes the name, the master key type, and the policy constraint. The public key comes from the response after being decoded from Base64. The API version field contains the API version used for the request.
You can use this data, along with the dataSigningKey
contained in the kdsAttestationReport
from the response, and
the signature
field to check the response integrity.
The API response holds the public key in 44 bytes. The first 12 bytes represent the algorithm identifier as per RFC-8410. The remaining 32 bytes hold the actual public key data.
The key import fails if a library doesn't handle the initial bytes with the algorithm identifier. You can prevent this failure in two ways:
- Slice the byte array, ignore the first 12 bytes, and use the last 32 bytes to read the key.
- Check the first 12 bytes to know if the algorithm is supported, and use the last 32 bytes to read the key.
The integrity check ensures that no one has tampered with the public key inside the response. But it
does not guarantee that the KDS sent the message. To ensure the sender's authenticity, you must validate
the kdsAttestationReport
field in the response.
Note
Java and Kotlin developers can use the [`post office`](api/-conclave%20-core/com.r3.conclave.client/-post-office-builder/using-k-d-s.html)
instead of the `/public` endpoint to retrieve the KDS public keys.