C3 AI Documentation Home

Private and Public Keys

This topic focuses on how to use a CryptoPrivateKey, CryptoPublicKey, and X509Certificate, and how to store them securely.

Private and public keys

In the C3 Agentic AI Platform a private key and public key are mapped to the CryptoPrivateKey and CryptoPublicKey Types.

For more information on the Types that are mixed in below, see the Config & Identifiable C3 AI Types.

The CryptoPrivateKey and CryptoPublicKey Types store the private and public key data for the C3 AI Platform. The X509Certificate Type stores the certificate data for the server. Each of these Types mixes the Config and Identifiable Types so they can also store a unique id and configuration data.

The CryptoCipher and CryptoSignature are two Types to encrypt/decrypt and to sign/verify content.

The CryptoKeyPair contains two properties, the CryptoPrivateKey and CryptoPublicKey. To pair a CryptoPrivateKey and a CryptoPublicKey, make sure they have the same id when configured, so later on using the same id in CryptoKeyPair can automatically pick up the paired CryptoPrivateKey and CryptoPublicKey.

You can also pair a CryptoKeyPair and a X509Certificate with the same mechanism.

Setting the private key

If a user has the correct permissions and the file storing the key exists in a cloud file system already, the Private Key can be set in the following manner:

JavaScript
// see {@link CryptoKeyPair} for more general or type-system-specific information on this.
CryptoPrivateKey.make({
  id: "<key_id>",
  content: "<key_content_in_PEM_encoding>"
}).setSecret();
JavaScript
// url_points_to_file_on_cloudFilesystem: url that looks like: `azure://path/to/file/location/exact-file.xyz` where `xyz`
// is the file format: `.pem`, `.cer`, `.crt`, etc. However, the file content **MUST** be `PEM` encoded, even if the
// file Type is not `.pem`.
CryptoPrivateKey.make({
  id: "<key_id>", 
  fileUrl: "<url_points_to_file_on_cloudFilesystem>"
}).setSecret()
JavaScript
// To set the passphrase protecting the private key, you can provide it when constructing and uploading the private key
// where `passphrase` is the passphrase used to access the key, the `id` can be whichever `id` the developer desires, and
// the `content` is a PEM-encoded string.
CryptoPrivateKey.make({
  id: "<key_id>", 
  content: "<key_content_in_PEM_encoding>", 
  passphrase: "<key_passphrase>"
}).setSecret()

Example

JavaScript
CryptoPrivateKey.make({
  id: "the_id_that_will_be_used_in_the_future_to_reference_this_certificate", 
  content: "very_long_string_that_has_been_pem-encoded", 
  passphrase: "my_passphrase"}).setSecret();

Or you can split them into two API calls:

JavaScript
CryptoPrivateKey.make({
  id: "<key_id>", 
  content: "<key_content_in_PEM_encoding>"
}).setSecret();

CryptoPrivateKey.make({
  id: "<key_id>", 
  passphrase: "<key_passphrase>"
}).setSecret()

Setting the public key or X.509 certificate

JavaScript
CryptoPublicKey.make({
  id: "<key_id>",
  content: "<key_content_in_PEM_encoding>"
}).setConfig();

X509Certificate.make({
  id: "<cert_id>", 
  content: "<key_content_in_PEM_encoding>"
}).setConfig();

Setting a private key at a given override level

By default, the scope/visibility of a private key is in the Application that it is set (for example, setConfig()). If you want to use the same Private Key across multiple Applications or Environments or clusters, you can configure it at a different level/scope depending on your application needs by passing the ConfigOverride argument as an input parameter in the above functions. (Use c3ShowType for more information on how to pass the parameter).

Make sure you don't use the same id for overriding at a different level. The platform can always prefer a smaller scope. For example, if you set the key id in Application1 to be xyz with key content abc for just that Application, then from another Application2 in the same cluster you set the same key id to a different content, def, to be used across the entire cluster, then in Application1 the key with id xyz can still have content of 'abc' rather than def. If you want Application1 to use the more global key value abc, you can simply remove the key with id xyz in Application1 by doing:

JavaScript
CryptoPrivateKey.make({
  id: "<key_id>"
}).clearConfigAndSecretOverride(ConfigOverride.APP)

This scoping of the key allows developers to determine one <key_id> that can be used across all the application code, and then within each USER/Application/Environment/CLUSTER/ETC set the content value of that key.

In this way, configurations can be made at whichever scope the developer wants. For example, you can create a Private Key in the current Environment/CLUSTER for the whole Environment/CLUSTER with the following commands:

JavaScript
CryptoPrivateKey.make({
  id: "<key_id>", 
  content: "<key_content_in_PEM_encoding>"
}).setSecret(ConfigOverride.ENV);

CryptoPrivateKey.make({
  id: "<key_id>", 
  content: "<key_content_in_PEM_encoding>"
}).setSecret(ConfigOverride.CLUSTER);

See ConfigOverride for the full set of scoping options available.

The above also applies to CryptoPublicKey and X509Certificate.

How to retrieve a private key

If a user has the correct permissions, then the Private key entry can be retrieved with the following APIs:

To hold a private key (does not imply the user may see the content or use the key):

JavaScript
CryptoPrivateKey.make({
  id: "<key_id>"
}).getSecret()

To see the field of a key:

JavaScript
// to see the key content in PEM encoding
CryptoPrivateKey.make({
  id: "<key_id>"
}).secretValue("content");

// to see the file url storing the key
CryptoPrivateKey.make({
  id: "<key_id>"
}).secretValue("fileUrl");

// to see the passphrase protecting the key if it has
CryptoPrivateKey.make({
  id: "<key_id>"
}).secretValue("passphrase");

How to assign the correct permissions

If you want certain end users to be able to access the private key and make API calls against an external client, leverage the C3 AI Types (UserGroup, Role, Permission) surrounding the Role-Based Access Control (RBAC) framework.

Was this page helpful?