メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

#77704accepted

x/crypto/acme: support standards compliant order finalization

ステータス変更: likely_accept accepted

要約

AIによる要約であり、誤りを含む場合があります。

概要

x/crypto/acme パッケージが、ACME仕様(RFC 8555)に厳密準拠したCA(証明書発行機関)でも証明書の発行(オーダーのファイナライズ)を行えるようにするため、新しいメソッド CreateCertFromOrder を追加する提案です。

ステータス変更

likely_acceptaccepted
2026年8月26日の提案レビュー会議で「likely accept」と判定された後、2週間の様子見期間中に反対意見が出なかったため、2026年9月9日の会議で正式に accepted となりました。議論は主にメソッド名の選定(bikeshedding)に集中し、技術的な設計自体には大きな異論がなかったことが承認を後押ししました。

技術的背景

現状の問題点

既存の Client.CreateOrderCert(ctx, url string, csr []byte, bundle bool) は、オーダーのファイナライズURLだけを引数に取ります。しかし、このメソッドはファイナライズのレスポンスに含まれる Location ヘッダーからオーダーのURI(ステータス確認用URL)を再構築する実装になっており、このヘッダーはRFC 8555の仕様上「ファイナライズ」アクションに対しては必須とされていません(§7.4の表でも「Location」の付与が明記されているのは「Create account」と「Submit order」のみ)。
Let's Encryptの本番CA実装であるBoulderはこのヘッダーを付与しているため、これまで問題になりませんでしたが、ACMEテストサーバーのPebbleは相互運用性向上のためこのヘッダーを意図的に削除しました(letsencrypt/pebble#509)。さらにBuypassのような実際のCAでもこのヘッダーが付与されないケースがあり、x/crypto/acme はこうした標準準拠CAに対してファイナライズ後のポーリングが空URL("")へのPOST-as-GETとなり失敗する、という互換性問題を抱えていました。

提案された解決策

既存の CreateOrderCert は後方互換性のためそのまま残しつつ、GodocにRFC 8555完全準拠CAでは動作しない可能性がある旨の注意書きを追加します。
新たに Order 型を直接引数に取る CreateCertFromOrder メソッドを追加します。このメソッドは Order.FinalizeURL をファイナライズPOST先として、Order.URIAuthorizeOrder 実行時に取得済みの、標準仕様で保証されている Location ヘッダー由来のURI)をポーリング先として利用するため、レスポンスの Location ヘッダーに依存しません。

これによって何ができるようになるか

Let's EncryptのBoulderだけでなく、BuypassなどLocationヘッダーを付与しないRFC 8555準拠のACME CAに対しても、証明書発行フローが正しく動作するようになります。ACMEクライアントの相互運用性が向上し、Pebble(テストサーバー)の仕様変更にも追従できます。autocert パッケージ内の呼び出し箇所は、いずれも既に Order を保持しているため、支障なく新APIへ移行可能とされています。

コード例

// Before: CreateOrderCert はファイナライズURLのみを渡し、
// レスポンスのLocationヘッダーに依存してオーダーURIを復元する
order, err := client.AuthorizeOrder(ctx, ids)
// ...
der, certURL, err := client.CreateOrderCert(ctx, order.FinalizeURL, csr, true)
// Locationヘッダーが無いCAではポーリングが失敗する
// After: Order自体を渡すことで、AuthorizeOrder時点で取得済みの
// 標準準拠のOrder.URIを使ってポーリングできる
order, err := client.AuthorizeOrder(ctx, ids)
// ...
der, certURL, err := client.CreateCertFromOrder(ctx, order, csr, true)

議論のハイライト

  • 提案当初のメソッド名 CreateOrderCert/CreateCertForOrder に対し、レビュー参加者から「名前が分かりにくい」との指摘があり、CreateCertFromOrder へ変更された。
  • 提案者(cpu氏)は「From」を選んだ理由として、RFC 8555上オーダーのファイナライズは一度限りの終端操作であり、同じオーダーから2回証明書を作ることはできない点を「From」がよく表していると説明した。
  • CreateOrderCert を非推奨(deprecated)にするかどうかも議題になったが、限定的な用途(Locationヘッダーを返すCA向け)では引き続き動作するため、非推奨化は見送られた。
  • 実装は既に go.dev/cl/817000 として提出されており、autocert の既存呼び出し箇所は全て Order を保持しているため新APIへの移行に問題はないと確認された。
  • 2週間の様子見期間で新たな反対意見が出なかったことが、最終的な accepted 判定の直接的な根拠となった。

関連リンク