This is a cache of https://developer.ibm.com/tutorials/awb-build-secure-hpvs-attestation-signatures/. It is a snapshot of the page as it appeared on 2025-11-19T04:39:48.250+0000.
Building secure Hyper Protect Virtual Servers workloads with attestation and signature - IBM Developer
This tutorial provides a hands-on walkthrough of Hyper Protect Virtual Servers (HPVS) anti-tamper and attestation features. You’ll learn how contract signing and attestation work together to ensure that only trusted workloads are deployed, even in a zero trust environment. By simulating a tampered contract and observing HPVS behavior, you'll gain a clearer understanding of how these mechanisms protect against unauthorized changes and maintain workload integrity.
Prerequisites
A working HPVS contract that deploys a workload.
The contract should be encrypted, as described in the official documentation
In HPVS, attestation is a process used to verify the integrity of your application stack. It allows you to view and confirm the SHA256 checksums of key components, including:
The original base image
The root partition at first boot
The root partition at build time
Cloud initialization options
Here's a diagram that shows the attestation flow:
In a zero trust system, only the AUDITOR should have access to the private and public key pair used to encrypt and decrypt attestation data. This makes the AUDITOR the only trusted role for verifying integrity.
While an admin deploying the workload can see the contract and figure out the correct SHA256 checksums (for workload, env, etc.), they cannot see the attestation data, because:
The contract is encrypted and only HPCR can decrypt it.
The attestationPublicKey in the contract is used by HPCR to encrypt the attestation data.
Without the corresponding private key, the admin cannot tamper with or fake the attestation.
If the attestation section were missing or unencrypted, a malicious admin could potentially fake the contract and make it look legitimate. Encrypting this section prevents that.
Setting up attestation in the contract
To enable attestation, mount the internal attestation directory in your contract like this:
Your workload must expose the attestation data—either through a web server/API or by writing it to the logs at boot time.
In this example, since the workload doesn’t include a web server, we chose to dump the data into the logs. The following line was added to the script that runs the workload:
Encrypting the contract and verifying attestation checksums
Attestation checksums are SHA256 hashes of specific parts of the contract. For example, the workload checksum is generated by hashing the following string (without any newline characters):
To make this easier, we used the encrypt_contract.sh script to automatically generate and save these checksums. This allowed us to compare them against the values provided by the system during boot.
The locally generated se-checksums.txt looked like this:
These matching values confirm that the contract running on the system is the same one we originally encrypted.
Encrypting the attestation records
As mentioned earlier, open attestation records can be faked. To prevent this, we take on the role of the auditor and encrypt the attestation records.
Since we’re now using encrypted records, we need to update the workload script to output the encrypted file se-checksums.txt.enc to the logs. To make it easier to spot in the logs, we add the following tags around the encrypted content:
Use the following commands to generate the RSA key pair used for encryption (change password zcatattestation to a password of your choice):
# Generate the private key with a passphrase
openssl genrsa -aes128 -passout pass:zcatattestation -out private_attestation.pem 4096
# Extract the public key from the private key
openssl rsa -in private_attestation.pem -passin pass:zcatattestation -pubout -out public_attestation.pem
Copy codeCopied!
Next, update the contract encryption script to include the attestation public key. Rename the modified script as encrypt_contract_att.sh (click to view). This change ensures that the attestation key becomes part of the contract and is included in the checksum calculations.
This confirms that the attestation data was encrypted with the auditor’s public key and logged securely by the workload.
Decrypting the attestation data
To verify the attestation data, follow these steps:
Copy the encrypted string (starting with hyper-protect-basic.MJ2R...) into a file named:
se-checksums.txt.enc
Use the provided decrypt-attestation.sh script to decrypt the attestation file using your private key.
Note: This script will overwrite the se-checksums.txt file generated by encrypt_contract.sh. To avoid this, change the output filename in either script.
./decrypt-attestation.sh private_attestation.pem se-checksums.txt.enc
Enter pass phrase for private_attestation.pem:
Copy codeCopied!
After decryption, the contents of se-checksums.txt should look like this:
A contract signature is an optional but powerful anti-tampering mechanism. It ensures that only a trusted source, usually the workload owner, can approve and validate the contract. For more information, see Contract signature.
The contract is signed using a private key or certificate, and the matching public key is included in the contract’s environment section as signingKey:. This allows the platform to verify that the contract hasn’t been tampered with.
It is recommended that the workload owner signs the contract. This ensures that only the intended workload can be deployed.
Unless a malicious actor has access to the private key, they won’t be able to create a valid signature. HPCR will reject any contract with an invalid or missing signature.
Signing process
The contract signer (typically the workload owner) generates a key or certificate pair.
The signer gives the public key (or certificate) to the ADMIN to include in the contract's env section as signingKey:.
The ADMIN shares the encrypted env section with the signer. The signer combines it with the encrypted workload section to form contract.txt. The signer uses their private key to sign the file.
The signer provides the signature back to the ADMIN, who uses it to deploy the contract.
Note: If you use certificates instead of keys, you can also enable contract expiry based on certificate validity. For simplicity, we’ll use keys in this example, but certificate usage is fully documented in the official guide.
We’ll now build on the contract we've created earlier (with attestation) and add this signature step for a complete, secure solution.
Steps
Run the following commands to generate an RSA key pair for signing (change password zcatsigner to a password of your choice):
# Generate a 4096-bit RSA private key, encryptedwith a passphrase
openssl genrsa -aes128 -passout pass:zcatsigner -out private_signer.pem 4096
# Extract the public key from the private key
openssl rsa -in private_signer.pem -passin pass:zcatsigner -pubout -out public_signer.pem
Copy codeCopied!
Convert the public key to a base64 string so it can be added to the contract (in the signingKey: field under the env section):
cat public_signer.pem | base64 -w 0
Copy codeCopied!
This outputs a single-line base64 string, which becomes your signingKey value.
Add the base64-encoded public key under the signingKey field in the contract's env section:
Use the modified script encrypt_contract_att_sign.sh to encrypt and sign the contract. This generates a signed checksum file (gen-se-checksums.txt) at creation time. The signature includes both the encrypted workload and env sections using the private key.
Log output should show:
***BEGIN se-checksums.txt.enc CAT DUMP***
... <encrypted and signed data> ...
***END se-checksums.txt.enc CAT DUMP***
To simulate a tampered contract, modify a character in the signingKey within the env section. This mimics someone trying to deploy a workload with an incorrect signature.
When the machine boots, it fails with the following logs:
VSI has failed tostart!
HPL10000E: One or more services failed -> systemd triggered hpl-catch-failed service
Copy codeCopied!
From the detailed logs:
Contract fileis invalid.
Validation of Contract failed.
HPL05001E: Unable to validate the contract semantically.
jsonschema: '/envWorkloadSignature' ... does not match expected pattern
Copy codeCopied!
This confirms that Hyper Protect Virtual Servers (HPVS) will reject any workload that doesn’t match the expected signature, protecting the environment from tampering.
Conclusion
We now have a better understanding of HPVS anti-tamper mechanisms:
Attestation: Lets an auditor verify that all components are as expected. It's important to keep both public and private keys secure, especially the public keys used for verification.
Contract signature: Allows the workload owner to sign the contract. If the signature doesn’t match, HPVS will block the deployment, assuming the contract was tampered with.
Note: These checks won’t stop a compromised image if it already exists in the registry with the same SHA256 checksum. To prevent this, use a secure build pipeline and digitally sign your images.