はじめに
GCP Secret Manager の料金が何で決まるのかを、実際に費用が増えた経験をもとに解説します。保管の費用は version の数で決まるので、version を追加し続ける処理は破棄まで作らないと費用が増え続けます。
Secret Manager は、API キーやトークンなどの秘密情報を保管する Google Cloud のサービスです。値を更新するたびに version(コンソールの表示は「バージョン」)という単位で新しい値が積まれます。
本記事のまとめ
- 課金の対象は、active な version、アクセス操作、ローテーション通知の 3 つである
- 無効にした version にも課金される。課金を止めるには破棄する
- 「最新 N 版だけ残す」設定は見つからなかったので、呼び出す側で破棄する処理を書いた
- 破棄しても一覧に行は残るので、確かめるときは行数ではなくステータスを見る
GCP Secret Managerの料金は3つの項目で決まる
課金されるのは、active な version の数、アクセス操作の回数、ローテーション通知の回数です。単価は変わることがあるので、公式の料金ページで確認してください。
| 項目 | 課金 | 数え方 |
| active な version(有効と無効) | される | location ごとの version 数。active だった期間に比例する |
| 破棄した version | されない | – |
| アクセス操作(値の読み取り) | される | 操作の回数 |
| 管理操作 | されない | – |
| ローテーション通知 | される | 通知の回数 |
表の語は、次の意味です。
- active: version が有効または無効の状態にあることである
- location: 値を保存するリージョンである
- 管理操作: シークレットの作成や破棄、version の状態の変更などである
- ローテーション通知: シークレットの更新時期を Pub/Sub で知らせるメッセージである
無料枠は請求先アカウント単位で数える
無料枠はプロジェクトごとではなく、請求先アカウントごとに合算します。枠は毎月リセットされます。
- active な version: 6 版
- アクセス操作: 10,000 回
- ローテーション通知: 3 回
レプリケーションの設定でversionの数え方が変わる
version は location ごとに数えますが、自動レプリケーションは 1 location として数えます。レプリケーションは、値を複数のリージョンに複製する設定です。保存先を自分で選ぶ設定にすると、選んだ location の数だけ課金の対象が増えます。
versionは実行した回数だけ増えて247版になった
version を追加するだけで破棄していなかったので、1 つのシークレットが 247 版まで増えました。対象は、Cloud Run Job が 1 日 2 回更新する refresh token です。refresh token はアクセス用のトークンを取り直すための値で、私が使っている API では更新のたびに入れ替わります。

増え方は実行した回数のとおりで、作成日時も実行時刻に沿って並んでいます。掃除する処理がリポジトリに 1 つも無かったので、増える一方でした。
実際の費用は、2026 年 9 月 7 日から 13 日までの 7 日間で 576 円、月に換算すると約 2,470 円でした。これはクレジット適用前の金額で、プロジェクト全体の Secret Manager の費用です。このシークレット以外の version も含みます。
247 版のうち 244 版を破棄し、最新 3 版を残しました。失敗は 0 件です。そのあと、課金エクスポート(利用料の明細を BigQuery に書き出す機能)で週ごとの費用を比べ、Secret Manager の費用が下がったことを確かめました。
version の保管費用は実行頻度とは別に発生します。実行回数を減らせば増える速さは落ちますが、すでに溜まった version の費用は破棄するまで減りません。
無効にしてもSecret Managerの課金は止まらない
課金が止まるのは破棄したときだけで、無効にしただけでは課金が続きます。公式ドキュメントのversion の状態の説明にも、有効と無効の両方に課金し、破棄済みには課金しないと書かれています。
| 状態 | 値の中身 | 課金 |
| 有効 | 読める | される |
| 無効 | 残っている(読めないだけ) | される |
| 破棄 | 削除済み | されない |

私は次の 3 つを思い違いしていました。
- 無効にすれば課金が止まると思っていた。上の表のとおり止まらない
version_destroy_ttlを設定すれば古い version が自動で消えると思っていた。実際は、破棄を要求してから消えるまでの猶予を決める設定である- 「最新 N 版だけ残す」を Secret Manager の設定でできると思っていた。調べた時点では、件数で区切る設定は見つからなかった
2 つ目の猶予は費用を下げる機能ではありません。公式ドキュメントによると、猶予を設定した version は破棄を要求すると無効になり、期間が過ぎてから破棄されます。無効の version は課金の対象なので、費用が下がる時期はその分遅くなると考えられます。猶予中の課金は請求では確かめていません。設定しなければ、破棄はすぐに実行されます。
破棄は取り消せません。誤って消したときに戻す余地が要るなら猶予を設定し、費用を優先するなら設定しない、という判断になります。
古いversionは呼び出す側で破棄する
件数で区切る設定が見つからなかったので、有効な version を新しい順に並べ、残す数より古いものを破棄する処理を書きました。手作業で破棄するなら、次のコマンドです。
gcloud secrets versions destroy SECRET_VERSION_ID --secret=SECRET_ID処理に組み込むと次の形になります。実際に動かしているコードから、該当するメソッドを抜き出しました。
def prune_secret_versions(self, secret: str, keep: int = KEEP_ENABLED_VERSIONS) -> list[str]:
if keep < 1:
raise ValueError("keep must be >= 1 so that the newest version always survives.")
parent = self.secret_resource_name(secret)
enabled = [
version
for version in self._client.list_secret_versions(request={"parent": parent})
if version.state == secretmanager.SecretVersion.State.ENABLED
]
enabled.sort(key=lambda version: version.create_time, reverse=True)
destroyed: list[str] = []
for version in enabled[keep:]:
self._client.destroy_secret_version(request={"name": version.name})
destroyed.append(version.name)
return destroyedこのメソッドは、新しい version の保存に成功したあとで呼びます。破棄を先にすると、保存が失敗したときに使える値を失うためです。また、対象は有効な version だけなので、すでに無効にした version は残り、課金も続きます。
残す数は 3 版にしました。入れ替わるトークンでは使用済みの値に戻せないので 1 版でも足りますが、誤操作への猶予として残しています。静的な API キーのように古い値へ戻す可能性があるなら、残す数は別に考えてください。
破棄の権限はバージョンのマネージャーで渡す
version を追加するだけのロールでは破棄できないので、実行するサービスアカウントのロールを変える必要があります。ロールは権限をまとめたもので、サービスアカウントはプログラムが使う Google Cloud の ID です。公式ドキュメントは、version の破棄に roles/secretmanager.secretVersionManager を案内しています。

破棄だけを持つ事前定義ロールは無く、カスタムロールを作らない方針にしているので、追加・破棄・無効化・有効化をまとめて持つこのロールを選びました。値を読む権限は含まれないので、読むためのロールとは分かれたままです。付与する範囲も、プロジェクト全体ではなくシークレット 1 つに絞りました。
破棄できているかはステータスで確かめる
破棄しても version の行は一覧に残るので、行数ではなくステータスの列を見てください。行数だけを見ると、消えていないように見えます。確かめる段階では、ほかにも 2 つ引っかかりました。
テストが通っても掃除が呼ばれていないことがある
テストは 14 件とも通っていたのに、掃除の処理は一度も呼ばれていませんでした。テスト用の差し替え部品に掃除のメソッドが無く、そこで出た AttributeError を except Exception が受け止めていたためです。
掃除の失敗で本来の処理を止めたくないので、広い例外の受け方そのものは残しました。そのうえで差し替え部品にメソッドを足し、呼ばれた順番を確かめるテストに直しています。広く例外を受ける箇所では、テストがその経路を通っているかを別に確かめてください。
動作確認でversionが増えることがある
入れ替わるトークンでは、疎通を見るために使うだけで新しい version が 1 つ増えます。そこで破棄の前は API を呼ばず、Job の実行履歴と version の作成時刻を突き合わせました。
Job の実行 開始 09-17 04:00:01 UTC
version 247 作成 09-17 04:00:22 UTC成功した実行の開始から 21 秒後に新しい version ができているので、最新の version はその実行が書いたものと判断できます。対象のトークンを使わずに確かめられます。
まとめ
GCP Secret Manager の保管の費用は active な version の数で決まり、無効にしても止まりません。私の環境では、破棄していなかったために 1 つのシークレットが 247 版まで増えました。
version を追加する処理を持っているなら、まず一覧でステータスごとの version の数を確かめてください。増え続けているなら、古い version を破棄する処理と、破棄できるロールを用意します。
なお、単価、無料枠の数量、課金の対象、コンソールの構成は変わります。実際に設定するときは、件数で区切る設定の有無も含めて、最新を公式ドキュメントで確認してください。

