Skip to main content

Bring your own key (BYOK)

Register, list, update, or delete your customer managed keys (CMKs), associate CMKs with services, and view CMK usage across services in Aiven projects using the Aiven Provider for Terraform, Aiven API, or the Aiven CLI.

important

Bring your own key (BYOK) is a BYOC enterprise feature. Contact Aiven to request access.

Encryption scope

BYOK encrypts the following using your CMKs:

  • Backups: All backups created by Aiven services are encrypted with your CMK.
  • Service data at rest: CMKs protect all data stored by the service.
  • Data in transit between the service and backups: Encryption occurs on the service node before data leaves the cluster, so backup transfers use your CMK.

Prerequisites

  • Key management service (KMS) that supports customer-managed keys in one of the supported cloud providers:
    • Google Cloud KMS: asymmetric RSA 2048 or RSA 4096 keys
    • Oracle Cloud Infrastructure (OCI) Vault: AES keys
    • AWS KMS: symmetric encryption keys (ENCRYPT_DECRYPT)

List CMK accessors

List customer managed key (CMK) accessors - principals that need to be granted access to perform encrypt/decrypt operations on your behalf.

API endpoint

GET /v1/project/PROJECT_ID/secrets/cmks/accessors

Reference: CMKAccessorsList API

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier

Sample request

curl -X GET https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks/accessors \
-H "Authorization: Bearer AIVEN_API_TOKEN"

Sample response

A successful request returns a 200 OK status code and a JSON object with the accessors for each provider, for example:

{
"accessors": {
"gcp": {
"access_group": "access.example.12345678-1234-1234-1234-123456789abc@aiven.io"
},
"oci": {
"access_group": "ocid1.group.oc1..abcdABCD....",
"access_tenant": "ocid1.tenancy.oc1..abcdABCD...."
},
"aws": {
"role_arn": "arn:aws:iam::123456789012:role/aiven-cmk-anchor"
}
}
}
note

Use the accessor values returned by this endpoint when granting Aiven access to your key:

  • Google Cloud KMS: Grant the access_group email address the roles/cloudkms.cryptoOperator role on your key.
  • OCI Vault: Use access_tenant and access_group OCIDs to create cross-tenancy IAM policies.
  • AWS KMS: Use the role_arn as the trusted principal in your KMS key policy (see AWS KMS setup).

Set up customer-managed keys on your cloud provider

Before registering a CMK with Aiven, set up the key and grant Aiven access on your cloud provider.

Google Cloud KMS setup

Create a key ring

gcloud kms keyrings create <keyring-name> \
--location <region> \
--project <your-project>

Create a CryptoKey

gcloud kms keys create <key-name> \
--location <region> \
--keyring <keyring-name> \
--purpose encryption \
--project <your-project>

For HSM-backed keys:

gcloud kms keys create <key-name> \
--location <region> \
--keyring <keyring-name> \
--purpose encryption \
--protection-level hsm \
--project <your-project>

Record the key resource name:

projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<key-name>

Grant Aiven access to your key

  1. Get Aiven's access group email using List CMK accessors.
  2. Grant the Cloud KMS CryptoKey Encrypter/Decrypter role to Aiven's group:
gcloud kms keys add-iam-policy-binding <key-name> \
--location <region> \
--keyring <keyring-name> \
--project <your-project> \
--member "group:<aiven-cmk-group>@aiven.io" \
--role "roles/cloudkms.cryptoKeyEncrypterDecrypter"

Oracle Cloud Infrastructure (OCI) Vault setup

OCI key validation can fail with a generic error when the key region is not available for BYOK. If key validation fails after you confirm the key OCID and IAM policy, contact Aiven support.

Create cross-tenancy IAM policies

  1. Get Aiven's tenancy OCID and group OCID using List CMK accessors. Use OCI access_tenant for <aiven-tenancy-ocid> and OCI access_group for <aiven-cmk-group-ocid>.
  2. Create the policy in the root compartment of your tenancy.
  3. Create cross-tenancy IAM policies in your tenancy to grant Aiven access to the key:
oci iam policy create \
--compartment-id <customer-tenancy-ocid> \
--name aiven-cmk-access \
--statements '[
"define tenancy AT as <aiven-tenancy-ocid>",
"define group AG as <aiven-cmk-group-ocid>",
"admit group AG of tenancy AT to use keys in tenancy"
]'

All three statements are required. Do not remove the define group statement.

Optional: Restrict access to a specific key by adding a condition to the admit statement:

oci iam policy create \
--compartment-id <customer-tenancy-ocid> \
--name aiven-cmk-access \
--statements '[
"define tenancy AT as <aiven-tenancy-ocid>",
"define group AG as <aiven-cmk-group-ocid>",
"admit group AG of tenancy AT to use keys in tenancy where target.key.id = \"<key-ocid>\""
]'

Create a Vault

oci kms management vault create \
--compartment-id <compartment-ocid> \
--display-name <vault-name> \
--vault-type DEFAULT

For HSM-backed vaults:

oci kms management vault create \
--compartment-id <compartment-ocid> \
--display-name <vault-name> \
--vault-type VIRTUAL_PRIVATE

Record the Vault's management endpoint and crypto endpoint.

Create a Master Encryption Key

oci kms management key create \
--compartment-id <compartment-ocid> \
--display-name <key-name> \
--endpoint <vault-management-endpoint> \
--key-shape '{"algorithm": "AES", "length": 32}'

Record the key OCID:

ocid1.key.oc1.<region>.<hash>

AWS KMS setup

Aiven authenticates to your AWS KMS key using cross-account IAM access. You grant access by adding Aiven's IAM role ARN as a trusted principal in your KMS key policy. No resources need to be created in Aiven's AWS account — everything is controlled through your key policy.

Step 1: Create a KMS key

Create a symmetric encryption key in the AWS region where your Aiven services will run:

aws kms create-key \
--description "Aiven CMK for data-at-rest encryption" \
--key-usage ENCRYPT_DECRYPT \
--origin AWS_KMS

Record the key ARN from the output:

arn:aws:kms:<region>:<account-id>:key/<key-id>
aws kms create-alias \
--alias-name alias/aiven-cmk \
--target-key-id <key-id>

Step 3: Grant Aiven access via the key policy

Get Aiven's IAM role ARN using List CMK accessors (role_arn), then update your KMS key policy to allow Aiven to perform encrypt and decrypt operations.

The key policy must include the following statement:

{
"Sid": "Allow Aiven to use this key for CMK operations",
"Effect": "Allow",
"Principal": {
"AWS": "<aiven-role-arn>"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt"
],
"Resource": "*"
}

The full key policy must also retain the root account statement so that your IAM policies can still manage the key:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM policies for key management",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<your-account-id>:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow Aiven to use this key for CMK operations",
"Effect": "Allow",
"Principal": {
"AWS": "<aiven-role-arn>"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt"
],
"Resource": "*"
}
]
}

Apply the key policy:

aws kms put-key-policy \
--key-id <key-id> \
--policy-name default \
--policy file://key-policy.json
note

You can revoke Aiven's access at any time by removing the Aiven principal from the key policy, or by disabling or deleting the key. All KMS operations performed by Aiven are logged in your AWS CloudTrail, giving you a full audit trail.

Manage a project CMK

Use the Aiven Provider for Terraform, Aiven API, or Aiven CLI to manage customer managed keys (CMKs) for encrypting service data.

For per-service CMK assignment and rotation, see Manage service CMK associations.

Register CMK resource identifier

Register a customer managed key resource identifier for an Aiven project.

API endpoint

POST /v1/project/PROJECT_ID/secrets/cmks

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier

Request body parameters

ParameterTypeRequiredDescription
providerStringTrueCloud provider hosting the KMS: gcp, oci, or aws
resourceStringTrueCMK reference (key identifier of max 512 characters). Format depends on provider: GCP resource name, OCI OCID, or AWS KMS key ARN
default_cmkBooleanFalseMark this key as default for new service creation

Sample request (Google Cloud)

curl -X POST https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer AIVEN_API_TOKEN" \
-d '{
"provider": "gcp",
"resource": "projects/aiven-example/locations/us-central1/keyRings/example-keyring/cryptoKeys/example-key",
"default_cmk": true
}'

Sample response (Google Cloud)

A successful request returns a 201 CREATED status code and a JSON object representing the newly registered CMK configuration, for example:

{
"cmk": {
"id": "12345678-1234-1234-1234-12345678abcd",
"provider": "gcp",
"default_cmk": true,
"resource": "projects/aiven-example/locations/us-central1/keyRings/example-keyring/cryptoKeys/example-key",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
}

Sample request (AWS)

curl -X POST https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer AIVEN_API_TOKEN" \
-d '{
"provider": "aws",
"resource": "arn:aws:kms:us-east-1:123456789012:key/mrk-1234abcd12ab34cd56ef1234567890ab",
"default_cmk": true
}'

Sample response (AWS)

{
"cmk": {
"id": "12345678-1234-1234-1234-12345678abcd",
"provider": "aws",
"default_cmk": true,
"resource": "arn:aws:kms:us-east-1:123456789012:key/mrk-1234abcd12ab34cd56ef1234567890ab",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
}

Response fields

ParameterDescription
idIdentifier of the specific key
providerProvider type: gcp, oci, or aws
resourceCMK reference
statusOne of current, old, or deleted
default_cmkWhether this CMK has been marked default for new services
created_atCMK creation timestamp
updated_atCMK update timestamp

Update CMK

Update attributes or parameters on an existing customer managed key configuration.

API endpoint

POST /v1/project/PROJECT_ID/secrets/cmks/CMK_ID

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier
CMK_IDStringTrueCMK identifier

Request body parameters

ParameterTypeRequiredDescription
default_cmkBooleanFalseMark a specific key as default for new service creation

Sample request

curl -X POST https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks/CMK_ID \
-H "Content-Type: application/json" \
-H "Authorization: Bearer AIVEN_API_TOKEN" \
-d '{
"default_cmk": false
}'

Sample response

A successful request returns a 200 OK status code and a JSON object representing the updated CMK configuration, for example:

{
"cmk": {
"id": "12345678-1234-1234-1234-12345678abcd",
"provider": "gcp",
"default_cmk": false,
"resource": "projects/aiven-example/locations/us-central1/keyRings/example-keyring/cryptoKeys/example-key",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
}

Response fields

ParameterDescription
idIdentifier of the specific key
providerProvider type: gcp, oci, or aws
resourceCMK reference
statusOne of current, old, or deleted
default_cmkWhether this CMK has been marked default for new services
created_atCMK creation timestamp
updated_atCMK update timestamp

Get CMK details

Get the details of a customer managed key configuration.

API endpoint

GET /v1/project/PROJECT_ID/secrets/cmks/CMK_ID

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier
CMK_IDStringTrueCMK identifier

Sample request

curl -X GET https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks/CMK_ID \
-H "Authorization: Bearer AIVEN_API_TOKEN"

Sample response (OCI)

A successful request returns a 200 OK status code and a JSON object representing the specified CMK configuration, for example:

{
"cmk": {
"id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
"provider": "oci",
"default_cmk": false,
"resource": "ocid1.key.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
}

Sample response (AWS)

{
"cmk": {
"id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
"provider": "aws",
"default_cmk": false,
"resource": "arn:aws:kms:us-east-1:123456789012:key/mrk-1234abcd12ab34cd56ef1234567890ab",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
}

List CMKs

List all customer managed key configurations for a project.

API endpoint

GET /v1/project/PROJECT_ID/secrets/cmks

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier

Sample request

curl -X GET https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks \
-H "Authorization: Bearer AIVEN_API_TOKEN"

Sample response (OCI)

A successful request returns a 200 OK status code and a JSON object containing a list of all CMK configurations for a project, for example:

{
"cmks": [
{
"id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
"provider": "oci",
"default_cmk": false,
"resource": "ocid1.key.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
},
{
"id": "8c9d0e1f-2a3b-4c5d-6e7f-8a9b0c1d2e3f",
"provider": "oci",
"default_cmk": false,
"resource": "ocid1.key.oc1.phx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"status": "old",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
]
}

Remove CMK

Delete a customer managed key configuration.

note

You can delete a CMK only when it has no service associations in active, activating, or deactivating status. Move each linked service to another CMK or remove the CMK association before deletion.

API endpoint

DELETE /v1/project/PROJECT_ID/secrets/cmks/CMK_ID

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier
CMK_IDStringTrueCMK identifier

Sample request

curl -X DELETE https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks/CMK_ID \
-H "Authorization: Bearer AIVEN_API_TOKEN"

Sample response (OCI)

A successful request returns a 200 OK status code and a JSON object representing the deleted CMK configuration, for example:

{
"cmk": {
"id": "a1b2c3d4-e5f6-4789-a0b1-c2d3e4f5a6b7",
"provider": "oci",
"default_cmk": false,
"resource": "ocid1.key.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"status": "current",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"updated_at": "YYYY-MM-DDTHH:MM:SSZ"
}
}

If the CMK is still associated with one or more services, the request returns 409 Conflict.

{
"message": "CMK cannot be deleted because it is still associated with one or more services"
}

Manage service CMK associations

Associate a specific customer managed key (CMK) with individual services during creation or update. This allows you to use different CMKs for different services, change CMKs for existing services, or remove CMK associations altogether.

Associate a CMK when creating a service

Create a service with a specific CMK by providing the CMK ID in the service creation request.

Set cloud to control the cloud region for the new service.

API endpoint

POST /v1/project/PROJECT_ID/service

Request body parameters

ParameterTypeRequiredDescription
service_nameStringTrueName of the service
service_typeStringTrueType of service (for example, pg, mysql, redis)
planStringTrueService plan
cloudStringFalseCloud region for the service, for example google-europe-west3
cmk_idStringFalseCustomer managed key (CMK) identifier. If omitted, the
project's default CMK is used, or Aiven-managed keys if no default is set.

Sample request

curl -X POST https://api.aiven.io/v1/project/PROJECT_ID/service \
-H "Content-Type: application/json" \
-H "Authorization: Bearer AIVEN_API_TOKEN" \
-d '{
"service_name": "my-pg-service",
"service_type": "pg",
"plan": "startup-4",
"cloud": "google-europe-west3",
"cmk_id": "12345678-1234-1234-1234-12345678abcd"
}'

Sample response

A successful request returns a 201 CREATED status code and a JSON object representing the newly created service with the CMK association:

{
"service": {
"service_name": "my-pg-service",
"service_type": "pg",
"plan": "startup-4",
"cloud_name": "google-europe-west3",
"state": "REBUILDING",
"cmk_id": "12345678-1234-1234-1234-12345678abcd"
}
}

Change or remove the CMK for an existing service

Update a service to use a different CMK or remove its CMK association.

API endpoint

PUT /v1/project/PROJECT_ID/service/SERVICE_NAME

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier
SERVICE_NAMEStringTrueService name

Request body parameters

ParameterTypeRequiredDescription
cmk_idStringFalseCustomer managed key (CMK) identifier to use for this service. Pass an empty UUID (00000000-0000-0000-0000-000000000000) to remove the CMK association and use Aiven-managed keys instead.

Sample request (change CMK)

curl -X PUT https://api.aiven.io/v1/project/PROJECT_ID/service/SERVICE_NAME \
-H "Content-Type: application/json" \
-H "Authorization: Bearer AIVEN_API_TOKEN" \
-d '{
"cmk_id": "87654321-4321-4321-4321-87654321dcba"
}'

Sample request (remove CMK association)

curl -X PUT https://api.aiven.io/v1/project/PROJECT_ID/service/SERVICE_NAME \
-H "Content-Type: application/json" \
-H "Authorization: Bearer AIVEN_API_TOKEN" \
-d '{
"cmk_id": "00000000-0000-0000-0000-000000000000"
}'

Sample response

A successful request returns a 200 OK status code and a JSON object representing the updated service:

{
"service": {
"service_name": "my-pg-service",
"service_type": "pg",
"cloud_name": "google-europe-west3",
"state": "REBALANCING",
"cmk_id": "87654321-4321-4321-4321-87654321dcba"
}
}

View CMK details in service information

When you retrieve service information, the response now includes the cmk_id field showing which CMK is actively protecting that service's data. This allows you to verify encryption key usage and track which services are using which CMKs.

API endpoint

GET /v1/project/PROJECT_ID/service/SERVICE_NAME

Sample request

curl -X GET https://api.aiven.io/v1/project/PROJECT_ID/service/SERVICE_NAME \
-H "Authorization: Bearer AIVEN_API_TOKEN"

Sample response

The service details now include the cmk_id field:

{
"service": {
"service_name": "my-pg-service",
"service_type": "pg",
"plan": "startup-4",
"cloud_name": "google-europe-west3",
"state": "RUNNING",
"cmk_id": "12345678-1234-1234-1234-12345678abcd"
}
}

If the service is not using a CMK, the cmk_id field is null:

{
"service": {
"service_name": "my-mysql-service",
"service_type": "mysql",
"plan": "startup-4",
"cloud_name": "google-europe-west3",
"state": "RUNNING",
"cmk_id": null
}
}

List services associated with a CMK

Find all services in a project that are using a specific customer managed key. This is useful for auditing, capacity planning, or managing CMK usage across your infrastructure.

API endpoint

GET /v1/project/PROJECT_ID/secrets/cmks/CMK_ID/service_associations

Path parameters

ParameterTypeRequiredDescription
PROJECT_IDStringTrueProject identifier
CMK_IDStringTrueCMK identifier

Sample request

curl -X GET https://api.aiven.io/v1/project/PROJECT_ID/secrets/cmks/CMK_ID/service_associations \
-H "Authorization: Bearer AIVEN_API_TOKEN"

Sample response

A successful request returns a 200 OK status code and a JSON object containing a list of services associated with the CMK:

{
"service_associations": [
{
"service_name": "my-pg-service",
"status": "active"
},
{
"service_name": "my-kafka-cluster",
"status": "activating"
}
]
}

Response fields

FieldDescription
service_nameName of the service using this CMK
statusAssociation status: active (service is actively using the CMK), or activating (service is in the process of transitioning to use this CMK)

The response includes services currently associated with the CMK, including services in transition (activating) and services already using the CMK (active). Services not associated with the specified CMK are not included.

note

If a CMK has no associated services, the service_associations array is empty.