Shogo's Blog

Sep 9, 2026 - 2 minute read - github github-actions

新規レポジトリーで GitHub Actions のOIDCフェデレーションが動かなくなった件

背景 新しいウェブサイトを立ち上げようと、GitHubのレポジトリーを新規作成して、GitHub Actions から Amazon S3 へデプロイするワークフローを組みました。 いつものように AWS OIDC フェデレーションを設定したのですが、認証に失敗してしまいました。 原因 (Codex先生に訪ねたところ)原因は ID トークンの Subject クレームの形式が変更になったことでした。 Immutable subject claims for GitHub Actions OIDC tokens 変更できないサブジェクト要求 以前までは repo:octocat/my-repo:ref:refs/heads/main のような形式だったのが、 repo:octocat@123456/my-repo@456789:ref:refs/heads/main のようなユーザーID・レポジトリーIDが入った形式に変更になりました。 7月15日以降に新規作成したレポジトリーでは新形式が使用されます。 古いレポジトリーに関しては新形式の利用はオプトインで、引き続き古い Subject クレームが使用されます。 CloudTrail のログを Codex先生に渡したら、Web検索してすぐに原因を突き止めてくれました。 賢いですね。 対応 今回のケースでは IAM ロールを CloudFormation のテンプレートで管理していました。 Resources: GitHubActionsWebntpDeployRole: Type: AWS::IAM::Role Properties: RoleName: GitHubActionsWebntpDeploy AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Federated: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:oidc-provider/token.actions.githubusercontent.com Action: sts:AssumeRoleWithWebIdentity Condition: StringEquals: "token.actions.githubusercontent.com:aud": sts.amazonaws.com "token.actions.githubusercontent.com:sub": repo:shogo82148/webntp.

Aug 24, 2026 - 2 minute read - go golang websocket

GoのWebSocketライブラリーを書いた

背景・目的 WebSocketのハンドシェイクがどのように行われているのか、お勉強のためにGo言語でWebSocketのライブラリーを実装しました。 shogo82148/websocket お勉強なのでコア部分の実装はなるべくAIは使わずに RFC 6455: The WebSocket Protocol を読んで頑張って実装しました。 ただし、テストコードをGitHub Copilot氏に描いてもらったり、CodeRabbitのレビューを受けたり、AI活用するところは活用してます。 また実装面では coder/websocket を大いに参考にさせていただきました。 使い方 APIは coder/websocket と合わせてあります。 サーバー 以下は接続すると「Hello WebSocket!」というメッセージを送り返してくれるサーバーの実装例です。 package main import ( "context" "log" "net/http" "time" "github.com/shogo82148/websocket" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 内部で Hijack 呼び出して、HTTP 通信から WebSocket に切り替える。 conn, err := websocket.Accept(w, r, nil) if err != nil { return } defer conn.CloseNow() // タイムアウト時間を設定 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // 「Hello WebSocket!

Aug 23, 2026 - 1 minute read - github

GitHub経由で脆弱性報告を受けた

TL;DR go-webntp および go-nginx-oauth2-adapter に脆弱性が見つかりました。 脆弱性を修正した以下のバージョンをリリースしました。 現在使用している方は最新バージョンへのアップデートをオススメします。 go-webntp v0.0.3 go-nginx-oauth2-adapter v0.4.8 脆弱性の概要 GitHub経由で脆弱性報告してみた では、「報告者」という立場でしたが、 今回は「報告を受けるメンテナー」という形で「プライベート脆弱性レポート機能」を利用することになりました。 報告者の @EQSTLab ありがとうございます。 go-webntp HTTP/WebSocketで時刻同期するWebNTPを書いた で紹介した、WebSocketのサーバーです。 GHSA-chpr-3j48-r4vg: Unbounded WebSocket Message Read Causes Remote Memory Exhaustion DoS in go-webntp Server WebSocketのメッセージを全部メモリー上に展開して解析する処理が入っているのですが、そこにサイズ制限が漏れていました。 そのため、攻撃者はデカいデータを送りつけることでメモリーを圧迫し、最終的にはOOMでサービスを止められます。 v0.0.3 では読み込みデータのサイズ制限を設けることでこの脆弱性を修正しました。 go-nginx-oauth2-adapter nginx-omniauth-adapterのGolangポート作った で紹介した、nginxにOIDCで認証を行う機能をつけるためのサーバーです。 GHSA-j2f5-qx44-xggq: Predictable Default Session Signing Key Leads to Authentication Bypass go-nginx-oauth2-adapter では、セッションの署名に使用する秘密鍵を設定する必要があります。 しかし、省略しても警告を吐くだけで、その場合は固定の文字列をキーとして使っていました。 固定の文字列はソースコードに埋め込まれているので、攻撃者は簡単にセッションを偽造することが可能です。 v0.4.8 では、秘密鍵未設定時に警告ではなく起動に失敗するよう修正しました。 警告をちゃんと読んで秘密鍵をちゃんと設定していたユーザーには影響はないはずです。 まとめ GitHub経由で脆弱性報告を受けたので、修正版をリリースしました。 go-webntp または go-nginx-oauth2-adapter を利用している方はアップデートをお願いします。 go-webntp v0.0.3 go-nginx-oauth2-adapter v0.4.8 うさぎが記事をぴょんと読む 脆弱性の話を明るく綴る

Jul 10, 2026 - 1 minute read - github

dependabotでgithub/codeql-actionのアップデートをまとめる

背景・目的 github/codeql-action について 僕の管理しているGitHubレポジトリーの一部はCodeQLを使って脆弱性の診断を行っています。 診断には公式のgithub/codeql-action Actionを使って、GitHub Actions上で実行しています。 github/codeql-actionは内部で複数のアクションを提供しており、これらのアクションを組み合わせて診断を行います。 init アクション analyze アクション autobuild アクション etc. これらのActionsはバージョンが食い違っていると、警告やエラー、予期しない結果につながるため、常にバージョンを一致させておく必要があります。 dependabotの仕様変更? 今まではgithub/codeql-actionに関連するActionをdependabotはすべて一括更新してくれました。 build(deps): bump github/codeql-action from 4.36.1 to 4.36.2 #507 しかし7月初めから、なぜか複数のプルリクエストに分割されるようになりました。 build(deps): bump github/codeql-action/analyze from 4.36.2 to 4.36.3 #525 build(deps): bump github/codeql-action/init from 4.36.2 to 4.36.3 #526 build(deps): bump github/codeql-action/autobuild from 4.36.2 to 4.36.3 #527 バージョンの不一致でCIがコケるので、このままではこれらのプルリクエストは取り込めません。 github/codeql-action のアップデートをまとめる これだと困るので一括更新してくれるよう、.dependabot.yaml の設定を更新しました。 version: 2 updates: # Maintain dependencies for GitHub Actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" # 新しく追加した部分 groups: codeql-actions: patterns: - "github/codeql-action/*" これで github/codeql-action のバージョンの食い違いを避けやすくなります。

Jun 16, 2026 - 3 minute read - go golang github

GitHub Personal Access Token を大量生成するプログラムを書いた

背景・目的 APIトークンは他者に知られると悪用される可能性があるので、GitHub などにプッシュするのは厳禁です。 とはいえ人間が注意するのではうっかり混入する場合もあります。 これを機械的に防ごうというサービスが GitHub Secret Protection です。 公開レポジトリーならデフォルトで有効になっているので、普段気が付かずにお世話になっているサービスだと思います。 さて、GitHub Secret Protection でシークレットが検出された場合のフローを検証しているのですが、そのためには実際にシークレットをプッシュする必要があります。 実際に GitHub などのサービスでトークンを発行してプッシュするのが楽ですが、本物のトークンを使うのは怖いですよね? じゃあ、ダミーデータを作ってみよう!というわけでやってみました。 PAT生成機 GitHub の Personal Access Token (PAT) のジェネレーターを作ってみました。 そんな長くないので、ここにペタリと貼っておきます。 手元にコピペしてお使いください。 // SPDX-FileCopyrightText: 2026 ICHINOSE Shogo <shogo82148@gmail.com> // SPDX-License-Identifier: MIT package main import ( "bufio" "crypto/rand" "encoding/base64" "hash/crc32" "os" ) func base62(in uint32) []byte { const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" var result [6]byte for i := 5; i >= 0; i-- { result[i] = chars[in%62] in /= 62 } return result[:] } func randomString(length int) []byte { ret := make([]byte, 0, length) var buf1 [30]byte var buf2 [40]byte for { rand.

Jun 16, 2026 - 1 minute read - go golang imageflux

go-imageflux の紹介と v1.3.0 リリースのお知らせ

背景・目的 週末を利用して go-imageflux の v1.3.0 をリリースしました。 v1.3.0 でちょっと大きめな変更を入れたので、 この変更を入れた背景等について説明します。 また、go-imageflux についてこのブログで紹介してなかったので、改めて紹介したいと思います。 ImageFlux の紹介 Webサイトを作っていると「画像が重すぎてサイトの表示が遅い!」という悩み、よくあると思います。 表示領域の広さに合わせて画像をリサイズするのが理想ですが、毎回毎回手作業でやるのも面倒です。 そんな悩みを解消してくれるのがImageFlux 画像変換・配信エンジン(以下、ImageFlux)。 ImageFlux は画像のリサイズやフォーマットの変換などを行ってくれるマネージドサービスです。 弊社でも画像の配信にImageFluxを利用しています。 導入事例 スマートフォンアプリ特有の課題「過酷な通信環境下での画像表示」をImageFluxで解決 go-imageflux の紹介 ImageFluxを利用するにはURLに画像変換用のパラメーターを埋め込む必要があります。 これをGoで簡単に行えるようにと作ったのが、ImageFlux向けのURLビルダーgo-imageflux です。 たとえば、「画像の幅を200ピクセルに、WebP対応のブラウザー向けにはWebPを配信したい」場合は、以下のようなコードを書きます。 // 画像を提供するホストの設定 proxy := &imageflux.Proxy{ Host: "demo.imageflux.jp", } // 画像リサイズ・変換フォーマット等の設定。 // キャッシュに乗りやすいよう、あらかじめ何パターンか用意しておく想定。 cfg := &imageflux.Config{ // 画像の幅を 200px に設定。 Width: 200, // ブラウザーが対応している場合は WebP に変換。 Format: imageflux.FormatWebPAuto, } // パラメーターを埋め込んだURLを発行。 u := proxy.Image("/images/1.jpg", cfg).SignedURL() fmt.Println(u) // Output: // https://demo.imageflux.jp/c/w=200%2Cf=webp:auto/images/1.jpg v1.3.0 からの変更点 今回 v1.

Apr 15, 2026 - 2 minute read - github aws

GitHub Appの秘密鍵をAWS KMSにインポートする

背景・目的 以下の記事を読んで GitHub App の秘密鍵を AWS KMS に閉じ込められることを知りました。 GitHub App の秘密鍵を AWS KMS に閉じ込める AWS KMS は食わず嫌いしていたので、この機会に仲良くなろうとちょっと触ってみることにしました。 触ってはみたものの秘密鍵をAWS KMSにインポートする手順が難しすぎる! 正直挫折しそうになりました。これからチャレンジする人が挫折しないよう、簡単に手順をまとめておきます。 GitHub Appの秘密鍵のインポート手順 GitHub Appの設定は終わっているものとし、秘密鍵はすでに入手しているものとします。 入手した秘密鍵のことをKMSの用語では「キーマテリアル(鍵素材)」と呼ぶので、以下そのように記載します。 以下のような手順でキーマテリアルをインポートします。 キーマテリアル無しでKMS Keyを作成する ラッピングパブリックキーとインポートトークンを取得する キーマテリアルの暗号化 KMSにキーマテリアルをインポートする エイリアスを割り当てる(Optional) キーマテリアル無しでKMS Keyを作成する AWS KMSにはキーマテリアルを自動生成してくれる機能がありますが、 今回は手元にあるキーマテリアルをインポートしたいです。 そのためには --origin EXTERNAL オプションをつけてキーを作成します。 aws kms create-key \ --key-spec RSA_2048 \ --key-usage SIGN_VERIFY \ --origin EXTERNAL \ --description "GitHub App JWT signing key" 作成に成功すると「KeyId」が発行されます。 後で使うので覚えておきましょう。 ラッピングパブリックキーとインポートトークンを取得する KMSにキーマテリアルをインポートするには、 キーマテリアルを暗号化する必要があります。 暗号化に必要な公開鍵を取得します。 aws kms get-parameters-for-import \ --key-id "$KEY_ID" \ --wrapping-algorithm RSA_AES_KEY_WRAP_SHA_256 \ --wrapping-key-spec RSA_4096 以下のようなJSONが出力されます。 PublicKey と ImportToken をそれぞれ publickey.

Apr 11, 2026 - 2 minute read - go golang aws

Amazon S3で分散ロックを実現するsets3lock

背景・目的 先週は三日三晩寝込んでしまい非常につらい思いをしたいっちーです。 さて、もう2年近く前になりますが、Amazon S3 が条件付き書き込みに対応しましたね。 昨年9月には条件付き削除にも対応しています。 Amazon S3 が条件付き書き込みのサポートを開始 Amazon S3 が S3 汎用バケットでの条件付き削除をサポート これの何が嬉しいかと言うと、今までDynamoDBが必要だった場面で、S3だけでカバーできるケースが増えます。 他所の例だと Terraform が有名ですね。 Terraform の S3 backend は多重実行を防ぐために元々は DynamoDB が必要でした。 条件付き書き込みがリリースされてからは多重実行防止の仕組みがS3だけで動くようになりました。 構成がシンプルになって管理するリソースが減るので嬉しいですね。 Terraform v1.10 からは S3 Backend の State Lock に DynamoDB が必要なくなる 僕も似たような用途で DynamoDB を利用していました。 昔 AWS Lambda と S3 を使ってyumレポジトリーを作ったときです。 yumレポジトリーのメタデータ更新が並列して走るとロストアップデートの可能性があるので、多重実行防止にDynamoDBを利用していました。 AWS Lambda + S3 を使ってyumレポジトリを作った 排他制御 メタデータ更新が並列して走るとロストアップデートの可能性がある DynamoDB を使った排他的ロックを実装 「今ならDynamoDBなしで実現できるのでは!」というわけで、やってみました。 また、その副産物として sets3lock というものができたので紹介します。 shogo82148/sets3lock sets3lock The setlock program という排他制御を行う有名なプログラムがあります。 有志たちによって DynamoDB版やRedis版が書かれてきましたが、sets3lock はそのS3版です。

Dec 24, 2025 - 2 minute read - perl

Perl 5.42 から新しく入った警告を試してみる

この記事は、Perl Advent Calendar 2025 24日目の記事です。 23日目は@shogo82148で「Perlクラスのレキシカルメソッドを試してみる」でした。 背景 ネタが尽きてきたので、引き続きperldeltaから頑張ってネタを探すシリーズをやっていこうと思います。 Perl 5.42 では警告にもいくつかの変更がありました。 そのうちよく引っかかりそうなものについて見ていきましょう。 否定演算子の優先順位に関する警告 たとえば以下のようなコードを考えてみましょう。 use v5.42; my $x = 5; my $y = 10; if (!$x < $y) { # バグ! (!$x) < $y を解釈される print "$x is not less than $y\n"; } else { print "$x is less than $y\n"; } 実行すると「5 is not less than 10」という誤った結果を返します: Possible precedence problem between ! and numeric lt (<) at ./test.pl line 5.

Dec 24, 2025 - 1 minute read - perl

Perlクラスのレキシカルメソッドを試してみる

この記事は、Perl Advent Calendar 2025 23日目の記事です。 22日目は@shogo82148で「Perlのフィールド変数の:writer属性を試してみる」でした。 背景 ネタが尽きてきたので、引き続きperldeltaから頑張ってネタを探すシリーズをやっていこうと思います。 クラスにレキシカルメソッドが実装されたらしいので、これを試してみます。 レキシカルメソッドの使い方 perlclass からの例です。 class機能はまだ実験的な機能扱いなので、機能の有効化と、警告の無効化が必要なことに注意してください。 use v5.42; use utf8; use feature 'class'; no warnings 'experimental::class'; class LexicalMethod { my method abc ($x, $y) { say "Internal method abc invoked with x=$x y=$y"; } method xyz { $self->&abc("x", "y"); } } my $obj = LexicalMethod->new(); $obj->xyz(); # エラーになる例: $obj->abc("hello", "world"); 実行すると以下のような結果が得られます: Internal method abc invoked with x=x y=y Can't locate object method "abc" via package "LexicalMethod" at .