You're viewing **Apigee Edge** documentation.  
[Go to the
**Apigee X** documentation](http://cloud.google.com/apigee/docs/api-platform/publish/create-api-products). info

This document describes how to create, modify, and delete keystores and truststores for Edge
for the Cloud and for Edge for the Private Cloud versions 4.18.01 and later.

> [!NOTE]
> **Note:** For Edge for the Cloud, you must have a cert signed by a trusted entity, such as Symantec or VeriSign. You cannot use a self-signed cert, or leaf certificates signed by a self-signed CA. For information about TLS, see the [TLS/SSL](https://docs.apigee.com/api-platform/system-administration/ssl).

> [!NOTE]
> **Note:** To create keystores and truststores for Private Cloud version 4.17.09 and earlier, see [Create
> keystores and truststores for the Private Cloud 4.17.09 and earlier](https://docs.apigee.com/api-platform/system-administration/create-keystores-and-truststores-private-cloud).

> [!NOTE]
> **Note:** The API examples below make requests to the URL of the Edge management API for the Cloud: `https://api.enterprise.apigee.com`. For Private Cloud installations, replace that URL with `https://MS_IP:8080`, where <var translate="no">MS_IP</var> is the IP address of the Management Server.

> [!CAUTION]
> **Caution:** When an API proxy in Apigee Edge for Public or Private Cloud connects to a target endpoint or target server, Apigee does not by default perform hostname validation for the certificate presented by the target endpoint or target server. To enforce hostname validation, you have the option of applying a configuration at the individual proxy level or setting a flag to enable enforcement for your entire organization. For more information these configuration changes, see [Security Bulletin: GCP-2024-006](https://cloud.google.com/apigee/docs/security-bulletins/security-bulletins).

## Introduction

To configure functionality that relies on public key infrastructure, such as TLS, you need to
create keystores and truststores that provide the necessary keys and digital certificates.

For an introduction to keystores, truststore, and aliases, see
[Keystores and Truststores](https://docs.apigee.com/api-platform/system-administration/keystores-and-truststores).

> [!NOTE]
> **Note:** This document describes how to use APIs to create keystores and truststores for the Edge Cloud. These APIs are not yet available in the Private Cloud. For more on creating keystores and truststores for the Private Cloud, see [Create keystores and truststores for the Private Cloud](https://docs.apigee.com/api-platform/system-administration/create-keystores-and-truststores-private-cloud).

## Create a keystore

A keystore is specific to an environment in your organization, for example the test or prod
environment. Therefore, if you want to test the keystore in a test environment before deploying
it to your production environment, you must create it in both environments.

To create a keystore in an environment:

1. Use the API call in this section to create the keystore.
2. Create an alias and upload a cert/key pair to the alias. The way you upload the cert and key is based on the format of the cert/key pair. The following sections describe how to upload each type of cert/key pair: **Note** : We recommend using PEM format for keys and certificates whenever possible. For more information, see [Supported certificate file formats](https://docs.apigee.com/api-platform/system-administration/creating-keystores-and-truststore-cloud-using-edge-ui#supportedcertificateformats).
   - [Upload a cert and key as a JAR
     file](https://docs.apigee.com/api-platform/system-administration/creating-keystores-and-truststore-cloud-using-edge-management-api#createakeystore-uploadacertandkeyasajarfile)
   - [Upload a cert and key as PEM
     files](https://docs.apigee.com/api-platform/system-administration/creating-keystores-and-truststore-cloud-using-edge-management-api#upload-a-cert-and-key-as-pem-files)
   - [Upload a cert and key as a
     PKCS12/PFX file](https://docs.apigee.com/api-platform/system-administration/creating-keystores-and-truststore-cloud-using-edge-management-api#upload-a-cert-and-key-as-a-pkcs12-pfx-file)
   - [Upload a self-signed cert and
     key](https://docs.apigee.com/api-platform/system-administration/creating-keystores-and-truststore-cloud-using-edge-management-api#create-and-upload-a-self-signed-cert-and-key)

To create a keystore specify the keystore name to the [Create a
Keystore or Truststore](https://docs.apigee.com/management/apis/post/organizations/{org_name}/environments/{env_name}/keystores) API. The keystore name can only contain alphanumeric characters:

```
curl -X POST -u orgAdminEmail:password -H "Content-Type: text/xml" \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores \
-d '<KeyStore name="myKeystore"/>'
```

Sample response:

```rust
{
  "certs" : [ ],
  "keys" : [ ],
  "name" : "myKeystore"
}
```

### Upload a cert and key as a JAR file

You must first create a JAR file with your private key, certificate, and a manifest. The JAR
file must contain the following files and directories:

```rust
/META-INF/descriptor.properties
myCert.pem
myKey.pem
```

A keystore JAR can contain just those three files. If you have a certificate chain, all certs
in the chain must be appended into a single PEM file, where the last certificate should be signed
by a root CA. The certs must be appended to the PEM file in the correct order,
with an empty line between each cert, meaning:

```rust
cert -> intermediate cert(1) -> intermediate cert(2) -> ... -> root
```

In the directory containing your key pair and certificate, create a directory called
`/META-INF`. Then, create a file called descriptor.properties in
`/META-INF` with the following contents:

```rust
certFile={myCertificate}.pem
keyFile={myKey}.pem
```

Generate the JAR file containing your key pair and certificate:

```
jar -cf myKeystore.jar myCert.pem myKey.pem
```

Add `descriptor.properties` to
your JAR file:

```
jar -uf myKeystore.jar META-INF/descriptor.properties
```

You can now upload your JAR files that contain a cert and private key by using the [Create an alias from a JAR or PKCS file](https://docs.apigee.com/management/apis/post/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases) API:

```
curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" -F file="@myKeystore.jar" -F password={key_pword} \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?alias={alias_name}&format=keycertjar"
```

where the -F option specifies the path to the JAR file.

In this call, you specify:

- **`alias_name`** - Identifies the certificate and key in the key store. When you create a virtual host, you reference the certificate and key by its alias name.
- **`key_pword`** - The password for the private key. Omit this parameter if the private key has no password.

Verify that your keystore uploaded properly:

```
curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}
```

Sample response:

```rust
{  
 "certs" : [ "myCertificate" ],
 "keys" : [ "myKey" ],
 "name" : "myKeystore"
}
```

### Upload a cert and key as PEM files

Upload PEM files that contain a cert and private key by using the [Create an alias from certificate and key PEM files](https://docs.apigee.com/management/apis/post/organizations/%7Borg_name%7D/environments/%7Benv_name%7D/keystores/%7Bkeystore_name%7D/aliases-0) API:

```
curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" -F keyFile="@server.key" -F certFile="@signed.crt" \
-F password={key_pword} \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?alias={alias_name}&format=keycertfile"
```

where the `-F` option specifies the paths to the PEM files.

In this call, you specify:

- **`alias_name`** - Identifies the certificate and key in the key store. When you create a virtual host, you reference the certificate and key by its alias name.
- **`key_pword`** - The password for the private key. Omit this parameter if the private key has no password.

Verify that your keystore uploaded properly:

```
curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}
```

Sample response:

```rust
{  
 "certs" : [ "myCertificate" ],
 "keys" : [ "myKey" ],
 "name" : "myKeystore"
}
```

### Upload a cert and key as a PKCS12/PFX
file

Upload a PKCS12/PFX file that contains a cert and private key by using the [Create an alias from a JAR or PKCS file](https://docs.apigee.com/management/apis/post/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases) API:

```
curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" \
-F file="@myKeystore.p12" -F password={key_pword} \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?alias={alias_name}&format=pkcs12"
```

where the `-F` option specifies the path to the P12 file.

In this call, you specify:

- **`alias_name`** - Identifies the certificate and key in the key store. When you create a virtual host, you reference the certificate and key by its alias name.
- **`key_pword`** - The password for the private key. Omit this parameter if the private key has no password.

Verify that your keystore uploaded properly:

```
curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}
```

Sample response:

```rust
{  
 "certs" : [ "myCertificate" ],
 "keys" : [ "myKey" ],
 "name" : "myKeystore"
}
```

### Create and upload a self-signed cert and
key

You can use the [Create an alias by generating a self-signed certificate](https://docs.apigee.com/management/apis/post/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases-1) API to create a self-signed cert and
key and upload them to an alias. The following call specifies only the required information to
create the self-signed cert. You can modify this call to add additional information:

```
curl -u orgAdminEmail:password -X POST --header "Content-Type: application/json"  \
-d "{
    "alias": "selfsigned",
    "subject": {
        "commonName": "mycert"
    }
}" \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases?format=selfsignedcert"
```

The response should appear as:

```rust
{
  "alias": "selfsigned",
  "certsInfo": {
    "certInfo": [
      {
        "basicConstraints": "CA:FALSE",
        "expiryDate": 1491497204000,
        "isValid": "Yes",
        "issuer": "CN=mycert",
        "publicKey": "RSA Public Key, 2048 bits",
        "serialNumber": "00:d1:b4:78:e1",
        "sigAlgName": "SHA256withRSA",
        "subject": "CN=mycert",
        "subjectAlternativeNames": [],
        "validFrom": 1459961204000,
        "version": 3
      }
    ],
    "certName": "selfsigned-cert"
  },
  "keyName": "selfsigned"
}
```

## Create a truststore

The APIs that you use to create a truststore is the same as used to create a keystore. The
only difference is that you only upload a cert file, as a PEM file, to the truststore.

If the cert is part of a chain, then you must either upload all certs in the chain separately
to the truststore, or create a single file containing all the certs. You must insert an empty
line between each cert in the file.

If you want to upload multiple self-signed certificates that are not part of a chain, then use the
same technique: if there are multiple certs you want to trust, upload them in a single file.

The final certificate is typically signed by the certificate issuer. For example, in the
truststore, you upload a client certificate,client_cert_1, and the client certificate issuer's
certificate, ca_cert.

During two-way TLS authentication, client authentication succeeds when the server sends
client_cert_1 to the client as part of the TLS handshaking process.

Alternatively, you have a second cert, client_cert_2, signed by the same cert, ca_cert.
However, you do not upload client_cert_2 to the truststore. The truststore still contains
client_cert_1 and ca_cert.

When the server passes client_cert_2 as part of TLS handshaking, the request succeeds. This is
because Edge allows TLS verification to succeed when client_cert_2 does not exist in the
truststore but was signed by the a cert that exists in the truststore. If you remove the CA
certificate, ca_cert, from the truststore then TLS verification fails.

Create an empty truststore in the environment by using [Create a
Keystore or Truststore](https://docs.apigee.com/management/apis/post/organizations/{org_name}/environments/{env_name}/keystores), the same API that you use to create a keystore:

```
curl -u orgAdminEmail:password -X POST -H "Content-Type: text/xml" \
-d '<KeyStore name="myTruststore"/>' \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores
```

After you create the truststore, upload the certificate as a PEM file to the truststore by
using the [Create an alias from a certificate PEM file](https://docs.apigee.com/management/apis/post/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases-2) API:

```
curl -u orgAdminEmail:password -X POST -H "Content-Type: multipart/form-data" -F certFile="@cert.pem" \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/myTruststore/aliases?alias=myTruststore&format=keycertfile"
```

where the `-F` option specifies the path to the PEM file.

## Get details about an existing
keystore or truststore

Check your environment for any existing keystores by using the [List Keystores
and Truststores](https://docs.apigee.com/management/apis/get/organizations/{org_name}/environments/{env_name}/keystores) API:

```
curl -u orgAdminEmail:password -X GET \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores
```

For cloud customers, a default keystore is provided for free trial organizations in both the
test and prod environments. You should see the following results for this call for both
environments:

```rust
[ "freetrial" ]
```

You can use this default keystore to test your APIs, and push your APIs to production, but you
typically create your own keystore, with your own cert and key, before you deploy to
production.

For Private Cloud customers, the returned array is empty until you create your first
keystore.

Check the contents of the keystore by using the [Get a Keystore or Truststore](https://docs.apigee.com/management/apis/get/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}) API. For a cloud customer, you should see a single server TLS
certificate--the default certificate that Apigee Edge provides for free trial accounts.

```
curl -u orgAdminEmail:password -X GET\
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/freetrial
```

The response should appear as:

```rust
{
 "certs" : [ "wildcard.apigee.net.crt" ],
 "keys" : [ "freetrial" ],
 "name" : "freetrial"
}
```

## Get details about an alias

Get a list of all aliases for a keystores by using the [List aliases](https://docs.apigee.com/management/apis/get/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases) API:

```
curl -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases"
```

The response should appear as:

```rust
[
  "alias1",
  "alias2",
  "alias3",
]
```

To get all information about an alias, such as expiration date and issuer, use the [Get alias](https://docs.apigee.com/management/apis/get/organizations/{org_name}/environment/{env_name}/keystores/{keystore_name}/aliases/{alias_name}) API and specify the alias name:

```
curl  -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases/{alias_name}"
```

The response should appear as:

```rust
{
  "alias": "alias1",
  "certsInfo": {
    "certInfo": [
      {
        "basicConstraints": "CA:TRUE",
        "expiryDate": 1459371335000,
        "isValid": "No",
        "issuer": "EMAILADDRESS=foo@bar.com, CN=smg, OU=doc, O=Internet Widgits Pty Ltd, L=noho, ST=Some-State, C=AU",
        "publicKey": "RSA Public Key, 1024 bits",
        "serialNumber": "00:86:a0:9b:5b:91:a9:fe:92",
        "sigAlgName": "SHA256withRSA",
        "subject": "EMAILADDRESS=foo@bar.com, CN=smg, OU=doc, O=Internet Widgits Pty Ltd, L=noho, ST=Some-State, C=AU",
        "subjectAlternativeNames": [],
        "validFrom": 1456779335000,
        "version": 3
      }
    ],
    "certName": "new\-cert"
  },
  "keyName": "newssl20"
}
```

To download the cert for an alias, use the [Export a certificate for an alias](https://docs.apigee.com/management/apis/get/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases/{alias_name}/certificate) API:

```
curl -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/e/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases/{alias_name}/certificate"
```

The response should appear as:

```rust
---BEGIN CERTIFICATE---
MIIDojCCAwugAwIBAgIJAIagm1uRqf6SMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
...
RBUkaTe/570sLHY0tvkIm5tEX36ESw==
---END CERTIFICATE---
```

If you have an expired cert and want to renew it, you can download a Certificate Signing
Request (CSR). You then send the CSR to your CA to obtain a new cert. To generate a CSR for an
alias, use the [Generate a CSR for an alias](https://docs.apigee.com/management/apis/get/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases/{alias_name}/csr) API:

```
curl -u orgAdminEmail:password -X GET \
"https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/{keystore_name}/aliases/{alias_name}/csr"
```

The response should appear as:

```rust
---BEGIN CERTIFICATE REQUEST---
MIIB1DCCAT0CAQAwgZMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRl
...
RF5RMytbkxkvPxIE17mDKJH0d8aekv/iEOItZ+BtQg+EibMUkkjTzQ==
---END CERTIFICATE REQUEST---
```

## Add a cert to a truststore for two-way TLS

When using two-way TLS for **inbound connections**, meaning an API request into Edge,
the truststore contains a cert or CA chain for each client allowed to make requests to Edge.

When you initially configure the truststore, you can add all the certs for the known clients.
However, over time, you might want to add additional certs to the truststore as you add new clients.

To add new certs to a truststore used for two-way TLS:

1. Ensure that you are using a reference to the truststore in the virtual host.
2. Upload a new cert to the truststore as described above in [Create a truststore](https://docs.apigee.com/api-platform/system-administration/creating-keystores-and-truststore-cloud-using-edge-management-api#create-a-truststore).
3. Update the truststore reference to set it to the **same** value.
   This update causes Edge to reload the truststore and the new cert.

   See [Modifying a reference](https://docs.apigee.com/api-platform/system-administration/working-references#modifyingareference) for more.

## Delete a keystore/truststore or alias

You must use caution when deleting a keystore/truststore or alias. If you delete a keystore,
truststore, or alias that is being used by a virtual host, target endpoint, or target server, all
API calls through the virtual host or target endpoint/target server will fail.

Typically, the process you use to delete a keystore/truststore or alias is:

1. Create a new keystore/truststore or alias as described above.
2. For **inbound connections**, meaning an API request into Edge, update the virtual host configuration to reference the new keystore and key alias.
3. For **outbound connections** , meaning from Apigee to a backend server:
   1. Update the TargetEndpoint configuration for any API proxies that referenced the old keystore and key alias to reference the new keystore and key alias. If your TargetEndpoint references a TargetServer, update the TargetServer definition to reference the new keystore and key alias.
   2. If the keystore and truststore are referenced directly from the TargetEndpoint definition, then you must redeploy the proxy. If the TargetEndpoint references a TargetServer definition, and the TargetServer definition references the keystore and truststore, then no proxy redeployment is necessary.
   3. Confirm that your API proxies are functioning correctly.
   4. Delete the keystore/truststore or alias.

See [Update the certificate in an alias](https://docs.apigee.com/management/apis/put/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases/{alias_name}) for more.

### Delete a keystore or truststore

You can delete a keystore or truststore by using the [Delete a Keystore or Truststore](https://docs.apigee.com/management/apis/delete/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}) API:

```
curl -u orgAdminEmail:password -X DELETE \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/myKeystoreName
```

If you delete and recreate a keystore or truststore that is being used by a virtual host, then
you must redeploy your API proxies.

### Delete an alias

You can delete an alias in a keystore or truststore by using the [Delete alias](https://docs.apigee.com/management/apis/delete/organizations/{org_name}/environments/{env_name}/keystores/{keystore_name}/aliases/{alias_name}) API:

```
curl -u orgAdminEmail:password -X DELETE \
https://api.enterprise.apigee.com/v1/o/{org_name}/e/{env_name}/keystores/myKeystoreName/aliases/{alias_name}
```