Complete command reference and usage guide for the IBM Confidential Computing Contract CLI.
The Contract CLI automates the process of generating and managing contracts for provisioning IBM Confidential Computing services including IBM Confidential Computing Container Runtime, IBM Confidential Computing Container Runtime for Red Hat Virtualization Solutions, and IBM Confidential Computing Containers for Red Hat OpenShift Container Platform. It provides a comprehensive set of commands for:
Download the latest release for your platform from the releases page.
# Check version
contract-cli --version
# View available commands
contract-cli --help
OpenSSL is required for all cryptographic operations. The CLI will use the openssl binary from your system PATH.
Installation:
apt-get install openssl or yum install opensslbrew install opensslIf OpenSSL is not in your system PATH, configure the OPENSSL_BIN environment variable:
Linux/macOS:
export OPENSSL_BIN=/usr/bin/openssl
Windows (PowerShell):
$env:OPENSSL_BIN="C:\Program Files\OpenSSL-Win64\bin\openssl.exe"
# 1. Generate RSA key pair
openssl genrsa -out private.pem 4096
# 2. Create your contract YAML
cat > contract.yaml <<EOF
env: |
type: env
logging:
logRouter:
hostname: example.logs.cloud.ibm.com
iamApiKey: your-api-key
workload: |
type: workload
compose:
archive: your-archive
EOF
# 3. Validate the contract
contract-cli validate-contract --in contract.yaml --os hpvs
# 4. Generate signed and encrypted contract
contract-cli encrypt --in contract.yaml --priv private.pem --out encrypted-contract.yaml
Encode text or JSON data to Base64 format. Useful for encoding data that needs to be included in contracts or configurations.
contract-cli base64 [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Input data to encode (text or JSON) (use ‘-‘ for standard input) |
--format |
string | No | Input data format (text or json) |
--out |
string | No | Path to save Base64 encoded output |
-h, --help |
- | No | Display help information |
Basic text encoding:
contract-cli base64 --in "Hello World" --format text
JSON encoding:
contract-cli base64 --in '{"type": "workload"}' --format json
Save to file:
contract-cli base64 --in "Hello World" --format text --out encoded.txt
Using standard input (pipe input):
echo "Hello World" | contract-cli base64 --in - --format text
Generate Base64-encoded tar.gz archive of docker-compose.yaml or pods.yaml. Creates a compressed archive of your container configuration files, encoded as Base64 for inclusion in Confidential Computing contracts. Supports both plain and encrypted output.
contract-cli base64-tgz [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to folder containing docker-compose.yaml or pods.yaml (use ‘-‘ for standard input) |
--output |
string | No | Output type: plain or encrypted (default: plain) |
--cert |
string | No | Path to encryption certificate (uses latest embedded certificate for the provided IBM Confidential Computing platform, if not specified) |
--os |
string | No | Target IBM Confidential Computing platform: ccrt, ccrv, ccco, or hpvs (default: hpvs) |
--ver |
string | No | Specific encryption certificate version (x.x.x). Uses latest version if not specified. Use list-encryptioncert-versions to see available versions |
--out |
string | No | Path to save the output |
-h, --help |
- | No | Display help information |
Plain Base64 archive:
contract-cli base64-tgz --in ./compose-folder
Encrypted archive with latest certificate:
contract-cli base64-tgz --in ./compose-folder --output encrypted
Encrypted archive with custom certificate:
contract-cli base64-tgz \
--in ./compose-folder \
--output encrypted \
--cert encryption.crt
For HPCR-RHVS:
contract-cli base64-tgz \
--in ./pods-folder \
--output encrypted \
--os ccrv
For CCCO:
contract-cli base64-tgz \
--in ./pods-folder \
--output encrypted \
--os ccco
Save to file:
contract-cli base64-tgz --in ./compose-folder --out archive.txt
With specific certificate version:
contract-cli base64-tgz \
--in ./compose-folder \
--output encrypted \
--os ccco \
--ver 1.2.2.1
Using standard input (pipe input):
echo "pods-folder" | contract-cli base64-tgz --in -
Generate a contract YAML template for IBM Confidential Computing deployments. Returns a pre-filled YAML scaffold for the workload section, env section, or a combined contract containing both. Use this as a starting point when authoring a new contract.
contract-cli contract-template [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--type |
string | No | Template type to generate: env, workload, or contract (default: contract) |
--os |
string | No | Target platform (default: hpvs). See OS values table below. |
--out |
string | No | Path to save the generated template (prints to terminal if not specified) |
-h, --help |
- | No | Display help information |
| Value | Platform | Workload template | Env template |
|---|---|---|---|
hpvs |
IBM Hyper Protect Virtual Servers | compose + play + volumes | standard (syslog, env vars, volumes) |
ccrt |
IBM Confidential Computing Container Runtime | compose + play + volumes | standard |
ccrv |
IBM CCRT for Red Hat Virtualization | play only (no compose) | standard |
ccco-peerpod |
IBM CCCO Peer Pod | confidential-containers (no volumes) | logRouter only |
ccco-bmtl |
IBM CCCO Baremetal | confidential-containers + volumes | logRouter + volumes + host-attestation |
Generate combined contract template (default):
contract-cli contract-template
Generate workload-only template:
contract-cli contract-template --type workload
Generate env-only template:
contract-cli contract-template --type env
Generate template for CCRT:
contract-cli contract-template --type contract --os ccrt
Save combined template to file:
contract-cli contract-template --out contract-template.yaml
Generate CCRV workload template:
contract-cli contract-template \
--type workload \
--os ccrv \
--out ccrv-workload-template.yaml
Generate CCCO Peer Pod workload template:
contract-cli contract-template \
--type workload \
--os ccco-peerpod \
--out ccco-peerpod-workload.yaml
Generate CCCO Baremetal combined template:
contract-cli contract-template \
--type contract \
--os ccco-bmtl \
--out ccco-bmtl-contract.yaml
Decrypt encrypted attestation records generated by Confidential Computing instances. Attestation records are typically found at /var/hyperprotect/se-checksums.txt.enc and contain cryptographic hashes for verifying workload integrity.
Optionally verify the signature of decrypted attestation records by providing both --signature and --attestation-cert flags together.
contract-cli decrypt-attestation [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to encrypted attestation file (use ‘-‘ for standard input) |
--priv |
string | Yes | Path to private key used for decryption |
--password |
string | No | Password for encrypted private key |
--out |
string | No | Path to save decrypted attestation records |
--signature |
string | No* | Path to signature file (se-signature.bin) |
--attestation-cert |
string | No* | Path to IBM attestation certificate file (PEM format) |
-h, --help |
- | No | Display help information |
* Both --signature and --attestation-cert must be provided together if signature verification is desired
Decrypt to console:
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private.pem
Decrypt and save to file:
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private.pem \
--out decrypted-attestation.txt
Decrypt and verify signature:
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private.pem \
--signature se-signature.bin \
--attestation-cert hpse-attestation.crt
Decrypt, verify signature, and save to file:
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private.pem \
--out decrypted-attestation.txt \
--signature se-signature.bin \
--attestation-cert hpse-attestation.crt
Using standard input:
cat se-checksums.txt.enc | contract-cli decrypt-attestation \
--in - \
--priv private.pem
Using password-protected private key:
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private-encrypted.pem \
--password "your-secure-password" \
--out decrypted-attestation.txt
Using password from environment variable:
export PRIVATE_KEY_PASSWORD="your-secure-password"
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private-encrypted.pem \
--password "$PRIVATE_KEY_PASSWORD" \
--out decrypted-attestation.txt
Download encryption certificates from the IBM Confidential Computing Repository. Retrieves the latest or specific versions of encryption certificates required for contract encryption and workload deployment.
contract-cli download-certificate [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--version |
strings | Yes | Specific certificate versions to download (comma-separated, e.g., 1.0.21,1.0.22) |
--format |
string | No | Output format for data (json, yaml, or text) |
--out |
string | No | Path to save downloaded encryption certificates |
-h, --help |
- | No | Display help information |
Download latest certificate:
contract-cli download-certificate
Download specific version:
contract-cli download-certificate --version 1.0.23
Download multiple versions:
contract-cli download-certificate --version 1.0.21,1.0.22,1.0.23
Save to file in YAML format:
contract-cli download-certificate \
--version 1.0.23 \
--format yaml \
--out certificates.yaml
Signs a pre-encrypted contract. Accepts either a combined encrypted contract file via
--in, or separate encrypted env and workload files via --env and --workload.
The signing key is always provided via --priv.
contract-cli sign-contract [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | conditional | Path to pre-assembled encrypted contract YAML (env: + workload: keys). Use - for standard input. Mutually exclusive with --env/--workload. |
--env |
string | conditional | Path to file containing the encrypted env section (contract-basic.…). Must be used together with --workload. Mutually exclusive with --in. |
--workload |
string | conditional | Path to file containing the encrypted workload section (contract-basic.…). Must be used together with --env. Mutually exclusive with --in. |
--priv |
string | Yes | Path to private key for signing |
--password |
string | No | Password for encrypted private key |
--out |
string | No | Path to save signed and encrypted contract (prints to stdout if omitted) |
-h, --help |
- | No | Display help information |
Input rules
- Provide either
--inor both--env+--workload— not both groups at once.--envand--workloadmust always be supplied as a pair; providing only one is an error.--privis always required regardless of which input mode is used.- Standard input (
-) is supported only with--in. Pass a full pre-assembled encrypted contract YAML (containing bothenv:andworkload:keys) on stdin.--envand--workloadaccept file paths only and do not support stdin.
Sign a pre-assembled encrypted contract file:
contract-cli sign-contract --in encrypted-contract.yaml --priv private.pem
Sign and save to file:
contract-cli sign-contract \
--in encrypted-contract.yaml \
--priv private.pem \
--out signed-contract.yaml
Sign by providing encrypted env and workload as separate files:
contract-cli sign-contract \
--env encrypted-env.txt \
--workload encrypted-workload.txt \
--priv private.pem \
--out signed-contract.yaml
Sign from separate files — output to stdout:
contract-cli sign-contract \
--env encrypted-env.txt \
--workload encrypted-workload.txt \
--priv private.pem
Using standard input (–in path only):
cat encrypted-contract.yaml | contract-cli sign-contract --in - --priv private.pem
Using password-protected private key:
contract-cli sign-contract \
--in encrypted-contract.yaml \
--priv private-encrypted.pem \
--password "your-secure-password" \
--out signed-contract.yaml
Using password-protected private key with separate env/workload files:
contract-cli sign-contract \
--env encrypted-env.txt \
--workload encrypted-workload.txt \
--priv private-encrypted.pem \
--password "your-secure-password" \
--out signed-contract.yaml
Generate a signed and encrypted contract for IBM Confidential Computing deployment. Supports optional contract expiry for enhanced security.
contract-cli encrypt [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to unencrypted IBM Confidential Computing contract YAML file (use ‘-‘ for standard input) |
--priv |
string | No* | Path to private key for signing |
--password |
string | No | Password for encrypted private key |
--cert |
string | No | Path to encryption certificate (uses latest embedded certificate for the provided IBM Confidential Computing platform, if not specified) |
--os |
string | No | Target IBM Confidential Computing platform: ccrt, ccrv, ccco, or hpvs (default: hpvs) |
--ver |
string | No | Specific encryption certificate version (x.x.x). Uses latest version if not specified. Use list-encryptioncert-versions to see available versions |
--out |
string | No | Path to save signed and encrypted contract |
--contract-expiry |
bool | No | Enable contract expiry feature |
--cacert |
string | No** | Path to CA certificate (required with expiry) |
--cakey |
string | No** | Path to CA key (required with expiry) |
--csr |
string | No** | Path to CSR file (required with expiry) |
--csrParam |
string | No** | Path to CSR parameters JSON |
--expiry |
int | No** | Contract validity in days (required with expiry) |
-h, --help |
- | No | Display help information |
* Generated automatically if not provided
** Required when --contract-expiry is enabled
Basic encryption:
contract-cli encrypt --in contract.yaml --priv private.pem
With custom certificate:
contract-cli encrypt \
--in contract.yaml \
--priv private.pem \
--cert encryption.crt
Save to file:
contract-cli encrypt \
--in contract.yaml \
--priv private.pem \
--out encrypted-contract.yaml
With specific certificate version:
contract-cli encrypt \
--in contract.yaml \
--priv private.pem \
--os ccrt \
--ver 26.2.0
With contract expiry:
contract-cli encrypt \
--contract-expiry \
--in contract.yaml \
--priv private.pem \
--cacert ca.crt \
--cakey ca.key \
--csr csr.pem \
--expiry 90
For CCRV:
contract-cli encrypt \
--in contract.yaml \
--priv private.pem \
--os ccrv
Using password-protected private key:
contract-cli encrypt \
--in contract.yaml \
--priv private-encrypted.pem \
--password "your-secure-password" \
--out encrypted-contract.yaml
For CCCO:
contract-cli encrypt \
--in contract.yaml \
--priv private.pem \
--os ccco
Using standard input:
echo "test-string" | contract-cli encrypt \
--in - \
--priv private.pem
Encrypt strings using the IBM Confidential Computing encryption format. Output format: hyper-protect-basic.<encrypted-password>.<encrypted-string>. Use this to encrypt sensitive data like passwords or API keys for contracts.
contract-cli encrypt-string [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | String data to encrypt (use ‘-‘ for standard input) |
--format |
string | No | Input data format (text or json) |
--cert |
string | No | Path to encryption certificate (uses latest embedded certificate for the provided IBM Confidential Computing platform, if not specified) |
--os |
string | No | Target IBM Confidential Computing platform: ccrt, ccrv, ccco, or hpvs (default: hpvs) |
--ver |
string | No | Specific encryption certificate version (x.x.x). Uses latest version if not specified. Use list-encryptioncert-versions to see available versions |
--out |
string | No | Path to save encrypted output |
-h, --help |
- | No | Display help information |
Encrypt plain text:
contract-cli encrypt-string --in "my-secret-password"
Encrypt JSON:
contract-cli encrypt-string \
--in '{"apiKey": "secret123"}' \
--format json
With custom certificate:
contract-cli encrypt-string \
--in "my-secret" \
--cert encryption.crt
Save to file:
contract-cli encrypt-string \
--in "my-secret" \
--out encrypted-secret.txt
With specific certificate version:
contract-cli encrypt-string \
--in "my-secret-password" \
--os ccrv \
--ver 25.11.0
Using standard input:
# Encrypt echo statement
echo "my-secret-password" | contract-cli encrypt-string --in -
# Encrypt file content
cat workload.yaml | contract-cli encrypt-string --in -
Decrypt encrypted strings in IBM Confidential Computing format using an RSA private key. Supports both contract-basic (CCRT/CCRV/CCCO) and hyper-protect-basic (HPVS) encryption formats.
contract-cli decrypt [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to encrypted input file or encrypted string (use ‘-‘ for standard input) |
--priv |
string | Yes | Path to RSA private key file (PEM format) |
--password |
string | No | Password for encrypted private key |
--out |
string | No | Path to save decrypted output (prints to stdout if omitted) |
-h, --help |
- | No | Display help information |
Decrypt from file, output to stdout:
contract-cli decrypt --in encrypted.txt --priv private.key
Decrypt raw encrypted string:
contract-cli decrypt \
--in "hyper-protect-basic.xxx.yyy" \
--priv private.key
Save decrypted output to file:
contract-cli decrypt \
--in encrypted.txt \
--priv private.key \
--out decrypted.txt
With password-protected private key:
contract-cli decrypt \
--in encrypted.txt \
--priv private.key \
--password "yourpassword"
Using standard input:
cat encrypted.txt | contract-cli decrypt --in - --priv private.key
Extract a specific encryption certificate version from download-certificate output. Parses the JSON output from download-certificate and extracts the certificate for the specified version.
contract-cli get-certificate [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to download-certificate JSON output (use ‘-‘ for standard input) |
--version |
string | Yes | Certificate version to extract (e.g., 1.0.23) |
--out |
string | No | Path to save extracted encryption certificate |
-h, --help |
- | No | Display help information |
Extract specific version:
contract-cli get-certificate \
--in certificates.json \
--version 1.0.23
Save to file:
contract-cli get-certificate \
--in certificates.json \
--version 1.0.23 \
--out cert-1.0.23.crt
Using standard input:
cat "cert.json" | contract-cli get-certificate --in - --version 1.0.23
Retrieve IBM Confidential Computing Container Runtime image details from IBM Cloud. Parses image information from IBM Cloud API, CLI, or Terraform output to extract image ID, name, checksum, and version. Supports filtering by specific version.
contract-cli image [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to IBM Cloud images JSON (from API, CLI, or Terraform) (use ‘-‘ for standard input) |
--version |
string | No | Specific version to retrieve (returns latest if not specified) |
--format |
string | No | Output format for data (json, yaml, or text) |
--out |
string | No | Path to save image details |
-h, --help |
- | No | Display help information |
Get latest image:
contract-cli image --in ibm-cloud-images.json
Get specific version:
contract-cli image \
--in ibm-cloud-images.json \
--version "1.0.23"
Output in YAML:
contract-cli image \
--in ibm-cloud-images.json \
--format yaml
Save to file:
contract-cli image \
--in ibm-cloud-images.json \
--out hpcr-image.json
Using standard input:
cat "ibm-cloud-images.json" | contract-cli image --in -
Fetch OCI image metadata from a container registry and generate a Kubernetes pod YAML template with the correct env, entrypoint, user, and port overrides for use with the registryMapping feature of confidential-containers workload contracts.
The command inspects the image’s USER field and reports it as Image user: <value> before printing the YAML. For numeric UIDs the generated spec includes a securityContext.runAsUser entry. For named users (e.g. postgres) the securityContext is omitted and the name is surfaced only in the header comment # image user: <name>. When the image declares no user at all the output reads Image user: no user specified.
contract-cli image-spec [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Fully-qualified image reference to inspect (e.g. quay.io/fedora/fedora:38) |
--out |
string | No | Path to write the generated pod YAML template (prints to stdout when omitted) |
--username |
string | No | Registry username for private image access |
--password |
string | No | Registry password / API key for private image access |
--container-name |
string | No | Container name in the generated pod spec (default: derived from image name) |
-h, --help |
- | No | Display help information |
Public image with numeric UID (e.g. postgresql-15-c9s uses UID 26):
contract-cli image-spec --in quay.io/sclorg/postgresql-15-c9s:latest
Output:
Image user: 26
# image user: 26
spec:
containers:
- name: postgresql-15-c9s
image: quay.io/sclorg/postgresql-15-c9s:latest
securityContext:
runAsUser: 26
allowPrivilegeEscalation: false
env:
- name: POSTGRESQL_VERSION
value: "15"
...
command:
- container-entrypoint
args:
- run-postgresql
workingDir: /opt/app-root/src
ports:
- containerPort: 5432
protocol: TCP
Image with a named user (e.g. official postgres image uses user “postgres”):
contract-cli image-spec --in docker.io/library/postgres:16 --container-name postgres
Output:
Image user: postgres
# image user: postgres
spec:
containers:
- name: postgres
image: docker.io/library/postgres:16
env:
...
ports:
- containerPort: 5432
protocol: TCP
Note: No
securityContextis emitted for named users because KubernetesrunAsUserrequires an integer. You must resolve the UID manually (e.g. forpostgresthe UID is typically999) and set it in your pod spec.
Image with no user declared:
contract-cli image-spec --in quay.io/fedora/fedora:38
Output:
Image user: no user specified
# image user: no user specified
spec:
containers:
- name: fedora
image: quay.io/fedora/fedora:38
Private registry:
contract-cli image-spec \
--in us.icr.io/my-ns/my-app:latest \
--container-name my-app \
--username iamapikey \
--password <API_KEY>
Save output to file:
contract-cli image-spec \
--in quay.io/sclorg/postgresql-15-c9s:latest \
--out postgres-pod.yaml
List all available embedded encryption certificate versions for IBM Confidential Computing platforms. This command helps you discover which certificate versions are available before using the --ver flag with encryption commands. The embedded certificates are bundled with the CLI and don’t require downloading from IBM Cloud.
contract-cli list-encryptioncert-versions [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--os |
string | No | Filter by platform (ccrt, ccrv, ccco, or hpvs). Shows all platforms if not specified |
--format |
string | No | Output format: json or yaml (defaults to json if not specified) |
--out |
string | No | Path to save output (prints to stdout if not specified) |
-h, --help |
- | No | Display help information |
List all available encryption certificate versions in JSON format (default):
contract-cli list-encryptioncert-versions
Output:
{"ccco":[{"mod":"1.2.2","fixpacks":["1.2.2.1","1.2.2.2"]},{"mod":"1.2.1","fixpacks":[]},{"mod":"1.2.0","fixpacks":[]}],"ccrt":["26.5.0","26.2.0"],"ccrv":["26.4.1","25.11.0"],"hpvs":["26.5.0","26.2.0"]}
Note: CCRT, CCRV and HPVS list the latest three certificate versions as flat lists. CCCO lists the latest three mod releases (
x.x.x), each with its fixpacks (x.x.x.x) grouped under it, with or without--os. A fixpack uses the certificate of its parent mod release.--veraccepts only the versions listed here; any other value returns an error.
List only the CCCO versions (grouped by mod release):
contract-cli list-encryptioncert-versions --os ccco
Output (latest mod release first; --ver accepts any mod or fixpacks value shown):
{"ccco":[{"mod":"1.2.2","fixpacks":["1.2.2.1","1.2.2.2"]},{"mod":"1.2.1","fixpacks":[]},{"mod":"1.2.0","fixpacks":[]}]}
YAML (--format yaml):
ccco:
- mod: 1.2.2
fixpacks:
- 1.2.2.1
- 1.2.2.2
- mod: 1.2.1
fixpacks: []
- mod: 1.2.0
fixpacks: []
Encrypt with a fixpack version (uses the certificate of its parent mod release):
contract-cli encrypt-string --in "my-secret" --os ccco --ver 1.2.2.1
List all available encryption certificate versions in YAML format:
contract-cli list-encryptioncert-versions --format yaml
Output:
ccco:
- mod: 1.2.2
fixpacks:
- 1.2.2.1
- 1.2.2.2
- mod: 1.2.1
fixpacks: []
- mod: 1.2.0
fixpacks: []
ccrt:
- 26.5.0
- 26.2.0
ccrv:
- 26.4.1
- 25.11.0
hpvs:
- 26.5.0
- 26.2.0
List versions for a specific platform in JSON:
contract-cli list-encryptioncert-versions --os ccrt --format json
Output:
{"ccrt":["26.5.0","26.2.0"]}
List versions for HPVS platform in YAML:
contract-cli list-encryptioncert-versions --os hpvs --format yaml
Output:
hpvs:
- 26.5.0
- 26.2.0
Save output to file:
contract-cli list-encryptioncert-versions --os ccrv --format yaml --out ccrv-versions.yaml
--ver flagencrypt - Use --ver flag to specify certificate version for contract encryptionencrypt-string - Use --ver flag to specify certificate version for string encryptionbase64-tgz - Use --ver flag with --output encrypt to specify encryption certificate versionValidate an unencrypted contract against the IBM Confidential Computing schema. Checks contract structure, required fields, and data types before encryption to help catch errors early in the development process.
contract-cli validate-contract [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to unencrypted IBM Confidential Computing contract YAML file (use ‘-‘ for standard input) |
--os |
string | No | Target IBM Confidential Computing platform: ccrt, ccrv, ccco, or hpvs (default: hpvs) |
--type |
string | No | Contract section to validate: workload, env, or '' for both (default: '') |
-h, --help |
- | No | Display help information |
Validate full contract (both sections):
contract-cli validate-contract --in contract.yaml --os ccrt
Validate only the workload section:
contract-cli validate-contract --in contract.yaml --os ccrt --type workload
Validate only the env section:
contract-cli validate-contract --in contract.yaml --os ccrt --type env
Validate CCRV contract:
contract-cli validate-contract --in contract.yaml --os ccrv
Validate CCCO contract:
contract-cli validate-contract --in contract.yaml --os ccco
Using standard input:
cat contract.yaml | contract-cli validate-contract --in - --os ccrt
Validate network-config YAML file against the schema. Validates network configuration for on-premise deployments, ensuring all required fields are present and properly formatted.
contract-cli validate-network [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to network-config YAML file (use ‘-‘ for standard input) |
-h, --help |
- | No | Display help information |
Validate network configuration:
contract-cli validate-network --in network-config.yaml
Using standard input:
cat network-config.yaml | contract-cli validate-network --in -
Validates encryption certificate for on-premise, VPC deployment. It will check encryption certificate validity, ensuring all required fields are present and properly formatted.
contract-cli validate-encryption-certificate [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to encryption certificate file (use ‘-‘ for standard input) |
-h, --help |
- | No | Display help information |
Validate encryption certificate configuration:
contract-cli validate-encryption-certificate --in encryption-cert.crt
Using standard input:
cat encryption-cert.crt | contract-cli validate-encryption-certificate --in -
Generate sealed secrets for IBM Confidential Computing Containers for Red Hat OpenShift Container Platform (CCCO).
contract-cli sealed-secret [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Secret for sealing (provide as string or file path, use '-' for standard input) |
--type |
string | Yes | Type of secret: env for env section of contract or workload for workload section of contract |
--out |
string | No | 1 or 3 comma-separated output file paths (see Output format below). Omit to print JSON to stdout. |
--encryptionkey |
string | No | Path to RSA private key for encryption (generates new key if not provided) |
--signingkey |
string | No | Path to RSA private key for signing (generates new key if not provided) |
-h, --help |
— | No | Display help information |
The --out flag accepts 1 or 3 comma-separated file paths.
The mapping is fixed and positional:
--out <sealed-secret-file>,<decryption-key-file>,<verification-key-file>
position 1 position 2 position 3
sealed value private key public key
⚠️ Order matters. Position 2 is always the private decryption key and position 3 is always the public verification key. Swapping them will cause runtime failures.
1-value form — only the sealed secret file name is given; key files fall back to
sealed_decryption.pem and sealed_verification.pem in the same directory:
| File | Key type | Contents |
|---|---|---|
<your-file> |
— | Sealed secret value for use in the contract |
sealed_decryption.pem |
Private key | RSA private key for decryption — keep secure |
sealed_verification.pem |
Public key | RSA public key for signature verification |
3-value form — all three names are given explicitly:
| Position | File | Key type | Contents |
|---|---|---|---|
| 1 | <sealed-secret-file> |
— | Sealed secret value for use in the contract |
| 2 | <decryption-key-file> |
Private key | RSA private key for decryption — keep secure |
| 3 | <verification-key-file> |
Public key | RSA public key for signature verification |
The terminal always confirms what was written and explicitly labels private vs public:
Sealed value written to: sealed_secret.txt
Decryption key written to: (private) sealed_decryption.pem
Verification key written to: (public) sealed_verification.pem
JSON stdout (when --out is omitted):
{
"sealed_secret": "<sealed-secret-value>",
"decryption_key": "<RSA-private-key-PEM-with-escaped-newlines>",
"verification_key": "<RSA-public-key-PEM-with-escaped-newlines>"
}
| JSON field | Key type | Description |
|---|---|---|
sealed_secret |
— | Sealed secret value for use in the contract |
decryption_key |
Private key | RSA private key for decryption (PEM, \n-escaped) — keep secure |
verification_key |
Public key | RSA public key for signature verification (PEM, \n-escaped) |
Note: PEM newlines are replaced with the literal
\nsequence so the value fits on a single JSON string line. To restore the original PEM for use with OpenSSL:echo '<value>' | sed 's/\\n/\n/g'
1-value form — key files use default names:
contract-cli sealed-secret \
--in "value123" \
--type env \
--out sealed_secret.txt
# sealed_secret.txt ← sealed value
# sealed_decryption.pem ← private key (position 2 default)
# sealed_verification.pem ← public key (position 3 default)
3-value form — all file names explicit:
contract-cli sealed-secret \
--in "value123" \
--type env \
--out sealed_secret.txt,my_decryption.pem,my_verification.pem
# sealed_secret.txt ← position 1 sealed value
# my_decryption.pem ← position 2 private key (keep secure)
# my_verification.pem ← position 3 public key
Generate sealed secret for workload section:
contract-cli sealed-secret \
--in workload-secret-data \
--type workload \
--out sealed_workload.txt,sealed_decryption.pem,sealed_verification.pem
Generate sealed secret from file:
contract-cli sealed-secret \
--in secrets.txt \
--type env \
--out sealed_secret.txt,sealed_decryption.pem,sealed_verification.pem
Generate sealed secret with custom encryption and signing keys:
openssl genrsa -out encryption.pem 2048
openssl genrsa -out signing.pem 2048
contract-cli sealed-secret \
--in "value123" \
--type env \
--encryptionkey encryption.pem \
--signingkey signing.pem \
--out sealed_secret.txt,sealed_decryption.pem,sealed_verification.pem
Read secret from stdin:
echo "value123" | contract-cli sealed-secret \
--in - \
--type env
Print all values as JSON to stdout (omit –out):
contract-cli sealed-secret \
--in "value123" \
--type env
Generate an OPA v1 Rego policy from a Kubernetes pod specification for use with IBM Confidential Computing Containers (CCCO). The generated policy enforces container image and command validation via the Kata Agent Policy engine.
Use --format to control what is written to stdout or to file:
--format |
stdout | with --out |
|---|---|---|
base64 (default) |
prints IBM CC base64 policy only | writes <stem>_base64 only |
text |
prints plain Rego policy only | writes <stem>.rego only |
both |
prints both | writes both files |
No separate base64 encoding step is required.
contract-cli rego-generator [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to Kubernetes resource YAML file (use - for standard input) |
--out |
string | No | Output stem used for file names (e.g. policy or policy.rego). Prints to stdout if not specified. |
--format |
string | No | Output format: base64 (default), text, or both |
-h, --help |
- | No | Display help information |
| Kind | Pod spec location |
|---|---|
Pod |
directly |
Deployment |
spec.template |
StatefulSet |
spec.template |
DaemonSet |
spec.template |
CronJob |
spec.jobTemplate.spec.template |
Files written when --out policy is specified (stem policy):
--format |
Files written |
|---|---|
base64 (default) |
policy_base64 |
text |
policy.rego |
both |
policy.rego + policy_base64 |
The policy_base64 value maps directly to confidential-containers.regoValidator.policy in the contract workload section.
Print only the base64 policy to stdout (default):
contract-cli rego-generator --in pod.yaml
Print only the plain Rego source to stdout:
contract-cli rego-generator --in pod.yaml --format text
Print both the plain Rego source and the base64 policy to stdout:
contract-cli rego-generator --in pod.yaml --format both
Save only the base64 policy to file (default):
# Creates policy_base64 only
contract-cli rego-generator --in pod.yaml --out policy
Save only the plain Rego source to file:
# Creates policy.rego only
contract-cli rego-generator --in pod.yaml --out policy --format text
Save both files (Rego source + base64):
# Creates policy.rego and policy_base64
contract-cli rego-generator \
--in deployment.yaml \
--out policy \
--format both
Generate policy from stdin:
cat pod.yaml | contract-cli rego-generator --in -
End-to-end: generate policy and embed in contract workload section:
# Step 1 — generate the base64 policy file (default format)
contract-cli rego-generator \
--in pod.yaml \
--out policy
# Output:
# Successfully generated Rego policy (base64): policy_base64
# Step 2 — read the ready-to-use base64 value (no manual encoding needed)
POLICY_B64=$(cat policy_base64)
# Step 3 — use in contract workload YAML under confidential-containers.regoValidator.policy
cat <<EOF > workload.yaml
type: workload
confidential-containers:
regoValidator:
policy: ${POLICY_B64}
EOF
Output format: The command outputs a complete OPA v1 Rego policy including:
CreateContainerRequest — wiring rule that requires both allow_image and allow_commandallow_image / allow_command — admits Kata pause/infra containersallow_image() rules — anchored regex per unique imageallow_command() rules — strict (with count(args) and per-index checks) for containers with explicit command/args, permissive (image-only) for ENTRYPOINT-only containersCreate initdata annotation from signed and encrypted contract for IBM Confidential Computing Containers for Red Hat OpenShift Container Platform. Supports both Peer Pod and Baremetal solutions, and optionally embeds extra root certificates into the cdh.toml section.
contract-cli initdata [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--in |
string | Yes | Path to signed & encrypted contract YAML file (use - for standard input) |
--sehdr |
string | No | Path to SE header binary file (.bin) for baremetal solution |
--extra_root_certificates |
string (repeatable) | No | Path to a PEM certificate file to embed in cdh.toml extra_root_certificates. Can be specified multiple times for multiple certs |
--out |
string | No | Path to store gzipped & encoded initdata value |
-h, --help |
- | No | Display help information |
Create initdata for Peer Pod solution:
contract-cli initdata --in signed_encrypted_contract.yaml
Create initdata for Baremetal solution with SE header binary:
contract-cli initdata \
--in signed_encrypted_contract.yaml \
--sehdr se-header.bin \
--out initdata.txt
Embed a single extra root certificate:
contract-cli initdata \
--in signed_encrypted_contract.yaml \
--extra_root_certificates root-ca.pem \
--out initdata.txt
Embed multiple extra root certificates:
contract-cli initdata \
--in signed_encrypted_contract.yaml \
--extra_root_certificates root-ca1.pem \
--extra_root_certificates root-ca2.pem \
--out initdata.txt
Baremetal with SE header and extra root certificates:
contract-cli initdata \
--in signed_encrypted_contract.yaml \
--sehdr se-header.bin \
--extra_root_certificates root-ca1.pem \
--extra_root_certificates root-ca2.pem \
--out initdata.txt
Using standard input:
cat signed_encrypted_contract.yaml | contract-cli initdata --in -
--sehdr, the command generates initdata for baremetal solution--sehdr, the command generates initdata for Peer Pod solution--extra_root_certificates is provided, the certificates are embedded in a cdh.toml entry inside the initdata with an aa.toml entry included automatically--extra_root_certificates can be specified multiple times to include more than one certificateGenerate an OpenSSL RSA key pair or a CA-signed certificate bundle. Produces PEM-encoded artifacts on disk or to stdout.
contract-cli crypto [flags]
| Flag | Type | Required | Description |
|---|---|---|---|
--type |
string | Yes | Generation mode: key for RSA key pair, cert for CA + client certificate bundle |
--out |
string | No | Comma-separated output filenames (see Output filenames below). Prints to stdout when omitted. |
--size |
int | No | RSA key size in bits: 2048, 3072, or 4096 (default: 4096) |
--password |
string | No | Passphrase to encrypt the private key with AES-256 (unencrypted when not specified) |
--san |
string | No | Comma-separated Subject Alternative Names, e.g. example.com,www.example.com,192.168.1.1 (default: example.com, cert only) |
--days |
int | No | Validity period in days. For --type key: when provided, a self-signed X.509 certificate embedding the public key is written to the public key slot instead of a plain public key — giving the key an expiry. Omit (or pass 0) for a plain public key with no expiry. For --type cert: sets the certificate validity period (default: 365). |
--cn |
string | No | X.509 subject Common Name for the client certificate (default: first SAN entry, cert only) |
-h, --help |
— | No | Display help information |
The --out flag accepts comma-separated filenames — one per output file.
The number of accepted values depends on --type:
--type key — up to 2 values:
--out <private-key-file>,<public-key-file-or-cert>
position 1 position 2
When
--daysis not provided, position 2 receives a plain RSA public key. When--days Nis provided, position 2 receives a self-signed X.509 certificate valid for N days — verify withopenssl x509 -in <file> -noout -dates.
| Values provided | Private key file | Public key / certificate file |
|---|---|---|
0 (omit --out) |
stdout | stdout |
1 (--out priv.pem) |
priv.pem |
public.pem (default) + log |
2 (--out priv.pem,pub.pem) |
priv.pem |
pub.pem |
| 3+ | first 2 used | warning logged, extras ignored |
--type cert — up to 3 values:
--out <ca-cert-file>,<client-cert-file>,<client-key-file>
position 1 position 2 position 3
| Values provided | CA cert | Client cert | Client private key |
|---|---|---|---|
0 (omit --out) |
stdout | stdout | stdout |
1 (--out ca.crt) |
ca.crt |
cert.pem (default) + log |
privatekey.pem (default) + log |
2 (--out ca.crt,client.crt) |
ca.crt |
client.crt |
privatekey.pem (default) + log |
3 (--out ca.crt,client.crt,key.pem) |
ca.crt |
client.crt |
key.pem |
| 4+ | first 3 used | warning logged, extras ignored |
Default filenames (used when a slot is not supplied):
| Type | Slot | Default filename |
|---|---|---|
key |
public key | public.pem |
cert |
client cert | cert.pem |
cert |
client private key | privatekey.pem |
File permissions:
| File | Permissions |
|---|---|
| Private key | 0600 (owner read/write only) |
| Public key / certificates | 0644 |
Print key pair to stdout (plain public key, no expiry):
contract-cli crypto --type key
Generate key pair with explicit filenames (plain public key, no expiry):
contract-cli crypto \
--type key \
--size 4096 \
--out mykey_private.pem,mykey_public.pem
Generate key pair with expiry (self-signed certificate in public key slot):
contract-cli crypto \
--type key \
--size 4096 \
--days 365 \
--out my_private.key,my_public.pem
# my_private.key ← RSA private key
# my_public.pem ← self-signed X.509 certificate (valid 365 days)
Verify the expiry of the generated certificate:
# Show notBefore and notAfter dates
openssl x509 -in my_public.pem -noout -dates
# Show only the expiry date
openssl x509 -in my_public.pem -noout -enddate
# Full certificate details (subject, issuer, key size, validity)
openssl x509 -in my_public.pem -noout -text
# Confirm the private key and certificate are a matched pair
openssl x509 -in my_public.pem -pubkey -noout | openssl md5
openssl rsa -in my_private.key -pubout | openssl md5
# Both MD5 hashes must match
Generate key pair with expiry and password protection:
contract-cli crypto \
--type key \
--size 4096 \
--days 365 \
--password "my-passphrase" \
--out private.pem,cert.pem
# private.pem ← AES-256-encrypted RSA private key
# cert.pem ← self-signed X.509 certificate (valid 365 days)
Generate key pair — one name, public key gets default filename:
contract-cli crypto --type key --out mykey_private.pem
# mykey_private.pem ← private key
# public.pem ← public key (default)
Generate password-protected key pair (no expiry):
contract-cli crypto \
--type key \
--size 2048 \
--password "my-passphrase" \
--out private.pem,public.pem
Print certificate bundle to stdout:
contract-cli crypto \
--type cert \
--san "example.com,www.example.com" \
--cn "example.com" \
--days 365
Generate certificate bundle with explicit filenames:
contract-cli crypto \
--type cert \
--san "example.com,192.168.1.10" \
--days 365 \
--out ca.crt,client.crt,client_private.pem
Generate certificate bundle — one name, remaining slots get defaults:
contract-cli crypto --type cert --out ca.crt
# ca.crt ← CA certificate
# cert.pem ← client certificate (default)
# privatekey.pem ← client private key (default)
Generate certificate bundle — two names:
contract-cli crypto --type cert --out ca.crt,client.crt
# ca.crt ← CA certificate
# client.crt ← client certificate
# privatekey.pem ← client private key (default)
Use as input for rsyslog TLS setup:
# Step 1 — generate CA + client cert bundle
contract-cli crypto \
--type cert \
--san "rsyslog.example.com" \
--days 730 \
--out rsyslog-ca.crt,rsyslog-client.crt,rsyslog-client.pem
# Step 2 — reference certs in contract env section
RSYSLOG_CA=$(cat rsyslog-ca.crt)
RSYSLOG_CERT=$(cat rsyslog-client.crt)
RSYSLOG_KEY=$(cat rsyslog-client.pem)
# Step 1: Generate key pair
openssl genrsa -out private.pem 4096
# Step 2: Download encryption certificate
contract-cli download-certificate --version 1.0.23 --out certs.json
contract-cli get-certificate --in certs.json --version 1.0.23 --out cert.crt
# Step 3: Create docker-compose archive
contract-cli base64-tgz --in ./compose-folder --output encrypted --cert cert.crt --out archive.txt
# Step 4: Create contract YAML (with archive from step 3)
cat > contract.yaml <<EOF
env: |
type: env
logging:
logRouter:
hostname: logs.example.com
workload: |
type: workload
compose:
archive: $(cat archive.txt)
EOF
# Step 5: Validate contract
contract-cli validate-contract --in contract.yaml --os hpvs
# Step 6: Generate signed and encrypted contract
contract-cli encrypt --in contract.yaml --priv private.pem --cert cert.crt --out final-contract.yaml
# Decrypt attestation from running instance
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private.pem \
--out attestation.txt
# Decrypt and verify signature
contract-cli decrypt-attestation \
--in se-checksums.txt.enc \
--priv private.pem \
--signature se-signature.bin \
--attestation-cert hpse-attestation.crt \
--out attestation.txt
# View decrypted attestation
cat attestation.txt
# Download all available certificates
contract-cli download-certificate --out all-certs.json
# Extract specific version
contract-cli get-certificate \
--in all-certs.json \
--version 1.0.23 \
--out cert-1.0.23.crt
The CLI supports stdin input (--in -) for all commands, making it easy to integrate into CI/CD pipelines.
name: Generate Contract
on:
push:
branches: [main]
jobs:
generate-contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download contract-cli
run: |
curl -sL https://github.com/ibm-hyper-protect/contract-cli/releases/latest/download/contract-cli-linux-amd64 -o contract-cli
chmod +x contract-cli
- name: Validate contract
run: ./contract-cli validate-contract --in contract.yaml --os hpvs
- name: Generate signed and encrypted contract
run: |
./contract-cli encrypt \
--in contract.yaml \
--priv "$" \
--out encrypted-contract.yaml
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: encrypted-contract
path: encrypted-contract.yaml
#!/bin/bash
set -euo pipefail
# Validate → Encrypt → Deploy pattern
if ! contract-cli validate-contract --in contract.yaml --os hpvs; then
echo "Contract validation failed" >&2
exit 1
fi
contract-cli encrypt \
--in contract.yaml \
--priv private.pem \
--out encrypted-contract.yaml
echo "Contract generated successfully"
| Code | Meaning |
|---|---|
0 |
Success |
1 |
General error (invalid input, missing files, encryption failure, etc.) |
All error messages are written to stderr. Successful output is written to stdout (unless --out is specified).
Error:
Error: openssl binary not found in PATH
Solution:
OPENSSL_BIN environment variable to the full path of OpenSSLError:
Error: contract validation failed
Solution:
validate-contract to see specific schema errorsError:
Error: certificate version not found
Solution:
download-certificate without --version to see available versions1.0.23)Error:
Error: permission denied reading file
Solution:
chmod 600 private.pemSymptom: Commits show Unverified badge on GitHub even after configuring SSH signing locally.
Cause: The SSH key is added to GitHub as an Authentication Key only. GitHub requires a separate Signing Key entry to verify commit signatures.
Solution:
cat ~/.ssh/id_ed25519.pub
Go to GitHub → Settings → SSH and GPG keys → New SSH key
Mac Signing (or any name)Signing Key ← must be Signing Key, not Authentication KeyGitHub will now show Verified on all commits signed with that key — no new push needed.
Note: You can have the same key added twice — once as Authentication Key (for push/pull) and once as Signing Key (for commit verification).
The samples/ directory contains working examples:
Need Help?