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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

keyprotect-3.0.1.tar.gz (119.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

keyprotect-3.0.1-py3-none-any.whl (121.0 kB view details)

Uploaded Python 3

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

Hashes for keyprotect-3.0.1.tar.gz
Algorithm Hash digest
SHA256 e4e596aa89bdc5513a6fe3b5ad5593424a4986f6f5497d79306f983106e040eb
MD5 6126123cabb12a3611aea7099f77bffd
BLAKE2b-256 38e2f5c4a6b5b77b981c326eb236ff1c38db418315761d70a5df6f99e9b08091

See more details on using hashes here.

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

Hashes for keyprotect-3.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 42591ee37150cdacfc449eb1ba50b34855f01a0aa931b1b0c228b8e0242287bd
MD5 a4a80e22e2c5e7b0a1719513509e3db5
BLAKE2b-256 cb6174348dea30f8ac974a82d342f913dabc3781fe5e6bc4fa3e14ff8f042f68

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

3.0.1 This release

2 files

2.3.1

2 files

2.2.0

2 files

2.1.0

2 files

2.0.0

2 files

1.0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page