# GCP Vertex AI vertex-metadata-store Without CMEK

> Flags Vertex ML Metadata stores without a customer-managed key, often the auto-created default store.

Source: https://zop.dev/integrations/gcp/recommendations/gcp-vertex-ai-vertex-metadata-store-without-cmek

---

## The store most teams never chose to create

Vertex ML Metadata records the lineage of ML work: artifacts, executions, parameters and metrics.
Google's [metadata store configuration page](https://cloud.google.com/vertex-ai/docs/ml-metadata/configure)
explains that the first time you run a PipelineJob or create an experiment in the Vertex SDK, the
project's MetadataStore is created for you. It also says that if you want CMEK, you must create the
store with the key before you use Vertex ML Metadata to track anything.

That ordering is the trap. By the time a compliance review asks, the `default` store already exists
under Google encryption, holding run parameters, dataset URIs and metrics. The
[CMEK reference](https://cloud.google.com/vertex-ai/docs/general/cmek) says a key covers all content
in the store.

## Checking the metadata stores in a region

```bash
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/metadataStores"
```

Look for `encryptionSpec.kmsKeyName` on the `default` store and any others.

## Condition for a finding

ZopNight records, for each metadata store it inventories, whether a Cloud KMS key name is present
in its encryption settings. A confirmed "no key" raises the finding. The amount of lineage stored
and pipeline activity are not considered.

## When no finding is produced

A store created with a key is silent. If encryption data is missing for a store, ZopNight does not
report it. Note that the key on the store is independent of keys used by the processes writing to
it, so a keyed pipeline run does not make an unkeyed store compliant.

## Why it matters without a saving

The saving is $0. The metadata store is a map of your ML estate: where datasets live, which
parameters produced which model. Keeping it outside your key policy undermines keys applied
everywhere else.

## Creating a keyed default store

1. Create a key in the region and grant the Vertex AI service agent the Cloud KMS CryptoKey
   Encrypter/Decrypter role on it.
2. In a new project or region, create the store before any pipeline runs:

   ```bash
   curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
     -H "Content-Type: application/json" \
     -d '{"encryption_spec": {"kms_key_name": "KEY_RESOURCE_NAME"}}' \
     "https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/metadataStores?metadata_store_id=default"
   ```

3. For an existing unkeyed store, plan a move: export the lineage you need, delete the store, and
   recreate it with the key before the next pipeline run.

**Warning**
Deleting a metadata store deletes its lineage history. Export anything auditors may ask for first.
