Upgrade to Pro — share decks privately, control downloads, hide ads and more …

全ての永続トークンを、生まれる前に消し去りたい!

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →
Avatar for sylph01 sylph01
October 16, 2026

 全ての永続トークンを、生まれる前に消し去りたい!

@ Kaigi on Rails 2026, 2026/10/16
https://kaigionrails.org/2026/talks/sylph01/

Avatar for sylph01

sylph01

October 16, 2026

More Decks by sylph01

Other Decks in Programming

Transcript

  1. Slides are available from the QR code → or from

    my Speaker Deck (username sylph01 ) 2
  2. whoami 梶原 龍 / sylph01 GitHub @sylph01, Twitter @s01, bsky

    @sylph01.s01.ninja やせいのプログラマ。暗号とか認証認可とかできます 愛媛県松山市に住んでいます 今の現場(どちらも認証基盤担当) codeTakt (今回のトークに関連する作業をした) Leaner Technologies いろいろします(背景参照) 3
  3. 6

  4. The One Ring 管理者権限とはThe One Ring (指輪物語のアレ) The One Ringが地上に存在している間、悪意のある人間はThe

    One Ringを悪用でき、世界は危機に晒され続けている The One RingはMount Doomに投げ捨てろ そのために約1000ページかけた大冒険をする必要はない image: https://www.needpix.com/photo/742654/ring-gold-middle-earth-golden-ring-metallic-map-cgi-jewellery-free-pictures 8
  5. 15

  6. offline_access を特別扱いする理由 確かにAuthCode Grantの一部だが… OAuthでは定義されておらず、OpenID Connectで導入されたscope OIDC Core §11 オフラインアクセスが要求された場合、(他の方法で許可を確

    認できない限り) prompt パラメータが consent である必要が ある(MUST) 本質的に違うgrantと言ってよい トークンが「ログアウトを経ても生き延びる」という意味 24
  7. 31

  8. におけるクライアント認証 OAuth confidential client クライアント認証に必要なシークレットを保持できるもの サーバーサイドアプリなど public client confidential client

    でないもの、つまりClient Secretなどを保持で きないもの ネイティブアプリ、ブラウザベースアプリ(SPA)など 32
  9. におけるクライアント認証 OAuth 共通のシークレット(shared secret)を用いる方法 client_secret_post , client_secret_basic , client_secret_jwt 秘密情報を共有しない方法

    公開鍵暗号を使う方式 private_key_jwt , tls_client_auth , self_signed_tls_client_auth https://qiita.com/TakahikoKawasaki/items/63ed4a9d8d6e5109e401 34
  10. に頼らない方式 shared secret FAPI (Financial-grade API) ではshared secretに頼らない方式が必要。 private_key_jwt トークンリクエストのペイロードを秘密鍵で署名

    認可サーバーは登録済みの公開鍵を使って署名検証 mTLS(mutual TLS; クライアント証明書を使ったTLS接続) RFC 7523: JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants 36
  11. Rails におけるmTLSの注意点: ALBの例 ALB の動作モード passthrough: バックエンドアプリは X-Amzn-Mtls-Clientcert から証明書を取り出してアプリ側でクライアント認証する必要 がある。これにはcertificate

    chainの検証も含む verify: ALBがtrust store相手に証明書を検証し、パースされたメ タデータがヘッダに乗ってくる verifyモードのほうが考えることが少ない 39
  12. DPoP (RFC 9449) クライアントは鍵ペアを生成 トークンリクエストに {公開鍵, ペイロード, 署名} の組 =

    DPoP proof JWT を渡す 認可サーバーは発行したトークンと公開鍵を関連づける 各リソースリクエストはアクセストークンに加えて {公開鍵, ペイロ ード, 署名} を送る リソースサーバーは署名検証 + トークンと公開鍵の関連付けを 確認する アクセストークンだけ取っても秘密鍵がないので何もできない! 43
  13. 権限の最小化が必要 でやることを減らす ではなく、Rings of PowerにはThe Three, The Seven, The Nineもある

    強い操作だけ違う権限にする operator scope The One Ring が権限分散の例として適切かどうかは諸説ある。The Nineの所有者はNazgûlになってしまったので… The Nine 47
  14. 50

  15. thundering herd problem 「有効期限が切れたら更新」ではなく、ある程度のrandom jitterを 設けてrefreshする 同時に更新が走ることを防ぐ Rails.cache.write / fetch

    の race_condition_ttl 最初のリクエストは更新が通常通り走る その次以降のリクエストについて、 race_condition_ttl で 設定した期間は最初のリクエストの値をキャッシュして返す 57
  16. トークンのキャッシュ方法 でもいいが最近はSolid Cacheがある Solid Cache with Active Record Encryptionがおすすめ DBに書かれるということはbackup,

    read replicaなどにも書かれ るので暗号化が重要 設定に encrypt: true → bin/rails db:encryption:init Redis store 58
  17. Rails.cache.fetch( ACCESS_TOKEN_CACHE_KEY, race_condition_ttl: RACE_CONDITION_TTL ) do |_name, options| # block

    runs when entry does not exist response = request_token # call token request jitter = rand(0.7..0.9) # random value from 70 to 90 percent options.expires_in = (response[:expires_in] * jitter).seconds response.fetch(:access_token) { raise TokenRequestError } end 59
  18. 61

  19. 66