
Semaphore UI 2.19 は 2.x 系列で最大のリリースです。グラフィカルエディターを備えた ワークフロー を導入し、 ランナーが Docker コンテナや Kubernetes Pod でタスクを実行できるようになり、実行中のタスクに 短命な JWT アイデンティティトークン を発行できるようになりました。さらに 暗号化キーのローテーション を追加し、 ランナーの信頼性の問題を根本的に修正し、多数のセキュリティ強化の変更を含んでいます。
この系列は v2.19.0 から v2.19.14 までのリリースを対象としています。パッチリリースは末尾に一覧があります。
ハイライト
- ワークフロー (Beta) — 承認ゲート付きのパイプラインとしてタスクテンプレートを連結し、 グラフィカルエディターで描画して、同じキャンバス上でライブに監視できます。
- Docker および Kubernetes エグゼキューター — ランナーが各タスクを新しいコンテナまたは Pod で実行できます (Pro / Enterprise)。
- タスク向け JWT アイデンティティトークン — プレイブックから Vault、AWS、GCP、Azure、 その他 OIDC トークンを受け付けるあらゆるサービスへのキーレス認証。
- 暗号化キーのローテーション — ラベル付きキーリング、ホットリロード、
vaults checkコマンド。 - サーベイ変数の環境変数としての受け渡し、および
int、text型と再設計されたenum型。 - タスク履歴の本格的なサーバーサイドページネーション — 数百万件のタスクを持つプロジェクトでも高速なままです。
- ランナーの信頼性 — オンライン/オフラインステータス、ワンタイムのハッシュ化された登録トークン、 停止したランナーで滞留したタスクの自動リカバリー。
- 選択的なデバッグログ —
SEMAPHORE_DEBUG_FILTERによる。 - セキュリティ強化: 現在のパスワードの確認、CSRF オリジン検証、セキュアクッキー、 API 全体でのより厳密な入力検証。
- BoltDB の削除 — SQLite、MySQL、PostgreSQL のみをサポート。
ワークフロー (Beta)
ワークフローとは、1 つの単位として実行されるタスクテンプレートのグラフです。各ノードは タスク (テンプレートを 実行)、承認 (ユーザーが承認または却下するまで実行を一時停止)、ノート (実行されない自由形式の 注釈) のいずれかです。エッジには条件があります: 成功時、失敗時、常に のいずれかです。
ワークフローは、プロジェクトのサイドバーに新しい ワークフロー 項目として表示され、Beta チップが付いています。 Pro エディションで利用可能ですが、ベータ期間中はプランに関係なく有効になっています。
グラフィカルエディター

エディターは Drawflow をベースに構築されたフルページのキャンバスです:
- パレットからノードをドラッグし、ノードのハンドルからドラッグして接続します;
- エッジをクリックして条件を変更します; エッジは色分けされ、凡例が隅に表示されます;
- ノードをクリックするとサイドパネルでプロパティを編集できます: テンプレート、収束モード (すべての親 / いずれかの親)、承認のタイムアウトとメッセージ、ノートのテキスト;
- 自己エッジと循環は描画時に拒否され、問題 パネルがサーバーサイドの検証をミラーするため、 壊れたグラフは保存できません;
- ノードの位置は保持されます; 位置を指定せずに API 経由で作成されたワークフローには、自動的に トポロジカルレイアウトが適用されます;
- ツールバーまたは
Ctrl+ マウスホイールでズーム、キャンバスをドラッグしてパン、パレットを折りたたんで スペースを確保できます; - 開始バージョン は実行のバージョニング (
1.4.0、1.4.1、…) の起点となります; バージョンは実行が 起動するすべてのタスクに伝播されます。

ライブ実行ビュー
実行ビューは同じキャンバスを再利用します。各ノードにはタスクのステータスが表示され、アクティブなノードはハイライトされ、
保留中の承認はキャンバス上に直接 承認 / 却下 ボタンとして表示されます。停止 ボタンは
実行中のすべてのタスクを強制停止し、保留中の承認を却下して、実行を stopped としてマークします。

実行ステータスは running、approval、success、failed、stopped です。ワークフローの進行は
サーバーによって駆動されます: いずれかのワークフロータスクが完了すると次のノードがスケジュールされるため、
自動実行の子を持たないテンプレートで実行が停滞することはなくなりました。

ノードごとのタスクパラメーター
すべてのタスクノードは、手動実行と同じように、テンプレートに渡すパラメーター (変数、インベントリ、ブランチ、 引数、バージョン、メッセージ) を上書きできます。
API
GET/POST /api/project/{id}/workflows
GET/PUT/DELETE /api/project/{id}/workflows/{workflow_id}
POST /api/project/{id}/workflows/{workflow_id}/run
GET /api/project/{id}/workflows/{workflow_id}/runs
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}
POST /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/stop
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/artifacts
GET /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/approvals
POST /api/project/{id}/workflows/{workflow_id}/runs/{run_id}/approvals/{node_id}
ベータ版の既知の制限: ミニマップ、元に戻す/やり直し、複数選択はありません; ワークフローアーティファクト
(set_stats の値) は、リモートランナーで実行されたタスク間ではまだ受け渡されません。
Docker および Kubernetes エグゼキューター (Pro / Enterprise)
ランナーは、ランナーホスト上で直接実行する代わりに、各タスクを隔離された環境で実行できます。
エグゼキューターはランナープロセスごとに runner.executor.type (local、docker、
k8s) で一度だけ選択します。
Docker (runner.executor.docker、Pro):
| オプション | 環境変数 | デフォルト |
|---|---|---|
host |
SEMAPHORE_RUNNER_DOCKER_HOST |
ローカルソケット |
tls_verify, cert_path |
SEMAPHORE_RUNNER_DOCKER_TLS_VERIFY, …_CERT_PATH |
|
image |
SEMAPHORE_RUNNER_DOCKER_IMAGE |
semaphoreui/job:latest |
helper_image |
SEMAPHORE_RUNNER_DOCKER_HELPER_IMAGE |
semaphoreui/helper:latest |
network |
SEMAPHORE_RUNNER_DOCKER_NETWORK |
bridge |
pull_policy |
SEMAPHORE_RUNNER_DOCKER_PULL_POLICY |
if-not-present |
cpu_limit, memory_limit |
SEMAPHORE_RUNNER_DOCKER_CPU_LIMIT, …_MEMORY_LIMIT |
|
privileged |
SEMAPHORE_RUNNER_DOCKER_PRIVILEGED |
false |
poll_interval_seconds, cleanup_grace_seconds |
…_POLL_INTERVAL_SECONDS, …_CLEANUP_GRACE_SECONDS |
2, 30 |
Kubernetes (runner.executor.k8s、Enterprise):
| オプション | 環境変数 | デフォルト |
|---|---|---|
kubeconfig |
SEMAPHORE_RUNNER_K8S_KUBECONFIG |
クラスター内 |
namespace |
SEMAPHORE_RUNNER_K8S_NAMESPACE |
semaphore |
image |
SEMAPHORE_RUNNER_K8S_IMAGE |
semaphoreui/job:latest |
helper_image |
SEMAPHORE_RUNNER_K8S_HELPER_IMAGE |
semaphoreui/helper:latest |
service_account |
SEMAPHORE_RUNNER_K8S_SERVICE_ACCOUNT |
default |
pull_secrets |
SEMAPHORE_RUNNER_K8S_PULL_SECRETS |
|
poll_interval_seconds, cleanup_grace_seconds |
…_POLL_INTERVAL_SECONDS, …_CLEANUP_GRACE_SECONDS |
3, 30 |
CI により 2 つの新しいイメージが公開されます: semaphoreui/job (Ansible、Terraform、OpenTofu、Terragrunt、
paramiko) と semaphoreui/helper です。テンプレートは、テンプレートフォームの新しい
エグゼキューターイメージ フィールドで自身のタスク用のイメージを上書きできます (エグゼキューター機能が
ライセンスされていない場合は PRO にアップグレード バッジ付きで表示されます)。
ランナー接続には runner.connection.server_ca_cert_file と
runner.connection.skip_tls_verify も追加されました。
タスク向け JWT アイデンティティトークン
Semaphore は実行中のタスクに対して OIDC 風のアイデンティティプロバイダーとして機能できるため、プレイブックは 長期的な認証情報なしで Vault、クラウドの STS エンドポイント、または内部サービスに対して認証できます。

- テンプレートごとに タスクランナーに JWT を発行 で有効化し、1 つ以上の オーディエンス と
TTL (
jwt.max_ttlが上限) を設定します。 - タスクは
SEMAPHORE_JWT環境変数でトークンを受け取ります。 - トークンは ES256 (ECDSA P‑256) で署名され、ID のみを含みます:
task_id、project_id、template_id、user_idに加えて、標準のiss、sub、aud、exp、nbf、iat、jtiクレーム。 - 公開鍵は
GET /.well-known/jwks.jsonで公開されます。
サーバー設定:
"jwt": {
"enabled": true,
"issuer": "https://semaphore.example.com",
"default_ttl": "1h",
"max_ttl": "24h"
}
環境変数: SEMAPHORE_JWT_ENABLED、SEMAPHORE_JWT_ISSUER、SEMAPHORE_JWT_DEFAULT_TTL、
SEMAPHORE_JWT_MAX_TTL。
サーベイ変数
変数を環境変数として渡す
サーベイ変数に 変数の受け渡し方法 設定が追加されました: アプリ固有の CLI 方式 (Ansible では --extra-vars、
Terraform/OpenTofu では -var、シェルスクリプトでは CLI 引数) または プロセス環境変数 です。
変数名はそのまま使用されるため、Terraform ユーザーは単に TF_VAR_region と名付けるだけで済みます。
環境変数はプロセス一覧に表示されないため、シークレットにとってはより安全な選択肢です。

新しい型
int— 検証付きの数値入力;text— 複数行テキスト;enum— 名前/値のペアとデフォルト値を持つ再設計されたエディター。

タスクダイアログは各型をそれに応じて表示します:

既存の survey_vars JSON に保存されます — マイグレーションは不要です。
テンプレートとタスク
-
動的なプレイブックピッカー。 プレイブックファイルへのパス フィールドに、リポジトリ内で見つかった プレイブックが一覧表示されます (
GET /api/project/{id}/repositories/{repository_id}/playbooks)。一覧は 選択されたブランチに追従し、リポジトリを読み取れない場合は自由入力にフォールバックします。 -
Ansible Galaxy インストールのスキップ — テンプレートごとのオプションで、タスクごとに上書きも可能です。
requirements.ymlからのロールとコレクションのインストールをスキップします。 -
変数グループでの型付き変数 (数値を含む):

-
タスク履歴のページネーション。 履歴ページはこれまで最新の 200 件のタスクを取得してクライアント側で ページ送りしていたため、それより古いものにはアクセスできませんでした。バックエンドはキーセットカーソル (
?count=20&before=<task_id>、X-Has-Nextレスポンスヘッダー) を使って 1 ページずつ返すようになり、COUNT(*)もOFFSETも使いません。フッターには 1 ページあたりの行数 と前へ/次へのコントロールがあります。同じページネーションは テンプレートごとのタスク一覧とダッシュボードにも適用されます。
-
タスク一覧の再読み込みは最大でも 5 秒に 1 回になりました; 冗長なリクエストがいくつか削除されました。
-
スケジュールはサーバーサイドの cron パーサーで検証されるため、クライアントとサーバーの解釈が食い違わなくなりました。
-
タスクでのブランチ上書きは、テンプレートが許可している場合にのみ受け付けられます。
-
Git 操作はリポジトリディレクトリごとに直列化されます。 並列タスクを許可 が有効なテンプレートは 1 つの作業コピーを共有しており、同時に実行される
git pull/git checkoutがそれを破損させる可能性がありました。更新と チェックアウトは、ローカル実行とランナー実行の両方で、インベントリリポジトリを含めて単一のクリティカル セクションを形成するようになりました。
ランナー

-
ランナーページに、ハートビートの生存確認から導出される オンライン / オフラインステータス が表示されます。
-
ワンタイム登録トークン。 ランナーを先に UI で作成し、後から
smrs_…トークンで登録できます。 トークンは一度だけ表示され、SHA‑256 ハッシュとしてのみ保存され、1 時間で期限切れになります。 ダイアログには環境変数、設定ファイル、Docker 用のコピーしてすぐ使えるコマンドが表示されます。トークンを再生成すると 登録済みのランナーがリセットされ、再登録できるようになります。
SEMAPHORE_WEB_ROOT=https://semaphore.example.com \ SEMAPHORE_RUNNER_REGISTRATION_TOKEN=smrs_… \ semaphore runner register --config ./config.runner.json semaphore runner start --config ./config.runner.json -
ハングしたタスクのリカバリー。 ランナーはプロセスの開始時刻 (
X-Runner-Started-At) を送信します。ポーリングを 停止したランナーはrunners.offline_timeout_sec(120 秒) 後に オフライン としてマークされます: 新しいタスクは 割り当てられず、starting状態のタスクは再割り当てされます。runners.task_fail_timeout_sec(420 秒) 後には、running状態のタスクが明確なメッセージとともに失敗扱いになります。再起動してメモリ内のジョブプールを失った ランナーは即座に検出されます。整合処理はrunners.reconcile_interval_sec(30 秒) ごとに実行されます。 -
ランナーから再割り当てされたタスクは、元のランナー上で終了されます。
-
古いランナーへのフォールバックは廃止されました: すべてのランナーがオフラインの場合、最大 30 分間ポーリングしていない ランナーにディスパッチされる代わりに、タスクはキューで待機します。
-
ランナーごとの RSA 暗号化キーを削除。 ランナーとサーバー間の通信は TLS に依存します; これにより登録と
setupからキー交換ステップが削除されます。 -
ランナークライアントの TCP 接続リークを修正; 無効な登録トークンには
400を返します。
シークレットと暗号化
- 暗号化キーのローテーション。 新しい
encryptionブロックはラベル付きキーリングを記述します: インラインのkeys(値またはファイル)、またはファイル名をキー名とするファイルを格納したkeys_folder、さらにシークレットキーと オプションキー用のactiveポインター。暗号文にはキー ID が含まれるようになったため、一括再暗号化なしでキーを ローテーションできます。encryption.keys_fileとkeys_poll_interval(デフォルト15s) によりキーリングをホットリロードします。新しい CLI:semaphore vaults check;semaphore vaults rekeyは キーリングを中心に書き直されました。従来のフラットなaccess_key_encryptionも引き続き機能します。 option_encryption— データベースに保存されるオプション用の別のキー。- OpenBao シークレットストレージタイプ (Vault プロバイダー経由でルーティング) と専用アイコン。
- 静的な認証情報なしの AWS Secrets Manager — IAM ロールを使用 チェックボックス。
- Vault/OpenBao ストレージ向けの TLS 検証スキップオプション。
- 同期済みおよび読み取り専用のシークレットフィールドが更新時に消去されなくなりました。
オブザーバビリティ
- 名前空間付きデバッグログ。
--debug-filter/SEMAPHORE_DEBUG_FILTERで、どのサブシステムが デバッグ出力を行うかを Node.js のdebug風に選択します:runner、runner,task_pool、task_*、*、*,-db。 利用可能な名前空間:runner、task_pool、task_runner、task_logger、git、terraform、session、ldap、schedule、db、ha。フィルターはログレベルがDEBUGのときにのみ適用され、 レベルを引き上げることはありません。Syslog フックも同じフィルターに従います。 - ランナー、タスク、認証にわたって多数のコンテキスト付きデバッグ文を追加; 選択されたワークスペースが 起動時に出力されます。
セキュリティ

- パスワードの変更に現在のパスワードが必要になりました (CWE‑620)。
- 状態を変更するリクエストに対する Origin / Referer 検証 (CSRF 強化)。
- HTTPS 経由で配信される場合、セッションクッキーに
Secureが付与されます。 - ランナー登録トークンはハッシュ化して保存され、期限切れになります; ランナーごとの暗号化キーは削除されました。
- カスタムロールの作成時に呼び出し元の権限を確認します (権限昇格の修正)。
- Git URL の検証; 細工された ref がフラグとして解釈されないように git に
--end-of-optionsを渡します; コミットハッシュの形式チェック; リポジトリ閲覧前のブランチ検証; プレイブックパスの 検証。 - アクセスキーのペイロードとテンプレートの
appフィールドを検証します。 - JWT クレームには ID のみが含まれます — 名前やメールアドレスが外部システムに漏れることはありません。
- ランナートークンはプロジェクトのバックアップに書き込まれなくなりました。
- API は書き込みエラー後に処理を継続せず、部分的に書き込まれたレスポンスを返さずに終了します。
- セキュリティ SLA を
SECURITY.mdで公開; リリースアーティファクトは[email protected]の GPG キーで署名されています。
UI とローカライズ

- チェコ語 翻訳。
- テンプレートフォームの JWT セクションとスケジュールセクション用のドロップダウンカード。
- ライトモードでクリップボードにコピーするアイコンが表示されるように; 実行中タスクのスピナーを修正; テンプレートフォームの パディングを修正; ワークフローの Beta ラベル。
- インテグレーション変数の抽出で、JSON オブジェクトと配列を文字列化せずにそのまま保持します。
アップグレードに関する注意事項
破壊的変更と動作の変更
- BoltDB は廃止されました。
boltは有効なダイアレクトではなくなり、サーバーは “Bolt is not supported starting from version 2.19” というメッセージで起動を拒否します。先に SQLite、MySQL、または PostgreSQL に移行してください。 - ランナーの暗号化キーを削除。 サーバーとランナーの両方が 2.19 である必要があります。ランナーとサーバー間の 通信が TLS で保護されていることを確認してください。キーの存在を前提とするスクリプト化されたランナーのプロビジョニングは更新が必要です。
- タスク一覧 API はページネーションされます。
GET /api/project/{id}/tasks/lastはcountとbeforeを受け取ります;limitも引き続き受け付けますが、1 回のレスポンスで最新 200 件のタスクを得ることに依存していたクライアントはページ送りが必要です。 - 古いランナーへのフォールバックの廃止。 すべてのランナーがオフラインの場合、タスクはキューに留まります。
- 登録から ランナーの
activeフラグを削除。 - プロジェクトのバックアップにランナートークンが含まれなくなりました。
- SQLite:
v2.19.14はsessionテーブルとtaskテーブルを再構築 し、適切な外部キーを追加します (ユーザー削除を 修正)。孤立したセッションは削除されます。アップグレード前にデータベースをバックアップしてください。
新しい設定
jwt、runners、encryption、option_encryption、secrets_path、db.dialect、
runner.executor.{type,docker,k8s}、runner.connection.{server_ca_cert_file,skip_tls_verify}、
runner.registration_token_file、runner.token_file。すべて省略可能で、既存の設定はそのまま
機能します。config.schema.yaml と設定リファレンスドキュメントは再生成されました。
データベースマイグレーション
v2.18.6 (テンプレートの jwt_params)、v2.18.15 (ワークフローテーブル)、v2.19.2 (runner.started_at)、
v2.19.11 (project__workflow_node.task_params_id)、v2.19.12 (project__template.executor_image)、
v2.19.14 (SQLite の session/task 再構築)。MariaDB 12.1 とのマイグレーション互換性を修正。
パッチリリース
| バージョン | 変更内容 |
|---|---|
| 2.19.8 | SQLite マイグレーションを修正; ユーザー削除を修正 (session/task の外部キー); DB クエリで大文字小文字を区別しない文字列比較 |
| 2.19.9 | SEMAPHORE_RUNNER_EXECUTOR_TYPE 環境変数; 設定の omitempty の整理 |
| 2.19.10 | エグゼキューター設定の修正; Docker ビルドオプションの修正 |
| 2.19.11 | 選択されたワークスペースをログに出力; ヘルパーイメージの latest タグ; DB マイグレーションテスト |
| 2.19.12 | ランナー設定オプションの nil ポインターを修正; エラー伝播の修正 |
| 2.19.14 | 設定内の従来の secrets_path の処理を修正 |
依存関係
Go 1.26; go-git 5.19、go-oidc 3.19、golang.org/x/crypto 0.53、go-ldap 3.4.13、
modernc.org/sqlite 1.52。ドキュメントを git サブモジュールとして追加; THIRD-PARTY-LICENSES.md を再生成。
