Skip to main content

IBM Cloud Python SDK Version 3.0.1

keyprotect-python-client

PyPi Downloads License Build Status

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

Metadata

Release files for keyprotect 3.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for keyprotect 3.0.1
File Size Uploaded
keyprotect-3.0.1.tar.gz 119.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for keyprotect 3.0.1
File Interpreter ABI Platform
keyprotect-3.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 240.7 kB

Release files / keyprotect-3.0.1.tar.gz

Download URL keyprotect-3.0.1.tar.gz
Size 119.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e4e596aa89bdc5513a6fe3b5ad5593424a4986f6f5497d79306f983106e040eb
BLAKE2b-256 checksum
How to use checksums
38e2f5c4a6b5b77b981c326eb236ff1c38db418315761d70a5df6f99e9b08091
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / keyprotect-3.0.1-py3-none-any.whl

Download URL keyprotect-3.0.1-py3-none-any.whl
Size 121.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
42591ee37150cdacfc449eb1ba50b34855f01a0aa931b1b0c228b8e0242287bd
BLAKE2b-256 checksum
How to use checksums
cb6174348dea30f8ac974a82d342f913dabc3781fe5e6bc4fa3e14ff8f042f68
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

3.0.1 This release

2 release files

2.3.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page