IBM Cloud Python SDK Version 3.0.1
keyprotect-python-client
A Pythonic client for IBM Key Protect
The client works with Python 3.9 or higher
Installation
The client is available on PyPI as the keyprotect package and is installable via pip:
pip install -U keyprotect
Usage
The following python is a quick example of how to use the keyprotect module.
The example expects IBMCLOUD_API_KEY to be set to a valid IAM API key,
and KP_INSTANCE_ID to be set to the UUID identifying your KeyProtect instance.
import io
import json
import os
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
from keyprotect.ibm_key_protect_api_v2 import IbmKeyProtectApiV2
# ---------------------------------------------------------------------------
# Configuration — set these environment variables before running:
# IBMCLOUD_API_KEY : your IBM Cloud IAM API key
# KP_INSTANCE_ID : the GUID of your Key Protect service instance
# KP_URL (optional) : Key Protect endpoint, defaults to us-south
# ---------------------------------------------------------------------------
API_KEY = os.getenv("IBMCLOUD_API_KEY", <API_KEY>)
INSTANCE_ID = os.getenv("KP_INSTANCE_ID", <INSTANCE_ID>)
KP_URL = os.getenv("KP_URL", "https://us-south.kms.cloud.ibm.com")
# ---------------------------------------------------------------------------
# 1. Build the authenticated service client
# ---------------------------------------------------------------------------
authenticator = IAMAuthenticator(apikey=API_KEY)
kp = IbmKeyProtectApiV2(authenticator=authenticator)
kp.set_service_url(KP_URL)
# ---------------------------------------------------------------------------
# 2. Create a root key (extractable=False makes it a root / non-exportable key)
# ---------------------------------------------------------------------------
key_create_body = {
"metadata": {
"collectionType": "application/vnd.ibm.kms.key+json",
"collectionTotal": 1,
},
"resources": [
{
"type": "application/vnd.ibm.kms.key+json",
"name": "my-sample-root-key",
"description": "Root key created by test.py sample",
"extractable": False, # False == root key (used for wrap/unwrap)
}
],
}
response = kp.create_key(
bluemix_instance=INSTANCE_ID,
key_create_body=io.BytesIO(json.dumps(key_create_body).encode("utf-8")),
prefer="return=representation",
)
key_data = response.get_result().json()
key_id = key_data["resources"][0]["id"]
print(f"[+] Created root key id={key_id}")
# ---------------------------------------------------------------------------
# 3. Wrap a plaintext DEK (data-encryption key) with the root key
# plaintext must be a base64-encoded 128, 192, or 256-bit value.
# Here we supply a 128-bit (16-byte) example; omitting plaintext lets
# Key Protect generate a DEK for you.
# ---------------------------------------------------------------------------
import base64
plaintext_dek = base64.b64encode(b"0123456789abcdef").decode() # 16-byte key → base64
wrap_body = {"plaintext": plaintext_dek}
response = kp.wrap_key(
id=key_id,
bluemix_instance=INSTANCE_ID,
key_action_wrap_body=io.BytesIO(json.dumps(wrap_body).encode("utf-8")),
)
wrap_result = response.get_result().json()
ciphertext = wrap_result["ciphertext"]
print(f"[+] Wrapped ciphertext (first 60 chars): {ciphertext[:60]}…")
# ---------------------------------------------------------------------------
# 4. Unwrap — recover the original plaintext DEK from the ciphertext
# ---------------------------------------------------------------------------
unwrap_body = {"ciphertext": ciphertext}
response = kp.unwrap_key(
id=key_id,
bluemix_instance=INSTANCE_ID,
key_action_unwrap_body=io.BytesIO(json.dumps(unwrap_body).encode("utf-8")),
)
unwrap_result = response.get_result().json()
recovered_plaintext = unwrap_result["plaintext"]
assert recovered_plaintext == plaintext_dek, (
"Unwrapped plaintext does not match original!"
)
print(f"[+] Unwrapped plaintext matches original ✓")
print("Sample complete.")
Using custom endpoint (for HPCS, Private Endpoint, Satellite, and Stage/Test instances)
Custom endpoints are needed when using this Python client against an HPCS/Satellite/Private service instance.
The following example shows how to specify a custom service endpoint
kp = keyprotect.Client(
credentials=tm,
region="<region>",
service_instance_id=os.getenv("KP_INSTANCE_ID"),
# Set custom service endpoint
endpoint_url="https://private.us-south.kms.cloud.ibm.com"
)
Testing
Test Types
The SDK has three test suites:
| Suite | Location |
|---|---|
| Unit tests | test/unit/test_unit_ibm_key_protect_api_v2.py |
| Integration tests | test/integration/test_ibm_key_protect_api_v2.py |
| Example tests | examples/test_ibm_key_protect_api_v2_examples.py |
Setup
This project uses uv for dependency management. Install it if you haven't already:
# macOS (Homebrew)
brew install uv
# or via the installer script
curl -LsSf https://astral.sh/uv/install.sh | sh
Then sync the lockfile to create a virtual environment with all dev dependencies:
uv sync --group dev
Integration & Example Test Environment Setup
Integration and example tests run against test.cloud.ibm.com. Create an
ibm_key_protect_api_v2.env file in the keyprotect-python-client root with
the following values:
IBM_KEY_PROTECT_API_URL=https://qa.us-south.kms.test.cloud.ibm.com
IBM_KEY_PROTECT_API_AUTH_URL=https://iam.test.cloud.ibm.com/identity/token
IBM_KEY_PROTECT_API_AUTH_TYPE=iam
IBM_KEY_PROTECT_API_APIKEY=<your-api-key>
IBM_KEY_PROTECT_API_BLUEMIX_INSTANCE=<your-instance-id>
If your integration or example test file requires unique resource names, assign them manually in the test class setup:
cls.created_keyring_id = "test-keyring"
cls.kmip_name = "test-kmip"
cls.kmip_cert_name = "Test-certificate"
Running Tests
All pytest commands can be run in two ways — pick whichever you prefer:
| Style | When to use |
|---|---|
uv run pytest … |
No need to activate the venv; uv handles it |
source .venv/bin/activate && pytest … |
Activate once, then run pytest directly |
# Run all unit, integration, and example tests
uv run pytest
# Run only unit tests
uv run pytest test/unit/test_unit_ibm_key_protect_api_v2.py
# Run only integration tests
uv run pytest test/integration/test_ibm_key_protect_api_v2.py
# Run only example tests
uv run pytest examples/test_ibm_key_protect_api_v2_examples.py
# Run a specific unit test
uv run pytest test/unit/test_unit_ibm_key_protect_api_v2.py::TestIbmKeyProtectApiV2::<test-name>
# Run a specific integration test
uv run pytest test/integration/test_ibm_key_protect_api_v2.py::TestIbmKeyProtectApiV2::<test-name>
# Run a specific example test
uv run pytest examples/test_ibm_key_protect_api_v2_examples.py::TestIbmKeyProtectApiV2Examples::<test-name>
# Example
uv run pytest test/integration/test_ibm_key_protect_api_v2.py::TestIbmKeyProtectApiV2::test_create_key
# Use -v -rs flags for more verbose output
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keyprotect-3.0.1.tar.gz.
File metadata
- Download URL: keyprotect-3.0.1.tar.gz
- Upload date:
- Size: 119.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4e596aa89bdc5513a6fe3b5ad5593424a4986f6f5497d79306f983106e040eb
|
|
| MD5 |
6126123cabb12a3611aea7099f77bffd
|
|
| BLAKE2b-256 |
38e2f5c4a6b5b77b981c326eb236ff1c38db418315761d70a5df6f99e9b08091
|
File details
Details for the file keyprotect-3.0.1-py3-none-any.whl.
File metadata
- Download URL: keyprotect-3.0.1-py3-none-any.whl
- Upload date:
- Size: 121.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42591ee37150cdacfc449eb1ba50b34855f01a0aa931b1b0c228b8e0242287bd
|
|
| MD5 |
a4a80e22e2c5e7b0a1719513509e3db5
|
|
| BLAKE2b-256 |
cb6174348dea30f8ac974a82d342f913dabc3781fe5e6bc4fa3e14ff8f042f68
|