-
Notifications
You must be signed in to change notification settings - Fork 11
KDS Configuration
This page describes how to configure an enclave to use the Key Derivation Service (KDS). You can find more information about the architecture of the KDS here.
By default, Conclave persists encrypted data outside the enclave using keys specific to the CPU on which the enclave is running. These CPU-specific keys cause problems for cloud applications where virtual machines may be re-provisioned and moved to different hardware.
In addition to CPU-based keys for storage, Conclave uses random session keys for communication using Conclave Mail. These random session keys cause additional problems for cloud applications to scale horizontally, as the session keys are different for each enclave in the cluster.
The Conclave Key Derivation Service (KDS) is an enclave-based service that solves these problems by allowing Conclave enclaves securely derive stable keys for storage and communication.
There is a publicly accessible instance of the KDS as part of the Conclave Cloud Platform, which any Conclave-based enclave may use. You can also use the development KDS for testing non-production enclaves.
For an enclave to obtain keys from the KDS, you must provide the URL of the KDS instance when you start the enclave.
If the KDS URL is not present in a release mode enclave, Conclave throws an error, and the enclave will not start.
If the KDS URL is not present in a simulation/debug mode enclave, Conclave displays a warning, and the enclave defaults to internally derived keys based on the enclave code signer. This design allows you to develop enclaves without connecting to the KDS.
If you are using the Conclave web host, provide the KDS URL and timeout duration in seconds on the command line when you start your application:
--kds.url=<URL of the KDS instance>
--kds.connection.timeout.seconds=<Count in seconds>
If you are writing a custom host for your enclave or if you're instantiating the enclave as part of an existing project,
you can configure the KDS URL by providing a KDSConfiguration
object when starting the enclave (see EnclaveHost.start
):
import com.r3.conclave.host.kds.KDSConfiguration;
...
KDSConfiguration kdsConfiguration = new KDSConfiguration("https://kds.dev.conclave.cloud");
EnclaveHost enclaveHost = EnclaveHost.load("com.example.MyEnclave");
enclaveHost.start(null, null, null, kdsConfiguration) {}
To use KDS-derived keys for persistent storage, you must specify how the KDS should derive the storage key. You can
configure key specifications on a per-enclave basis. Conclave saves these key specifications in the enclave's
build.gradle
file.
The format of the KDS configuration is as follows:
conclave {
...
kds {
kdsEnclaveConstraint = "<KDS enclave policy constraints>"
persistencekeySpec {
masterKeyType = ("development"|"cluster"|"azure_hsm")
policyConstraint {
constraint = "<key policy constraints>"
useOwnCodeHash = (true|false) // Optional
useOwnCodeSignerAndProductID = (true|false) // Optional
}
}
}
...
}
The kds {}
section contains all KDS-related configurations:
-
kdsEnclaveConstraint
- The constraints that the KDS enclave must match. The enclave will use these constraints to attest to the KDS at the URL provided on startup. -
persististenceKeySpec
- The subsection contains specifications for how the KDS should derive the encrypted storage keys.
-
masterKeyType
- The master key type the KDS should use to derive the key. Supported values aredevelopment
,cluster
andazure_hsm
. See KDS detail for more information about KDS master keys. -
policyConstraint
- The subsection contains the constraints an enclave must meet to access the key generated by the KDS.
-
constraint
- The enclave must meet this policy constraint to derive the key. This subsection has the same format as the enclave constraints DSL, which Conclave uses for attestation. -
useOwnCodeHash
- Use this enclave's code hash. This configuration will add the code hash of the enclave to theconstraint
property at runtime. -
useOwnCodeSignerAndProductID
- Use this enclave's code signer and product ID. This configuration will add the code signer and product ID of the enclave to theconstraint
property at runtime.
The KDS enclave constraint controls how your enclave will attest to the KDS enclave at the URL provided on startup (see enclave constraints).
For the R3 development KDS, use the following constraint:
S:B4CDF6F4FA5B484FCA82292CE340FF305AA294F19382178BEA759E30E7DCFE2D PROD:1 SEC:STALE
.
There are three types of master keys with different trust models:
Master key type | Description |
---|---|
cluster |
A production-ready master key that resides entirely within SGX enclaves. |
azure_hsm |
A production-ready master key which is backed by an Azure Key Vault. The key is end-to-end encrypted. However, users of this key are assuming trust in Microsoft Azure. |
development |
A stable master key which is not suitable for production. You can use it to test KDS integration. Release mode enclaves cannot use this key type. |
For more information on the master key types, see the KDS detail page.
The policyConstraint
section defines which enclaves can access a derived key. It is crucial to choose a constraint
which is:
- Strict enough to prevent unauthorized access to the key.
- Lenient enough to allow data migration and upgrades of enclave code.
See sample configurations here.
The constraint
property of policyConstraint
is similar to the EnclaveConstraint
object, which is used to attest a Conclave enclave.
When the KDS receives a request for a key, the KDS attests that the key policy constraint matches the details of the requesting enclave before releasing a derived key. Just like Conclave attestation, it follows the enclave constraints DSL.
The useOwnCodeHash
and useOwnCodeSignerAndProductID
properties of the policyConstraint
section allow you to
add the code hash or code signer and product ID of the current enclave in the constraint
property. These
parameters cannot be added directly to the constraint
field as their values are unknown at build time.
- The
useOwnCodeHash
property, when set totrue
, will append the current enclave's code hash to the constraint. - The
useOwnCodeSignerAndProductID
property, when set totrue
, will append the current enclave's code signer and product ID to the constraint.
This policy constraint example restricts access to the derived key to release mode enclaves with a specific code hash running on a fully patched and up-to-date SGX-capable host.
kds {
persistenceKeySpec {
policyConstraint {
constraint = "SEC:SECURE"
useOwnCodeHash = true
}
}
}
This is a restrictive policy constraint with significant operational implications.
Due to the code hash requirement, subsequent versions of the enclave will not be able to access persisted data. Also, if the host system is not fully patched, the derived key will not be accessible. The enclave will be denied access to storage keys until patches are installed.
In this slightly less restrictive policy example, access to the derived key is permitted in cases where non-critical security patches are available for the host system.
kds {
persistenceKeySpec {
policyConstraint {
constraint = "SEC:STALE"
useOwnCodeHash = true
}
}
}
This constraint doesn't affect the operational implications of enclave updates because access to the derived key
still requires that the enclave has a specific code hash. However, it gives the enclave host time to patch their
systems to bring them back to the SECURE
state.
In this permissive policy constraint example, access to the derived key is permitted for enclaves with a matching product ID and signing key.
kds {
persistenceKeySpec {
policyConstraint {
constraint = "SEC:STALE"
useOwnCodeSignerAndProductID = true
}
}
}
This constraint has fewer operational implications, as you can update the enclave code without losing access to persisted data. However, security is weakened with this constraint, as the enclave signer must be trusted not to sign an unsafe or malicious enclave.
You can enhance security by engaging an external auditor to build and sign the enclave.
The KDS can provide keys for use with Conclave Mail using the
PostOffice
API.
When using a KDS post office, the post office requests a public key from the KDS for use in a Conclave PostOffice
and specifies which enclaves should be permitted access to the corresponding private key.
Upon receiving Mail, the enclave requests the private key from the same KDS and uses it to decrypt the Mail message
from the client. Users can create Mail messages which any enclave that matches a set of constraints can decrypt
without first having to receive and attest to the EnclaveInstanceInfo
of a specific enclave.
To use KDS keys for Mail, you must configure the kdsEnclaveConstraints
field in the enclave's build.gradle
.
...
conclave {
kds {
kdsEnclaveConstraints = "<KDS enclave policy constraints>"
}
}
...
You can use the following constraints for the R3 development KDS:
S:B4CDF6F4FA5B484FCA82292CE340FF305AA294F19382178BEA759E30E7DCFE2D PROD:1 SEC:STALE
.
The client must construct an appropriately configured PostOffice
object with which to encrypt Mail. The first step is to create a KDSKeySpec
object which specifies how the KDS should derive the public key and which enclaves should have access to the
corresponding private key:
import com.r3.conclave.common.kds.KDSKeySpec;
...
var kdsKeySpec = new KDSKeySpec(
keyName,
masterKeyType,
policyConstraint);
...
-
keyName
- The name of the key. This name is used during key derivation. A change inkeyName
will generate a different key. This can be used to generate separate keys by purpose. -
masterKeyType
- The type of master key to use for the derivation (seeMasterKeyType
). -
policyConstraint
- A string that specifies the constraints the enclave must meet to derive the corresponding private key and decrypt messages. The string should be in the enclave constraints DSL format.
After creating an appropriate key spec, you can instantiate a post office using the usingKDS
method of the PostOfficeBuilder
class.
import com.r3.conclave.client.PostOfficeBuilder;
...
var kdsURL = new URL("<kds-url>");
var kdsEnclaveConstraint = new EnclaveConstraints.parse("<kds-enclave-constraints>");
PostOffice postOffice = PostOfficeBuilder().usingKDS(
kdsURL,
kdsKeySpec,
kdsEnclaveConstraint
).build();
...
-
<kds-url>
is the URL of the KDS instance to use. This URL must match the KDS instance that the enclave is configured for. -
<kds-enclave-constraints>
are the constraints that will be used when attesting to the KDS enclave. These constraints must match the expected details of the KDS.
You can then use the PostOffice
to encrypt
and decrypt messages.