
Semaphore UI 2.20 は、SIEM エクスポートを備えた 監査ログ を追加し、遅延ノード、リビジョン、タスク間で 受け渡される出力、ワークフロー変数によって ワークフロー を本格的なパイプラインエンジンへと成長させ、 1 人のメンバーが複数を保持できるように ロール を再構築して管理者にインスタンス全体のロールと IdP グループマッピングを提供し、ホストごとの SSH および Git 認証情報のための ホスト設定 を導入し、 Ansible のすべての追加変数を Vault で暗号化されたファイル に移し、Prometheus メトリクス を公開します。
この系列は v2.20.0 から始まります。パッチリリースは、公開され次第このページの末尾に一覧されます。
ハイライト
- 監査ログ — 誰が、どこから、何を行い、どのような結果になったか; 管理画面、保持期間、SIEM 向けの Syslog / Splunk HEC エクスポート (エクスポートとフィルターは Pro)。
- ワークフロー — 遅延ノード、実行に固定されるイミュータブルなリビジョン、次のタスクの入力として 受け渡される出力、実行ダイアログで尋ねられるワークフロー変数、ホットキーと元に戻す操作に対応した 再設計されたエディター、ワークフローを開始する Webhook。
- メンバーごとの複数ロール、id と slug を持つロール、インスタンス全体の権限を持つ グローバルロール (Pro)、サインイン時に適用される IdP グループ → ロールのマッピング (Enterprise)。
- 外部アイデンティティ — LDAP と OIDC のログインは、メールアドレスではなくプロバイダーの安定した id で アカウントに紐付けられます; 1 つのログインページに複数の LDAP ディレクトリ。
- ホスト設定 — SSH ホストと Git URL をプロジェクトの認証情報にマッピングし、クローン、Galaxy、 Terraform モジュール、Ansible に適用します。
- Ansible の追加変数がコマンドラインに載ることはなくなりました; シークレットは Ansible Vault で 暗号化されたファイルで受け渡され、値に含まれる Jinja2 は評価されなくなりました。
- テンプレート: Ansible の作業ディレクトリ、一意な名前とタスク API の
template_name、エラー通知の抑制、 Dry Run / Diff の非表示、Galaxy インストールオプション、複数選択のサーベイ変数、リモートランナーでの サーベイシークレット。 - モノレポのリポジトリ はテンプレート間で 1 つのチェックアウトを共有します; Git のリトライ、 サブモジュールの並列フェッチ、SSH ホストキーの検証。
/api/metricsの Prometheus メトリクス。- サーバー上での SSH キーペアの生成 と、Key Store からの公開鍵のコピー。
監査ログ

Semaphore は、セキュリティに関連するイベントを専用の追記専用ログに記録するようになりました。 次の設定で有効化します:
"audit": {
"enabled": true,
"instance_id": "semaphore-prod"
}
(SEMAPHORE_AUDIT_ENABLED、SEMAPHORE_AUDIT_INSTANCE_ID; instance_id は必須で、すべてのイベントで
インストール先を識別します。)
記録される内容。 8 つのカテゴリーにわたる 116 種類のイベント: auth (サインイン、サインアウト、MFA、
API トークンの拒否、拒否されたリクエスト、CSRF ブロック)、iam (ユーザー、パスワード、API トークン、
アイデンティティ、メンバーシップ、ロール、テンプレート権限)、resource (プロジェクト、バックアップ、
インベントリ、リポジトリ、テンプレート、スケジュール、インテグレーション、ホスト設定、ワークフロー、
変数グループ)、secret (認証情報とシークレットストレージ)、task (トリガーを伴う開始、結果と所要時間を伴う
完了、承認、停止、履歴の削除)、runner (登録、変更、拒否されたレポート)、system (設定、ライセンス)、
そして audit 自身 (開始、保持期間、エクスポート)。パスワード、トークン、シークレットの値、タスクの出力と
変数は一切書き込まれません。
イベントのエンベロープ。 すべてのイベントは、UUID、欠番のないシーケンス番号、マイクロ秒精度の UTC
タイムスタンプ、アクター (ユーザー / 匿名 / システム / ランナー / インテグレーション。セッションまたは
API トークン認証とトークンのフィンガープリントを伴う)、送信元 IP と User‑Agent、対象、プロジェクト、
リクエスト id (X-Request-ID レスポンスヘッダーでも返されます)、インスタンス id、HA ノード id を保持します。
結果は success または failure で、理由はクローズドリストから選ばれます; オブジェクトは保存されたものの
後続のステップで失敗したアクションは、partial = true を伴う success になります。リバースプロキシの背後では、
X-Forwarded-For は audit.trusted_proxy_cidrs からのみ信頼されます。

管理画面。 ユーザーメニューの 監査ログ (/audit-log) は、イベントを新しい順に 1 ページ 50 件で
一覧し、古い / 新しい でページ送りできます; 行をクリックすると 誰が、対象、どこから、いつ、
詳細、技術情報 の各セクションと、イベントを SIEM に送信される JSON としてコピーするボタンを備えた
カードが開きます。アクセスには新しい 監査ログの閲覧 グローバル権限が必要です。
保持期間。 audit.retention_days は古いイベントをバッチで削除します。HA ノードが衝突しないよう
ジッターを加えて 1 時間ごとに実行され、何かを削除したパスはそれ自体が記録されます。
Pro: フィルターとエクスポート。 期間、ユーザー、プロジェクト、イベント種別、結果、IP でフィルタリング できます; カードの任意の値を起点に絞り込み、現在の選択範囲を CSV または JSON Lines としてエクスポートできます。
Pro: SIEM エクスポート。 受信側がダウンしていても取りこぼしがないよう、それぞれ独自のカーソルを持つ
2 つの宛先があります: audit.syslog による TLS 上の Syslog (RFC 5424、イベント JSON を本文とする) と、
audit.splunk_hec (url、token、index、source、sourcetype、ca_file、…) による
Splunk HTTP Event Collector です。配信は at‑least‑once で、シーケンス順に並びます; HA では宛先ごとに
1 ノードだけがエクスポートを行い、Redis のリースで調整されます。エクスポーターは 3 つの Prometheus 系列で
表されます: semaphore_audit_export_pending_events、semaphore_audit_export_oldest_pending_seconds、
semaphore_audit_export_errors_total。
ストレージ: テーブル audit_event、audit_event_sequence、audit_export_state (マイグレーション
v2.20.9〜v2.20.11)。API: GET /api/audit/events と GET /api/audit/events/export。
ワークフロー
ワークフローは Pro 機能です; Beta ラベルは外れました。
遅延ノード
タスク、承認、ノートに並ぶ 4 番目のノード種別: 遅延 は実行を指定した秒数だけ一時停止し、その後
エッジを解放します。実行ビューではカード上にカウントダウンがライブ表示されます; 実行を停止すると遅延は
キャンセルされます。フィールド delay_seconds、マイグレーション v2.20.2。
リビジョン
ワークフローを保存するたびにグラフの新しい リビジョン が作成され、実行は開始時点のリビジョンを固定します。
そのため、ワークフローを編集しても進行中の実行が変化することはなく、過去の実行のノードが孤立することも
ありません。エディターには rev. N チップと、古いリビジョンを実行中の実行がいくつ残っているかが表示されます;
実行ビューにはどのリビジョンを実行しているかが表示されます。どの実行からも参照されていないリビジョンは、
新しいリビジョンが保存された時点で削除されます。API: GET …/workflows/{id}/revisions と
…/revisions/{revision_id}。
出力と入力

タスクは後続のノードに構造化データを渡せます。ワークフローが開始したすべてのタスクには
SEMAPHORE_OUTPUTS_FILE が渡され、そこに JSON オブジェクトとして書き込んだ内容がそのタスクの
出力 になります:
cat > "$SEMAPHORE_OUTPUTS_FILE" <<EOF
{"image_tag": "1.4.2", "replicas": 3, "subnet_ids": ["subnet-1", "subnet-2"]}
EOF
Ansible は、同梱のコールバックプラグインを通じて ansible.builtin.set_stats で出力を生成します;
Terraform、OpenTofu、Terragrunt の出力は output -json から自動的に取得されます (sensitive な値は
スキップされ、未取得 として一覧されます)。出力はタスクが成功した場合にのみ読み取られます; 上限は
出力 100 個、1 個あたり 32 KB、1 ファイルあたり 256 KB です。
タスクノードへの接続は 入力を受け渡します — 接続元ノードの出力から、接続先テンプレートのサーベイ変数を 埋めます:
- 名前による (デフォルト): サーベイ変数と同じ名前を持つすべての出力がその変数を埋めます。
- 入力を明示的にマッピング: 受け渡す
variable ← output keyのペアを列挙します; ワークフローに完了した実行が あれば、パネルはその実行が生成したキーを候補として提示します。

値は変数の型に変換され、承認ノードと遅延ノードは出力をそのまま通過させます。明示的なマッピングは名前による
受け渡しより優先され、必須 の変数に値が与えられなかった場合はノードのタスクが開始前に失敗するため、
実行は 失敗時 のエッジをたどります。実行ビューはノードごとに N 件の出力 バッジを表示し、タスクダイアログには
出力 テーブルがあり、タスクログは受け渡された値ごとに Input "x" <- output "y" of node N の行で始まります。
出力は平文で保存され、secret 変数を埋めることはありません; secret を出力経由で渡すことはできません。
リモートランナー上のタスクも出力の生成と受け取りを行えます; Docker および Kubernetes エグゼキューターは
まだ出力を取得しません。

ワークフロー変数と実行ダイアログ
ワークフローは独自の サーベイ変数 を持ち、実行の開始時に Run “…” ダイアログで一度だけ尋ねられます
(変数のないワークフローは従来どおり即座に開始します)。回答は実行に保存され、実行キャンバスの上部にある
変数 ストリップにチップとして表示されます。そして、ノードパネルでの明示的な バインディング を
通じてのみタスクに届きます — ワークフロー変数が名前経由でテンプレートに漏れることはありません。シークレットは
ワークフロー変数として使用できません。POST …/workflows/{id}/runs は
{"environment": {"image_tag": "1.4.3"}} を受け取ります; 型に合わない回答や必須値の欠落は開始を拒否します。
ワークフロータスクの環境
ワークフローが開始したすべてのタスクは、SEMAPHORE_WORKFLOW_ID、SEMAPHORE_WORKFLOW_RUN_ID、
SEMAPHORE_WORKFLOW_URL (web_host が必要)、SEMAPHORE_OUTPUTS_FILE を受け取ります。これはすべての
アプリで、またリモートランナーでも有効です。
再設計されたエディター

- 種別タイル、ステータス、所要時間、出力バッジ、インラインの 承認 / 却下 を備えた新しいノードカード; その場で条件を変更できるドロップダウンと削除ボタンを備えたエッジラベル; ドットグリッドのキャンバス。
- ノードの
+ハンドル、キャンバスの右クリック、または空状態のボタンから開く クイック追加メニュー: ノード種別とタスクテンプレートを検索できる一覧で、新しいノードは 成功時 で接続されます。 - 元に戻す / やり直し (
Ctrl/⌘+Z、Ctrl/⌘+Shift+Z)、ワークフロー名のインライン変更、問題のある ノードにフォーカスする 問題 メニュー、未保存の変更を示す 保存 バッジ、ページ離脱時の警告。 - キャンバス上の ホットキー: 矢印キーでパン (
Shiftで大きく移動)、+/-でズーム、0でグラフ全体を 表示、1でズームをリセット、Escで選択を解除; ノードカードはキーボードでフォーカスできます。 - フローティングコントロール: ズームイン / アウト、全体表示、整列 自動レイアウト、ズーム率。
- 1 つのシェブロンでパレットとメインナビゲーションをまとめて折りたたみ、その状態は記憶されます。
- トラックパッドのオーバースクロールが macOS でブラウザーの「戻る」ジェスチャーを引き起こすことは なくなりました。

Webhook がワークフローを開始
インテグレーションは、テンプレートの代わりに ワークフロー を実行できるようになりました
(インテグレーションフォームの 実行対象: テンプレート / ワークフロー)。抽出されたすべての値が
ワークフローのサーベイへの回答になります。このようなインテグレーションの管理には Pro の
workflow_integrations_management 機能が必要です。テンプレートのインテグレーションでは、git_branch という
名前で抽出された Task Params の値が、テンプレートが上書きを許可している場合に開始されるタスクの
ブランチを設定します。
API の変更
POST …/workflows/{id}/run は POST …/workflows/{id}/runs に名称変更され、environment ボディを
受け取ります。実行の詳細には revision_id、revision、ノードごとの delay オブジェクト、
task.artifacts が含まれます。タスクに対してクライアントから渡された workflow_run_id、
workflow_node_id、artifacts は無視されるため、タスクが他人の実行のノードを装うことはできません。
ロールとアクセス制御
メンバーごとの複数ロール

プロジェクトメンバーは ロールのセット を保持し、チームページでチップとして編集します。API は従来の
role に加えて roles: ["manager", "release_approver"] を受け取ります; レスポンスはロールが 1 つだけの
メンバーに対してのみスカラーの role を保持します。管理者以外は、最後のオーナーから組み込みの Owner
ロールを外すことはできません。
id、slug、スコープを持つロール
ロールは整数の id と slug (^[A-Za-z0-9_-]{1,100}$、フォームでは名前から導出) を持つ行になりました;
4 つの組み込みロールも行として扱われ、カスタムロールで隠されることはなくなりました。ロールは スコープ
を持ちます: 組み込み、共有 (任意のプロジェクトで使用可能)、プロジェクトのいずれかです。使用中のロールを
削除すると、その影響範囲 (メンバー、プロジェクト、テンプレート権限、マッピング) とともに 409 が返され、
?force=true を付けて再実行できます — UI では 割り当てごと削除 です。マイグレーション v2.20.12 と
v2.20.13 がロールテーブルを再構築します; アップグレードに関する注意事項を参照してください。
グローバルロールと権限 (Pro)

インスタンス全体の権限は、もはや管理者フラグだけではありません。グローバルロール は 4 つの権限 —
ユーザーの管理、グローバルロールの管理、システム設定の管理、監査ログの閲覧 — のマスクを付与し、
Users ページの Roles タブ (/users/roles) およびユーザーダイアログの グローバルロール タブで
ユーザーに割り当てます。後者には有効な権限と、どのロールがそれを付与しているかも表示されます。すべての
管理ルートは 4 つのビットのいずれかで保護されます; GET /api/user は global_permissions を返します。
インスタンスには常に少なくとも 1 人の管理者が残り、これは HA ノード間でも安全な行ロックで強制されます。
ユーザーの管理 を持つユーザーは、管理者や、自分が持たない権限を保持するユーザーを編集できません。
API: /api/global-roles、/api/users/{id}/global-roles、/api/users/{id}/global-permissions、
カタログは /api/global-roles/permissions。
グループロールマッピング (Enterprise)

新しい グループマッピング ページ (/role-mappings) で、アイデンティティプロバイダーのグループを
プロジェクトのロールにマッピングします: プロバイダー、グループ、プロジェクト、ロール。OIDC でサインインする
たびに、ユーザーのマッピング済みロールはトークン内のグループ (プロバイダーの groups_claim) に一致するよう
更新されます。マッピングされたロールはチームページに provider: group のツールチップ付きのロックされた
チップとして表示され、メンバーロールとして削除することはできません; マッピングされたロールはプロジェクトの
最後のオーナーとしてはカウントされません。パスワードまたは LDAP でのサインインはグループ情報を伴わないため、
マッピング済みロールをクリアします。API: /api/role_mappings。
認証とアイデンティティ

- 外部アイデンティティ。 LDAP と OIDC のログインは、メールアドレスではなくプロバイダーの安定した id
(OIDC の
sub、LDAP の DN) によって、新しいuser__external_identityテーブルで Semaphore アカウントに 紐付けられます。これにより、入力された任意のアドレスを受け入れる IdP が他人のアカウントを取得して しまう種類のバグが解消されます。external_auth_email_matching(デフォルトはauto、他にalways、never) は、アイデンティティを持たない既存の外部ユーザーを一度だけメールアドレスで照合してよいかを 制御します; ローカルのパスワードアカウントが取得されることはありません。OIDC のメールアドレスは、email_verifiedが真で、かつプロバイダーがrequire_verified_emailを設定している場合にのみ有効です。 ユーザーはアカウントダイアログで自分のアイデンティティの紐付けと解除を行えます (/api/users/{id}/identities、POST /api/user/identities/ldap、/api/auth/oidc/{provider}/login?link=1)。 - 複数の LDAP ディレクトリ。
ldap_providersは名前付きディレクトリのマップで、それぞれが独自の サーバー、バインド、検索、マッピング、色、並び順を持ちます; 従来のフラットなldap_*ブロックは プロバイダーldapとして引き続き機能します。ログインページはタブが複数ある場合に切り替えを表示し、 内部タブがディレクトリにパスワードを送信することはありません。GET /api/auth/loginはldap_providersとlogin_with_passwordを返します。 - LDAPS 証明書はデフォルトで検証されます。 自己署名証明書の場合は
ldap_tls_skip_verify(フラットなブロック) またはプロバイダーごとのtls_skip_verifyを設定してください。 - セッションの絶対的な有効期間。
auth.max_session_life_hours(SEMAPHORE_AUTH_MAX_SESSION_LIFE_HOURS) は、アクティビティに関係なくログインから一定時間後に セッションを期限切れにします;0では無操作タイムアウトのみが有効です。 - プロジェクトを持たず、作成も許可されていないユーザーには、送信できないフォームの代わりに
プロジェクトがまだありません ページが表示されます; その場合
POST /api/projectsは403を返します。 - ユーザーメニューで選択した言語はサーバーに保存され、ブラウザーをまたいでユーザーに追従します
(
/api/user/optionsのlang)。
ホスト設定

新しいプロジェクトページ ホスト設定 は、SSH ホスト と Git URL をプロジェクトの認証情報に マッピングします:
- ホスト マッピング (
bastion.example.com) は、生成されるssh_configのHostブロックとして SSH キーを割り当てます; - URL マッピング (
https://github.com/acme/、/で終わるプレフィックスはグループ全体をカバー) は、 Git のinsteadOfによる書き換えとして SSH キーまたはログイン/パスワード (HTTPS のみ) を割り当てます; 最も具体的な URL が優先されます。
マッピングは、テンプレートのリポジトリとそのサブモジュール、requirements.yml のロールとコレクション、
terraform init のモジュール、プレイブックが実行する git コマンド、インベントリリポジトリとインベントリ
ホスト、そしてブランチとプレイブックの閲覧に適用され、リモートランナーにも配布されます。秘密鍵がディスクに
書かれることはありません — マッピングごとに 1 つの SSH エージェントを起動し、IdentityAgent でバインド
します; パスワードは GIT_CONFIG_PARAMETERS 経由で渡され、リポジトリ URL はタスクログ内で秘匿されます。
マッピングから参照されているキーは削除できません。マッピングはプロジェクトバックアップに含まれます。
git_client: cmd_git が必要です。テーブル project__host_config、マイグレーション v2.20.7;
API は /api/project/{id}/host_configs。
テンプレートとタスク

-
Ansible の作業ディレクトリ。 別の作業ディレクトリ を指定すると、リポジトリのサブディレクトリから
ansible-playbookを実行します; パスはチェックアウト内に収まっていなければなりません (working_directory、マイグレーションv2.20.3)。 -
プロジェクトごとに一意なテンプレート名 (マイグレーション
v2.20.4)、およびPOST /api/project/{id}/tasksはtemplate_idの代わりにtemplate_nameを受け取ります。 -
テンプレートごとのエラー通知の抑制 — 既存の成功時の抑制に並ぶ設定です; メール通知が初めて両方を 尊重します (
suppress_error_alerts、マイグレーションv2.20.5)。 -
テンプレートごとにタスクダイアログから Dry Run / Diff を非表示 にできます; サーバー側もその テンプレートに対して
--check/--diffを付加しなくなります (task_params.hide_dry_run、hide_diff)。 -
Galaxy インストールオプション — Galaxy インストールをスキップ、
ansible-galaxy role installとcollection install向けの個別の CLI 引数 (フラグは許可リスト方式で、--token、--api-key、 パス系フラグは拒否されます)、タスクごとの上書きプロンプトをまとめた折りたたみ可能なセクション。 -
プレイブックピッカー は入力に応じてサブディレクトリを一覧し、アプリごとにフィルタリングします (Ansible は
.yml、Terraform / OpenTofu / Terragrunt / Pulumi はトップレベルディレクトリ、.sh、.py、.ps1)。Ansible のレイアウトディレクトリとドットディレクトリはスキップし、エントリ数は 30 件が 上限で、リポジトリルートに限定された浅いクローンを閲覧します。 -
複数選択のサーベイ変数 — 新しい
select型は複数の値を受け取り、タスクダイアログではチップとして 表示されます;default_valueは配列でも構いません。
-
サーベイシークレットがリモートランナーに届きます。 これまで
secretのサーベイ回答はランナー上で 空のまま届いていました。現在はタスクに紐付くアクセスキー (access_key.task_id、expire_at、 マイグレーションv2.20.1) として暗号化して保存され、ランナーを処理する HA ノードが復号し、タスク終了時に 削除され、1 時間ごとに掃除されます; Key Store、バックアップ、キー API からは隠されます。 -
YAML 形式の追加変数。 変数グループエディターに テーブル | JSON | YAML の切り替えとフルスクリーン エディターが追加されました; 変換は厳格です (日付は文字列のまま、オブジェクト以外のルートと非有限の数値は 拒否されます)。保存形式は変更ありません。

-
タスクページは、タスクを開始した スケジュールまたはインテグレーション の名前とリンクを表示し、 削除済みの発生元は
#id (deleted)と表示します。ログをコピーする際にタイムスタンプが選択されることは なくなりました。 -
スケジュール は保存前にサーバー側で式を検証するため、
@hourlyが受け付けられるようになり、 タイムゾーンのバナーは閉じられるようになりました。
-
ローカルタスクの停止はそのプロセスグループ全体を終了させます:
SIGTERM、15 秒の猶予、その後SIGKILL; 孤立したsshやプロバイダープロセスがタスクより長く生き残ることはなくなりました。停止された Terraform の plan は続行しなくなり、SIGTERMで0を返した plan が成功として読み取られることも なくなりました。 -
インベントリの
repository_idはfile型でのみ保持され、プロジェクトに属していなければなりません。 -
サーバーログの Task added to queue / Task started エントリにユーザー名が記録されます。
シークレットと Ansible Vault
-
追加変数はコマンドラインではなくファイルで受け渡されます。 変数グループ、サーベイの回答、 ワークフローの入力、タスクの詳細は
0600の YAML ファイルに書き出され、--extra-vars @fileとして 渡されます。シークレット —secretのサーベイ回答と変数グループのシークレット — は、ネイティブな Go 実装によって Ansible Vault 1.1 / AES‑256 形式で暗号化された 2 つ目のファイルに入り (ansible-vaultバイナリは不要)、ansible-playbookの--vault-id <uuid>@promptに応答する 使い捨てのパスワードで復号されます。値もパスワードもpsに現れず、どちらのファイルもタスク終了時に 削除されます。 -
値の中の Jinja2 はコードではなくデータです。
{{、{%、{#または#jinja2:ヘッダーを含む すべての文字列には再帰的に!unsafeタグが付けられるため、{{ lookup('pipe', 'id') }}のような サーベイ回答はそのままリテラルとして渡されます。デリミターを含まない文字列は意図的にタグ付けされません: ansible‑core 2.19 以降は!unsafeスカラーを再解決するため、"2026.08"が浮動小数点数になって しまうからです。 -
新しい
extra_varsデバッグ名前空間 (SEMAPHORE_DEBUG_FILTER=extra_vars) は、変数がどのように分割され 書き出されたかをログに記録します — 名前、ファイル、サイズのみで、値は記録しません。 -
サーバー上での SSH キーペアの生成。 Key Store の SSH キーを生成 は RSA キーを作成します; 公開鍵はキーとともに保存され、表示 / 非表示 とコピーボタン付きで表示され、作成直後にダイアログで 提示されます (
generate_ssh_key)。
-
キーの更新では、上書き が設定されている場合にのみ
type、secret、公開鍵部分が書き込まれるため、 クライアントがシークレットを差し替えずにキーのペイロードを変更することはできません。 -
dirs.secrets配下のサーバーの 環境変数またはファイル から認証情報を読み取る方法がドキュメント化 されました (Key Store フォームの Env / File タブ)。
リポジトリと Git
- モノレポ: すべてのテンプレートで単一のチェックアウト。 リポジトリのオプションにより、テンプレート
ごとにコピーを作る代わりに、リポジトリを 1 回だけクローンしてテンプレート間で共有します; チェックアウトは
fetch と pull の間ロックされ、タスクはその後並列に実行されます。そのようなリポジトリのテンプレートは
独自のブランチを持てず、そのタスクはブランチやコミットを上書きできません (
monorepo、マイグレーションv2.20.11)。 - Git のリトライ。
cloneとpullは、最大 1 分に制限された指数的な遅延でリトライされます;git_attempts(SEMAPHORE_GIT_ATTEMPTS、デフォルト4)。 - サブモジュールの並列処理。
git_submodule_jobs(SEMAPHORE_GIT_SUBMODULE_JOBS、デフォルト4) が--jobsとして渡されます。 - SSH ホストキーの検証。 新しい
sshセクション:config_path、known_hosts_file(SEMAPHORE_SSH_KNOWN_HOSTS_FILE)、strict_host_key_checking—no(デフォルト)、yes、accept-new— が SSH 経由の Git に適用されます。 - リポジトリの閲覧はブランチごとにキー付けされた浅いクローンを使用します; 認証情報はベアメタルの クローンではパーセントエンコードされ、ログとイベントフィードでは秘匿されます。
ランナーとインテグレーション
-
runner.check_interval_seconds(SEMAPHORE_RUNNER_CHECK_INTERVAL_SECONDS、デフォルト5) は ランナーのポーリング間隔を設定します; Runners ページの 詳細オプション スイッチにより、生成される env、設定、Docker のスニペットに反映されます (v2.19.17で出荷)。 -
runner.connection.timeout_seconds(SEMAPHORE_RUNNER_CONNECTION_TIMEOUT_SECONDS、デフォルト3) は、 接続、TLS ハンドシェイク、レスポンスヘッダーをそれぞれ個別に制限します; ログのアップロードは 打ち切られません。 -
runners.default_global_runners_mode(SEMAPHORE_DEFAULT_GLOBAL_RUNNERS_MODE:disable、prefer、require) が非推奨のuse_remote_runnerを置き換え、runners.registration_tokenが トップレベルのrunner_registration_tokenを置き換えます。 -
SEMAPHORE_DEBUG_FILTER=runnerによるサーバーサイドのランナー診断: トークン拒否の理由、再起動と オンライン検出、拒否された進捗レポート、ディスパッチのトレース。 -
ランナーの
unregisterリクエストは認証されます; ランナークライアントは HTTP リダイレクトを拒否します。 -
既存の HMAC‑SHA256 に並ぶ HMAC‑SHA512 の Webhook 認証 (
hmac-sha512); 署名ヘッダーは設定可能です。
-
インテグレーションが別のプロジェクトに属する Webhook は拒否されます。
オブザーバビリティ
-
Prometheus メトリクス。 静的なサービス認証情報による HTTP Basic 認証の背後に置かれた
GET /api/metrics:"metrics": { "enabled": true, "username": "prometheus", "password": "…" }(
SEMAPHORE_METRICS_ENABLED、SEMAPHORE_METRICS_USERNAME、SEMAPHORE_METRICS_PASSWORD。) 系列:semaphore_tasks_running、semaphore_tasks_total{status}、標準のgo_*およびprocess_*コレクター、 そして Pro では監査エクスポートのゲージ。 -
新しいデバッグ名前空間
extra_varsとrunner; リポジトリの閲覧では Git の出力を DEBUG レベルで 記録します。 -
プロジェクトバックアップのエクスポートとリストアがログに記録されます。
セキュリティ
- メールアドレスではなくプロバイダー id によるアイデンティティの紐付け; LDAPS 証明書の検証をデフォルトで 有効化。
- 追加変数をコマンドラインから排除; シークレットは Vault で暗号化; 値に含まれる Jinja2 は評価しません。
- クライアントのタスクから偽装された
workflow_run_id、workflow_node_id、artifactsを除去。 - 管理ルートは管理者フラグではなく明示的なグローバル権限で保護; 未知の権限ビットは拒否; ユーザー管理における権限昇格ガード。
- プレイブックピッカーをリポジトリルートに限定 (
OpenRoot)、件数を制限しフィルタリング。 - 追加変数のルートと YAML の数値を検証; Galaxy の CLI 引数を許可リスト化。
- リポジトリの認証情報をログとイベントフィードで秘匿; Git の設定パラメーターで
=をエスケープ。 - 監査エンドポイントはクロスサイトの読み取りと不正なカーソルを拒否; 信頼するプロキシのネットワークを検証。
- ランナーの
unregisterを認証; ランナークライアントはリダイレクトを拒否。 - ローカルタスクをプロセスグループごと停止。
アップグレードに関する注意事項
破壊的変更と動作の変更
- テンプレート名はプロジェクトごとに一意である必要があります。 マイグレーション
v2.20.4が一意 インデックスを追加します; アップグレード前に重複をリネームしてください。 - ロールテーブルが再構築されます (
v2.20.12/v2.20.13)。先にバックアップしてください。slug が 組み込みロールや他のロールと大文字小文字を区別せずに衝突するカスタムロールはリネームされます (ログに記録)。解決できないロールを指すテンプレート権限は削除されます (ログに記録)。メンバーシップはproject__user_roleに移り、project__user.roleカラムは削除されました。 GET /api/project/{id}/usersは、ロールが 1 つだけのメンバーに対してのみroleを返します —rolesを読んでください。/roles*の移行: 管理者フラグから グローバルロールの管理 権限へ; 管理者は影響を 受けません。- LDAPS 証明書はデフォルトで検証されます。 自己署名証明書の場合は
ldap_tls_skip_verifyまたは プロバイダーのtls_skip_verifyを設定してください。 ansible-playbookの呼び出し方が変わりました:--extra-vars @fileに加え、タスクにシークレットが ある場合は 2 つ目のファイルと--vault-id <uuid>@promptが使われます。これは vault を持たない テンプレートでも同様です。コマンドラインを解析するものや、vault のプロンプトを禁止するansible.cfgは 影響を受けます。- 追加変数の値に含まれる Jinja2 は評価されなくなりました。 Webhook やサーベイの値のテンプレート展開に 依存していたプレイブックは、それが機能しなくなります。
- ワークフロー実行エンドポイントの名称変更:
POST …/workflows/{id}/run→…/runs。 - モノレポのリポジトリはテンプレートの設定を上書きします: テンプレートごとのブランチはなく、タスクでの ブランチやコミットの上書きもできません。
- インベントリの
repository_idはfile以外のすべての型で削除されます。 - ローカルタスクの停止はそのプロセスグループを kill します (Windows には同等の仕組みがまだ ありません)。
- ワークフローの出力は Docker および Kubernetes エグゼキューターではまだ取得されません; サーベイ シークレットもこれらのエグゼキューターにはまだ届きません。
新しい設定
audit、metrics、auth.max_session_life_hours、ssh.{config_path,known_hosts_file,strict_host_key_checking}、
git_attempts、git_submodule_jobs、ldap_providers、ldap_tls_skip_verify、
external_auth_email_matching、OIDC プロバイダーごとの groups_claim と require_verified_email、
runner.check_interval_seconds、runner.connection.timeout_seconds、
runners.{default_global_runners_mode,registration_token}。すべて省略可能です。ポインター型の設定
フィールドを環境変数から設定できるようになりました。設定と CLI のリファレンスページはソースから
生成されます。
データベースマイグレーション
v2.20.0 外部アイデンティティ · v2.20.1 タスクに紐付くサーベイシークレット · v2.20.2 遅延ノード ·
v2.20.3 作業ディレクトリ · v2.20.4 一意なテンプレート名 · v2.20.5 エラー通知の抑制 ·
v2.20.7 ホスト設定 · v2.20.8 ワークフローリビジョン · v2.20.9〜v2.20.11 監査ログとインデックス、
エッジの入力マッピング、モノレポフラグ · v2.20.12〜v2.20.13 ロールテーブル、ワークフロー変数 ·
v2.20.14 ワークフローインテグレーションとグループマッピング · v2.20.16 グローバルロール。
依存関係
Go 1.26; Alpine 3.24 上の Docker イメージ; prometheus/client_golang 1.23 を追加; go-oidc 3.21、
go-ldap 3.4.14、golang.org/x/crypto 0.57、modernc.org/sqlite 1.59、logrus 1.10; フロントエンドは
js-yaml 5 と cron-parser 5.10。新しいワンクリックデプロイ: Cloudzy、RepoCloud、Pethost。
