Skip to content

[keymanager] add cloudbuild integration test flow#701

Merged
atulpatildbz merged 9 commits intogoogle:mainfrom
atulpatildbz:cloudbuild-test
Mar 16, 2026
Merged

[keymanager] add cloudbuild integration test flow#701
atulpatildbz merged 9 commits intogoogle:mainfrom
atulpatildbz:cloudbuild-test

Conversation

@atulpatildbz
Copy link
Copy Markdown
Collaborator

This adds the automated integration tests for the keymanager service.

  • Adds a test workload container image that runs the end-to-end Python client test
  • Adds a cloudbuild yaml test definition to spin up a VM with the workload
  • Hooks the test into the main launcher cloudbuild.yaml workflow

@atulpatildbz
Copy link
Copy Markdown
Collaborator Author

/gcbrun

1 similar comment
@atulpatildbz
Copy link
Copy Markdown
Collaborator Author

/gcbrun

@atulpatildbz atulpatildbz force-pushed the cloudbuild-test branch 2 times, most recently from 27ece38 to 4d5baf9 Compare March 12, 2026 03:03
import requests_unixsocket

session = requests_unixsocket.Session()
# Use the correct socket path for confidential space environment
Copy link
Copy Markdown
Collaborator Author

@atulpatildbz atulpatildbz Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: remove / modify this comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Updated the comment to reflect the HTTP post request instead of reading from server.log

enc_bytes, ciphertext, plaintext = do_encap(pub_key_b64)
shared_secret_bytes = decap_key(handle, enc_bytes)
verify_payload(shared_secret_bytes, ciphertext, plaintext)
print("\nSuccess! Flow completed.")
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: add destroy. then enumerate again to check if it is empty

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Added a destroy_key step at the end of the test flow, followed by enumerate_keys to assert the handle is no longer present


# Check for server.log generated by background WSD server
def generate_key():
print("\n--- Generating Key ---")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move all the log print statements to the serial console. Otherwise they are not captured in the VM logs and it will be hard to debug if anything goes wrong.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Redirected sys.stdout and sys.stderr to /dev/console at the start of the script.

Checking the output after test execution

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the logs are still missing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to push the workload image after changes. Trying again

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted the /dev/console logic. the SERIAL_OUTPUT was empty in that case.

as per launcher/image/test/scripts/test_keymanager.sh we only echo to serial output in case of failure.

I temporarily removed this condition in 48980de and then reran the cloudbuild test.

the print statements can be found in the cloudbuild job: (sharing url separately)

level=INFO msg="workload task started" Socket /run/container_launcher/kmaserver.sock found after 0 seconds  --- Getting Capabilities --- Capabilities: { "supported_algorithms": [ { "algorithm": { "type": "kem", "params": { "kem_id": "DHKEM_X25519_HKDF_SHA256" } } } ] }  --- Generating Key --- Generated Key: af9ee813-9e3e-498b-9610-e9da884fb439  --- Enumerating Keys --- Enumerated Keys: [ { "key_handle": { "handle": "af9ee813-9e3e-498b-9610-e9da884fb439" }, "pub_key": { "algorithm": { "type": "kem", "params": { "kem_id": "DHKEM_X25519_HKDF_SHA256" } }, "public_key": "Ktak7twxMHVResTMfmLKQK4UahV04+6V5l/ao4dVbDo=" }, "key_protection_mechanism": "KEY_PROTECTION_VM_EMULATED", "expiration_time": 1773386236 } ]  --- Performing HPKE Encapsulation --- Encrypting plaintext payload: 'authentic-secret-32-bytes-value!'  --- Decapping Key af9ee813-9e3e-498b-9610-e9da884fb439 --- Decapped shared secret: { "algorithm": "DHKEM_X25519_HKDF_SHA256", "secret": "L5BzbGPw41Nd2NXQmIjBnB8Vlq1dVgBmXI06ebZbwM0=" }  --- Verifying Decapped Payload --- Initializing HPKE receiver context from the decapped shared secret... Opening the ciphertext locally using the returned shared secret... Decrypted payload: 'authentic-secret-32-bytes-value!' SUCCESS: The decrypted payload matches the originally sent payload!  --- Destroying Key af9ee813-9e3e-498b-9610-e9da884fb439 --- Key destroyed successfully.  --- Enumerating Keys --- Enumerated Keys: []  Success! Flow completed. time=2026-03-13T06:17:17.555Z 

I'll proceed to revert 48980de now

if resp.status_code != 200:
print(f"Error: {resp.status_code} - {resp.text}")
resp.raise_for_status()
keys = resp.json()["key_infos"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets tighten this test to check that the key we generated in the generate_key step is also included in the enumerated list.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. The test now explicitly looks for the generated key handle in the enumerate_keys response.

This adds the automated integration tests for the keymanager service.

- Adds a test workload container image that runs the end-to-end Python client test

- Adds a cloudbuild yaml test definition to spin up a Keymanager VM with the workload

- Hooks the test into the main launcher cloudbuild.yaml workflow

Fix fetchExperiments for Vanguard images and update KeymanagerTests

The confidential_space_experiments binary is intentionally omitted from
Vg
images (which use vgpreload.sh and vgentrypoint.sh). Because of this,
the
fetchExperiments function fails and experiment variables default to
false, breaking tests like the new Keymanager E2E tests.

This commit updates launcher/spec/launch_spec.go to gracefully fallback
to
reading the static /usr/share/oem/confidential_space/vgexperiment.json
file
when the experiments binary is absent or fails.

It also updates launcher/cloudbuild.yaml so the KeymanagerTests step
runs
against the vg debug image (DebugVgImageBuild), rather than the standard
debug image, as EnableKeyManager is specifically an injected vg feature.

Fix fetchExperiments linter warning (indent-error-flow)
Addresses PR feedback for the keymanager client test workload:

1. Console Logging: Redirects sys.stdout and sys.stderr to /dev/console
at the start of the script so that standard output appears in the VM
serial console logs immediately.
2. JSON Schema Validation: Replaces the custom nested dictionary
validation logic with the standard `jsonschema` Python library. Adds
comprehensive JSON schemas for each API response (KEY_HANDLE_SCHEMA,
ALGORITHM_SCHEMA, PUB_KEY_SCHEMA, KEY_INFO_SCHEMA, GET_CAPABILITIES_SCHEMA,
DECAPS_RESPONSE_SCHEMA, ENUMERATE_KEYS_SCHEMA) and enforces strict payload
structures.
3. Added `jsonschema` to the workload Dockerfile dependencies.
4. Destroy Key Flow: Adds a `destroy_key` function to test the v1/keys:destroy
API.
5. End-to-End Test Updates: Enhances the main execution flow to destroy
the generated key at the end, and then re-enumerates the keys to assert
that the destroyed key handle no longer exists in the key manager.
@atulpatildbz
Copy link
Copy Markdown
Collaborator Author

/gcbrun

@atulpatildbz
Copy link
Copy Markdown
Collaborator Author

/gcbrun

@atulpatildbz
Copy link
Copy Markdown
Collaborator Author

@meetrajvala i've separated keyclaims and keymanager workload. can you approve this restructuring looks okay?

@jkl73 can you take a look at yaml changes in this PR and approve if it looks okay?

@atulpatildbz atulpatildbz requested a review from jkl73 March 13, 2026 08:29
@@ -1,13 +1,18 @@
# From current directory:
# gcloud builds submit --tag us-west1-docker.pkg.dev/confidential-space-images-dev/cs-integ-test-images/kms-workload:latest --project confidential-space-images-dev
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we do not follow any convention, It would be helpful to have the workload image reference here in comment so that test workload images can be easily mapped to their artifact registry refs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. added gcloud build submit comment.

also added registry reference comment in launcher/image/test/test_keymanager_cloudbuild.yaml

As we do not follow any convention, it is helpful to have the workload image reference in comments so that test workload images can be easily mapped to their artifact registry refs.

This addresses a review comment on PR google#701.
@atulpatildbz atulpatildbz merged commit 64f2a3f into google:main Mar 16, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants