---
cuppy_hub: gcp
cuppy_path: reference/identity/secret-manager-and-kms.md
cuppy_section: docs
cuppy_doc: TZT4-NMR5
cuppy_doc_uuid: 28fc2140-88ea-4ce9-adc1-e19aa660edaa
cuppy_permalink: https://cuppy.io/gcp/d/TZT4-NMR5
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/reference/identity/secret-manager-and-kms
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 122d50ddf5a6d42eaf707009605c9b5e6c94edf40a7baeb087c814110c4f1657
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Secret Manager and Cloud KMS

## 1. Secret Manager's object model

A **secret** is the container: labels, annotations, permissions, and a list of **versions**. A version holds
the data. The overview describes it exactly that way and stops there — it does **not** give a resource-name
format, does **not** define what `latest` selects, and does **not** enumerate the version states. Those gaps
are stated rather than guessed; read the REST reference if a design depends on them.

**Replication is chosen once, at creation**, from two named policies:

| Policy | What it means, verbatim-ish |
|---|---|
| **Automatic replication** | "Google Cloud decides the regions considering availability and latency" |
| **User managed replication** | "you can select a custom set of regions" |

For a migration estimate this is the row that matters: a data-residency requirement forces user-managed
replication, and that is a per-secret decision multiplied by the number of secrets, not one account setting.

### The one role that reads a payload

| Role | What it does |
|---|---|
| `roles/secretmanager.secretAccessor` | **reads the payload**, via `secretmanager.versions.access` |
| `roles/secretmanager.viewer` | metadata only — **cannot** read a payload |
| `roles/secretmanager.secretVersionAdder` | adds a version to an existing secret |
| `roles/secretmanager.secretVersionManager` | add, destroy, disable, enable |
| `roles/secretmanager.editor` / `.admin` | create and delete secrets; `.admin` also controls the allow policy |

The commonest wrong grant on Google Cloud is `roles/secretmanager.viewer` to a workload that needs to *read* a
value. Viewer sees that the secret exists. Only the accessor role sees what is in it.

### Fixed, and therefore a design constraint

- **payload size 64 KiB**, stated non-adjustable;
- **50 aliases per secret**, stated non-adjustable.

Everything else on the quotas page is a rate, adjustable through sales or Support. Per-secret modification
rates are quoted *per secret* for global secrets and *per secret per region* for regional secrets — so a hot
single secret is the bottleneck, never the project.

## 2. Cloud KMS's object model

```
project → location → key ring → key → key version
```

Resource names, verbatim from the page:

```
projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME
projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION
```

### What cannot be undone

- **"Key rings can't be deleted."** Verbatim. A key ring created in the wrong location or with a name you
  regret is permanent for the life of the project. Name it as if it were permanent, because it is.
- **Names of deleted keys cannot be reused.**
- **Protection level, key purpose and key type are immutable** once the key exists.
- **Cloud KMS resources cannot be moved to a different location after creation.**

Four irreversible decisions in one service; this is the service where a migration plan most often has to
create new objects rather than move existing ones.

### Protection levels

`SOFTWARE`, `HSM` (multi-tenant HSM), `HSM_SINGLE_TENANT`, `EXTERNAL`, `EXTERNAL_VPC`.

### The quota shape, which is unusual and worth knowing

> "There are no quotas on the number of key rings, keys, key versions, or other Cloud KMS resources that you
> can have; only on their usage."

Usage is metered by `cloudkms.googleapis.com/read_usage`, `write_usage`, `software_usage`, `hsm_usage` and
`external_kms_usage`. The first four are soft-enforced and `external_kms_usage` is hard-enforced — so an
external-key design is the one that can be refused outright under load. **No value is typed here**; read
yours live (`reference/overview/quotas-and-limits-model.md`).

Cross-cloud: AWS KMS and Secrets Manager, Azure Key Vault — including the fact that Azure puts both jobs in
one service while Google Cloud splits them — in `guides/parity/identity.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 91 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/gcp/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
