,

Vertex AI IAM, CMEK, and Data Governance (Google Cloud Gen AI Series, Part 10)

IAM decides who may call your Vertex AI models, CMEK decides who holds the encryption key, and data governance decides what Google keeps. Here is how to set all three without breaking production.

Google Cloud Gen AI Series · Part 10 of 30

Most Vertex AI data problems I have been called in to clean up did not start with a clever attacker or a broken model. They started with a single line, run once, months before anyone noticed it mattered:

gcloud projects add-iam-policy-binding my-project 
    --member='group:engineering@example.com' 
    --role='roles/aiplatform.admin'

One command. The whole engineering group. Full administrative control over every model, endpoint, tuning job, and stored dataset in the project. It felt reasonable on a Friday afternoon. It is also the reason a service account nobody remembered could still read a tuned model six months later, long after the person who created it had left. This part is about the three controls that keep that line from becoming an incident: who may call the models, who holds the key that encrypts what they produce, and what Google and you can see and keep after the request is done. Vertex AI is Google Cloud’s managed platform for building with generative models, and these three controls are the identity and data layer that sits inside the network boundary you drew in Part 9.

Who this is for: you have called a Gemini model on Vertex AI and can create a service account. I assume you read Part 9 on Private Service Connect and VPC Service Controls, so a service perimeter is already the network wall in your head and this part is the identity and key layer living inside it. You do not need a security background. Principal, role, service agent, CMEK, key ring, and audit log are each defined here on first use.

Key takeaways

Identity and Access Management, or IAM, answers one question: who may call. The predefined roles roles/aiplatform.user and roles/aiplatform.admin are wider than most callers need, so scope a custom role to the single permission a client actually uses, which for a prediction client is aiplatform.endpoints.predict. Customer-managed encryption keys, or CMEK, put a key you control in Cloud KMS in front of the data Vertex AI stores at rest, but it only works when you grant the Vertex AI service agent the CryptoKey Encrypter/Decrypter role and keep the key in the same region as the resource. Google does not use your prompts, responses, or tuning data to train its foundation models, though abuse monitoring can log prompts for up to 90 days unless your workload qualifies for zero data retention. Admin Activity audit logs are always on, but Data Access logs, the ones that record who read what, are off by default, so turn them on before you need them, not after an incident when they would have helped.

Three controls, three questions

The network boundary from Part 9 decided where a request may travel. It said nothing about who is allowed to send it, whether the data it leaves behind is encrypted under a key you hold, or whether anyone can prove after the fact who read what. Those are three separate questions, and Google Cloud answers them with three separate controls. Mixing them up is where teams get a false sense of coverage, because each one is silent about the other two.

IAM answers who may call. It grants a principal, which is any identity such as a user, a group, or a service account, a role, which is a bundle of permissions, on a resource. CMEK answers who holds the key. By default Google encrypts your data at rest with keys it manages, and CMEK swaps in a key you own in Cloud KMS so you can rotate it, or destroy it, on your terms. Governance and audit answer what was seen and kept. Cloud Audit Logs record the calls, Access Transparency records the rare times Google staff touch your content, and Google’s data commitments define what is retained and what is never used to train a model.

You want all three, and you want them in a deliberate order. Identity first, because a call that should never have been allowed is the cheapest thing to stop. Encryption next, because it decides who can read the data even if they reach it. Audit last, because it is how you learn what actually happened. The rest of this part takes them one at a time.

Three controls around one datasetidentity, key, and visibility each answer a different questionIAMwho may callCMEKwho holds the keyAudit and governancewhat is seen and keptYour Vertex AI dataprompts, tunes, endpoints
Three controls, one dataset. Each arrow is a question the others cannot answer, which is why turning one on tells you nothing about the other two.

IAM roles for Vertex AI, and why the predefined ones are too wide

Vertex AI ships three predefined roles that cover most of what people reach for. Vertex AI Viewer, roles/aiplatform.viewer, is read only: it can list and describe resources but change nothing. Vertex AI User, roles/aiplatform.user, is the working role: it can submit predictions, run jobs, and use the resources in a project. Vertex AI Administrator, roles/aiplatform.admin, is full control, including creating and deleting endpoints and persistent resources. These exist to make setup quick, and quick is exactly the trap. A prediction client that only ever calls a model gets handed roles/aiplatform.user because it is right there, and now that same identity can also start a tuning job and delete an endpoint it should never touch.

Google’s own guidance is to prefer custom roles for anything that faces production, because you build them and you decide exactly which permissions go in. A permission is a single verb on a single resource type, written like aiplatform.endpoints.predict, which is the one a client needs to send a prompt to a deployed endpoint. Put that permission, and only that permission, in a custom role and bind it to your service account. The client keeps working. The blast radius of a leaked credential shrinks from administrator to caller.

There is a fourth identity that surprises people: the service agent. When you enable Vertex AI, Google creates a managed service account named service-PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com that acts on your behalf to run jobs and, as you will see next, to use your encryption key. You do not create it and you rarely grant it much, but when CMEK or a cross-service job fails with a permission error, this agent is usually the identity that was missing a grant. Know its name before you need it.

RoleWhat it can doReach for it whenWatch out for
roles/aiplatform.viewerList and describe, no changesDashboards, read-only auditCan still read resource metadata
roles/aiplatform.userPredict, run jobs, use resourcesA human doing hands-on workToo wide for a predict-only client
roles/aiplatform.adminFull control, create and deletePlatform owners onlyA leaked key is a leaked admin
custom, predict onlyJust aiplatform.endpoints.predictAny production callerYou maintain the permission list

Here is the least-privilege version in gcloud. It defines a custom role holding only what a prediction client uses, then binds that role to a service account. Read the permissions flag as the whole point: two verbs, not two hundred.

gcloud iam roles create vertexPredictOnly 
    --project=my-project 
    --title='Vertex Predict Only' 
    --description='call a deployed endpoint, nothing else' 
    --permissions=aiplatform.endpoints.predict,aiplatform.endpoints.get 
    --stage=GA

# bind the narrow role to the app service account
gcloud projects add-iam-policy-binding my-project 
    --member='serviceAccount:app@my-project.iam.gserviceaccount.com' 
    --role='projects/my-project/roles/vertexPredictOnly'

Expected output: a custom role created with two permissions, then a policy binding added. The service account can now call generate_content against a deployed endpoint, but an attempt to create or delete an endpoint returns PERMISSION_DENIED, which is the point.

Failure mode: grant roles/aiplatform.user instead and the same account can submit tuning jobs, deploy models, and delete endpoints, none of which a prediction client needs. A leaked key for that account is now a leaked operator, not a leaked caller. The convenience of the broad role is paid back in full the day the credential ends up somewhere it should not be.

In practice: bind roles to groups, not to individual people, and scope the role, not the group. A group like ml-callers with a predict-only custom role means onboarding is one group membership and offboarding is one removal, and no single person carries a standing admin grant. When someone asks for aiplatform.admin, the honest question back is which single task needs it, because nine times in ten the answer is a job that a job-runner service account should own, not a person.
How wide each role really isillustrative count of permissions granted, not an exact audit050100150200permissions251102102vieweruseradmincustom predictthe custom role is the green sliver on the right
Illustrative permission counts, not a measured list, since the exact numbers shift as the service grows. The shape is the point: a predict-only custom role is a rounding error next to the admin bundle.

How CMEK actually changes the picture

Everything Vertex AI stores for you is already encrypted at rest, by default with keys Google generates and manages. For many teams that is enough. CMEK is for the teams whose contract or regulator says the encryption key must be one the customer controls, rotates, and can revoke. With CMEK you create a key in Cloud KMS, Google’s managed key service, inside a key ring, which is just a regional container for keys. Vertex AI then uses your key to wrap the data-encryption keys that protect the resource, so nothing is readable at rest without your key being available.

Two rules decide whether this works on the first try. First, the key has to live in the same region as the resource it protects. A key in us-east1 cannot encrypt a Vertex AI resource in us-central1, and the create call fails outright rather than falling back. Second, the Vertex AI service agent from the last section needs the CryptoKey Encrypter/Decrypter role, roles/cloudkms.cryptoKeyEncrypterDecrypter, granted on that key. Without it the agent cannot wrap or unwrap data, and the resource never finishes creating. Both errors read like something is broken. Neither is. They are the alignment CMEK requires, and skipping either is the most common reason a first CMEK rollout stalls.

Be clear about what CMEK does and does not buy you. It gives you a kill switch: disable the key and every resource that depends on it goes dark, which is drastic and dangerous in equal measure. It does not decide who may call the model, that is still IAM, and it does not by itself hide data from Google personnel during a support action, that visibility is what Access Transparency reports. CMEK is control over the key, nothing more and nothing less. That is worth real money to a regulated team and close to nothing to a team without that obligation, so match it to the requirement rather than turning it on for the feeling of safety.

gcloud kms keyrings create vertex-ring 
    --location=us-central1

gcloud kms keys create vertex-key 
    --location=us-central1 --keyring=vertex-ring 
    --purpose=encryption 
    --rotation-period=90d 
    --next-rotation-time=2026-10-01T00:00:00Z

# let the Vertex AI service agent use the key
gcloud kms keys add-iam-policy-binding vertex-key 
    --location=us-central1 --keyring=vertex-ring 
    --member='serviceAccount:service-PROJECT_NUMBER@gcp-sa-aiplatform.iam.gserviceaccount.com' 
    --role='roles/cloudkms.cryptoKeyEncrypterDecrypter'

Expected output: a key ring and a key in us-central1 with 90 day rotation, then a policy binding that lets the aiplatform service agent wrap and unwrap data with it. A Vertex AI resource created with the kms-key-name flag pointing at vertex-key now encrypts its data at rest under your key.

Failure mode: put the key in us-east1 while the Vertex resource lives in us-central1 and the create call fails, because the key and the resource must share a region. Skip the service-agent binding and the resource cannot use the key at all, so it hangs and never creates. Disable or destroy the key later and every resource that depends on it stops serving, which is the kill switch working as designed, not an outage to chase.

Gotcha: the kill switch cuts both ways. I have watched a team destroy an old KMS key during a cleanup, not realising a Vertex AI resource still pointed at it, and take their own inference endpoint offline until the key version was restored. Before you disable or destroy a key, list what depends on it and confirm nothing in production still needs it. A key with automatic rotation is fine to leave alone; a key you are about to delete deserves a dependency check first.
Where your key sits in the paththe service agent uses your KMS key to wrap data before it restsVertex AIresourceService agentencrypter roleCloud KMS keysame regionat restdisable the key and this whole chain stopskey and resource must share one region
CMEK inserts your Cloud KMS key into the wrap step. The service agent is the identity that reaches it, which is why it needs the encrypter role, and why a missing grant stalls the whole create.

What Google can see, and what it keeps

The question I get from every legal team is the same: what happens to our prompts. The baseline commitment is clear and worth stating plainly. Google does not use your prompts, your model responses, or your tuning data to train its foundation models. When you tune a Gemini model, the private data and outputs stay yours and never enter the training corpus. That is a contractual position, not a setting you toggle, and it is the reason a regulated workload can run on Vertex AI at all.

There is one nuance to know, because it catches people. Abuse monitoring runs automated safety classifiers over traffic, and if a request trips a classifier, Google may log the prompt to check whether it breached the acceptable use policy. That logged content is stored securely for up to 90 days, in the same region or multi-region you selected, and it is not used to train or tune any model. For most teams that is an acceptable safety trade. For a bank or a hospital it may not be, which is why zero data retention exists: eligible customers on eligible models can turn off that retention so flagged content is not stored at all. Confirm your model and account qualify before you promise a regulator a hard zero.

So the honest summary is layered. Prompt content is never training data. It may be retained briefly for abuse review unless you hold zero data retention. Your own logging, on the other hand, is entirely your responsibility, and the same warning from Part 8 applies: Vertex AI can keep zero prompt content while your application quietly writes every prompt to a log sink that keeps it for a year. Trace where the data goes after the model call, not just what Google does with it.

Data categoryUsed to train foundation modelsDefault retention
Prompts and responsesNoNot retained after the response, 0 days
Tuning data and tuned modelNo, stays private to youKept until you delete it
Abuse-monitoring logs, flagged onlyNoUp to 90 days, 0 with zero data retention
Data Access audit logsNoOff by default, 30 days once on
Admin Activity audit logsNoAlways on, 400 days, metadata only

Worked example

A bank runs a Gemini workload under a rule that no customer prompt may persist beyond the transaction. Out of the box, three things can retain data: context caching if it is enabled, abuse-monitoring logs for up to 90 days on flagged prompts, and Data Access audit logs at the Cloud Logging default of 30 days once you switch them on. Admin Activity logs hold metadata, who called and when, not the prompt text, for 400 days.

The bank closes each content path in turn. It applies for zero data retention on its model, which drops the abuse-monitoring retention from 90 days to 0. It disables context caching. Prompt content now persists for 0 days. What remains is audit metadata: 30 days of Data Access records showing which service account called, and 400 days of Admin Activity records, neither of which contains a customer prompt.

The compliance line was met not by one master switch but by naming every retention path and closing the ones that held content, while keeping the ones that only hold metadata. 0, 90, 30, and 400 are four different numbers for four different things, and treating them as one is how teams either over-retain or lose their audit trail.

Default retention by data categorydays each category is kept before you change a thing0100200300400days kept09030400prompt contentabuse logsdata access logsadmin activitygreen is content at 0 days, black is metadata at 400
The numbers from the worked example. Content sits at or near zero once you close the paths, while metadata is kept longest, which is the shape a compliance reviewer wants to see.

Audit logs and Access Transparency, the part teams skip

Cloud Audit Logs are the record of who did what on aiplatform.googleapis.com, the service name Vertex AI logs under. They come in two kinds that behave very differently. Admin Activity logs capture changes to configuration, creating an endpoint, editing a role binding, and they are always on and cannot be turned off. Data Access logs capture reads of your data and the calls that touched it, and they are off by default because they can be high volume. That default is the trap. The log that would tell you which identity read a tuned model last Tuesday is the one nobody enabled until the week they needed it and found nothing there.

Access Transparency is a different lens, pointed at Google rather than at your own users. In the rare cases a Google employee accesses your content, during a support ticket you opened, for example, Access Transparency writes a near real time log of what they touched, which operation they ran, and the justification for it. It arrives in Cloud Logging alongside your audit logs. For a regulated buyer this is often the control that closes the deal, because it turns Google’s side of the boundary from a promise into a log line you can read. Enabling it is an organisation-level step, not a per-project one, so it usually belongs to the platform team.

My take: turn on Data Access audit logs for aiplatform.googleapis.com on day one, before the project holds anything sensitive, and route them to a bucket with a retention you have actually chosen. They cost storage and they are noisy, and both of those are cheaper than the meeting where you explain that the read you need to investigate was never recorded. If volume is a real worry, scope Data Access logging to the services that touch regulated data rather than switching it off wholesale.

Least privilege by default, CMEK by exception

Here is how I would set this up on a new project. Start with identity, because it is the cheapest control and the one most often left wide. Give humans a group with a scoped role, give each workload a service account with a custom role holding only the permissions it uses, and keep roles/aiplatform.admin for the two or three people who actually own the platform. Do not reach for the predefined user role just because it is one click. A predict-only custom role is barely more work and it is the difference between a leaked caller and a leaked operator.

Treat CMEK as an exception, not a default. Turn it on where a contract or a regulator names customer-controlled keys, and size the operational cost honestly: key rotation, the availability risk of a kill switch, and the same-region constraint that shapes where resources can live. Where there is no such requirement, Google-managed encryption is already protecting your data at rest and CMEK adds work without adding coverage. On governance, enable Data Access audit logs immediately, apply for zero data retention if a regulator needs a hard zero on prompt content, and confirm the current retention terms on the live docs because they move. Least privilege is the rule for everyone. CMEK is the rule for the teams who can name why.

One thing to do this week: run gcloud projects get-iam-policy on your main Vertex AI project and read every binding that grants roles/aiplatform.admin or roles/aiplatform.user. For each one, ask which single task needs it. The bindings that cannot answer are your first cleanup, and they are almost always where a leaked credential would do the most damage. Part 11 moves from securing the platform to calling it well, with the Gemini API, streaming responses, and function calling, so the identity you just tightened is the one making real requests.

The same identity and key problem has an AWS shape, where roles are IAM policies and the key sits in KMS rather than Cloud KMS. The mirror of this part is Amazon Bedrock data residency, KMS, and security, which solves who may call and who holds the key with different plumbing and the same logic.

Disclaimer: changing IAM bindings, creating or destroying KMS keys, and enabling or disabling audit logs are production changes to identity and data controls. Run them through your normal change review, test on a non-production project first, and confirm the current Vertex AI role list, CMEK region rules, and data-governance and retention terms on the live Google Cloud docs for your exact model and region before you rely on them. Never destroy a KMS key without checking what still depends on it.
Google Cloud Gen AI Series · Part 10 of 30
« Previous: Part 9  |  Guide  |  Next: Part 11 »

References

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading