ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-06-25上級

「広告を見たら壁紙を解放」をエージェントがクライアント側だけで付与していた — リワード報酬をSSVで検証し直した記録

リワード広告を見たら壁紙を解放する機能を Antigravity のエージェントに頼んだら、解放フラグをクライアント側だけで書き込む実装が返ってきました。なぜそれでは足りないのか、AdMob のサーバーサイド検証(SSV)で報酬付与を検証し直し、二重付与まで止めた設計を記録します。

antigravity390admob14monetization14app-dev37security10

プレミアム記事

リワード広告を一本見たら、有料の壁紙を一枚だけ解放できる。そんな小さな導線を Antigravity のエージェントに頼んだとき、返ってきたコードは確かに動きました。広告が閉じた瞬間に壁紙が解放され、次に開いたときも解放されたままです。ただ、その「解放されたまま」を支えていたのは、端末のローカル設定に書き込まれた一個の真偽値だけでした。

私は個人開発で壁紙・ヒーリング系のアプリを Google Play で運用しています。課金のない代わりに、リワード広告の視聴で一部の壁紙を解放する設計を長く使ってきました。だからこそ、この実装を一目見て手が止まりました。これは、解放という報酬付与を誰が決めるのか、という信頼境界の話だからです。

「広告を見たら解放」を、エージェントは一番短い道で実装した

エージェントが書いたのは、おおよそ次のような形でした。広告の視聴完了コールバックで、その壁紙の解放フラグをそのまま端末に書き込みます。

// エージェントが最初に提案した版(クライアント側だけで付与)
rewardedAd.show(activity) { rewardItem ->
    // 視聴完了 = 即・解放を端末に永続化
    prefs.edit()
        .putBoolean("wallpaper_${wallpaperId}_unlocked", true)
        .apply()
    unlockUi(wallpaperId)
}

挙動としては正しく見えます。広告を見れば解放され、再起動しても残ります。テストでも問題は出ません。けれども、この一行 putBoolean(... true) が「壁紙が解放されたか」の唯一の根拠になっている点が、本番では弱点になります。

端末のローカル設定は、ユーザーの手の届く場所にあります。root 化された端末や改変したビルドでは、広告を一度も見ずにこのフラグを true にできます。広告のコールバック自体も、クライアントの中で完結している限りは差し替えの対象です。つまり「広告を見た」という事実と「解放してよい」という判断が、どちらもクライアント側に閉じていました。

少額とはいえ、これは広告収益の取りこぼしに直結します。リワード広告は「視聴という対価と引き換えに報酬を渡す」契約で成り立っているのに、対価を払わずに報酬だけ取れる経路を残してしまうからです。

なぜクライアント側の付与だけでは足りないのか

ここで効いてくるのが、AdMob のサーバーサイド検証(Server-Side Verification, SSV)です。リワード広告ユニットで SSV を有効にすると、ユーザーが報酬を得るたびに Google が私のサーバーへコールバックURLを叩いてくれます。このコールバックには、報酬を「付与してよい」とGoogleが認めた事実が、ECDSA の署名つきで載っています。

公式ドキュメントでも、クライアント側のコールバックは即時のUX用に使い、報酬の正当性はSSVで検証するのが推奨とされています(Validate server-side verification (SSV) callbacks)。アプリ内経済に影響する報酬ほど、サーバーの検証済みコールバックを正とすべきだと明記されています。私の壁紙解放はまさに「経済に影響する報酬」でした。

設計として持ち帰るべき線は一本です。「広告を見た」という計測はクライアント(と広告SDK)に任せてよい。しかし「解放してよい」という付与の判断は、署名を検証できるサーバーだけが下す。 エージェントが短絡したのは、この二つを一つにまとめてしまった点でした。

観点クライアント側だけの付与SSV で検証した付与
解放の根拠端末のローカルフラグGoogleが署名したコールバック
詐称耐性フラグ書き換え・APK改変で突破可能署名検証を通らない付与は弾ける
二重付与検知できないtransaction_id で冪等化できる
真実の所在端末サーバー

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
クライアント側の解放フラグがなぜ詐称できるのかを、AdMob のリワードSSVという一点で今日から塞げる
SSVコールバックを Cloudflare Worker で検証する完成コードを、DER署名をWeb Cryptoが受け取れない罠の回避ごと自分のアプリに移植できる
transaction_id で二重付与とリプレイを止める冪等な付与の組み方と、計測はエージェント・信頼境界は人という線引きを持ち帰れる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-03-27
Antigravity × AdMob 広告収益最適化ガイド — AI エージェントでモバイル広告実装を効率化する
Antigravity の AI エージェントを活用して Google AdMob のモバイル広告実装を効率化し、収益を最大化する方法を解説。広告フォーマット選定からウォーターフォール最適化、A/B テストまで実践的に紹介します。
アプリ開発2026-06-21
戻るボタンで広告が出る/出ないが安定しない — 入れ子のifを独立ガードのリストに作り替えた記録
戻るボタン押下時のインタースティシャル表示判定が、入れ子のif文で優先度が暗黙化して壊れていました。各条件を理由つきの独立ガードに分解し、決定表からテストを生成した設計をまとめます。
アプリ開発2026-06-19
ATT を取る前に広告SDKを初期化していた — 初回起動だけ eCPM が下がる順序の罠
iOS の AdMob メディエーションを4本のアプリへ広げたとき、初回セッションだけ広告収益が落ちる現象に気づきました。原因は ATT 許諾と MobileAds 初期化の順序です。順序が効く理由と、Antigravity にその順序を監査させた実装記録をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →