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

Go Proposal Weekly Digest

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

#77704likely_accept

x/crypto/acme: support standards compliant order finalization

ステータス変更: active likely_accept

要約

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

概要

x/crypto/acmeパッケージの証明書発行API(CreateOrderCert)が、RFC 8555の仕様上は必須でないLocationヘッダーへの依存により、一部のACME準拠CA(Buypassなど)と互換性がない問題を解決するため、標準準拠の新メソッドCreateCertFromOrderを追加する提案です。

ステータス変更

activelikely_accept
2026年8月26日のproposal reviewミーティング(@aclements, @adonovan, @cherrymui, @griesemer, @ianlancetaylor, @neild, @rolandshoemaker参加)にて、「CreateOrderCertを非推奨化すべきか」という論点は「限定的な用途では現状も機能するため不要」と判断され、メソッド名についての議論(bikeshedding)を経てCreateCertFromOrderに決着したことで、大きな異論がない状態となり likely accept(承認見込み)となりました。最終的な承認可否は最終コメント期間(last call for comments)を経て決定されます。

技術的背景

現状の問題点

既存のClient.CreateOrderCertは、finalization URL(文字列)のみを引数に取り、CAからのfinalizationレスポンスに含まれるLocationヘッダーからOrder.URIを再構築してポーリングに利用しています。しかしRFC 8555 §7.4の仕様では、finalizationレスポンスにLocationヘッダーが含まれることは規定されておらず、Let's Encryptの実装であるBoulderがこの非標準的な挙動を提供していたために、多くのクライアント実装(x/crypto/acme含む)がこれに依存する形になっていました。ACMEテストサーバーPebbleが最近この非標準ヘッダーを意図的に削除したことで、x/crypto/acmeの統合テストが壊れ、BuypassなどLocationヘッダーを返さないCAとの非互換性が表面化しました。

提案された解決策

CreateOrderCertはそのまま残しつつ、Godocに「本メソッドはfinalizationレスポンスでLocationヘッダーを返すCAでのみ動作する」旨の注意書きを追加します。加えて、url string引数の代わりに*Orderを受け取る新メソッドCreateCertFromOrderを追加し、内部的にはOrder.FinalizeURLでfinalization POSTを行い、AuthorizeOrderで作成されたOrder.URI(新規注文レスポンスのLocationヘッダーから取得され、RFC 8555上必須)を用いてポーリングを行うことで、標準準拠のCAでも確実に動作するようにします。

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

これにより、開発者はRFC 8555準拠だがLocationヘッダーを省略するACME CA(Buypassなど)に対しても、x/crypto/acmeパッケージを使って証明書発行ワークフローを完結できるようになります。特にLet's Encrypt以外のCAを利用するTLS証明書自動化ツールや、autocertパッケージの内部実装(既存の呼び出し箇所はOrderを保持しているため、無理なく移行可能とされています)にとって有用です。

コード例

// Before: finalization URLのみを渡す(Location非対応CAでは失敗する)
order, err := client.AuthorizeOrder(ctx, ids)
// ...
der, certURL, err := client.CreateOrderCert(ctx, order.FinalizeURL, csr, true)
// Location ヘッダーがないCAでは、空文字列へのPOST-as-GETが発生しエラーになる
// After: Order自体を渡し、標準準拠のURIを利用
order, err := client.AuthorizeOrder(ctx, ids)
// ...
der, certURL, err := client.CreateCertFromOrder(ctx, order, csr, true)
// order.URI(新規注文レスポンスのLocationヘッダーに由来し、RFC 8555上必須)でポーリングするため、
// finalizationレスポンスのLocationヘッダーに依存しない

議論のハイライト

  • 提案当初はCreateCertForOrderという名称でしたが、レビューで「紛らわしい」との指摘があり、CreateCertFromOrder(@cpuが提案)・CreateCertWithOrderなどが候補に挙がり、最終的に「注文の終端操作である finalize を表すには"From"がふさわしい」との理由でCreateCertFromOrderに決定しました。
  • 既存のCreateOrderCertを非推奨(deprecated)にすべきかが議論されましたが、「限定的な用途(Locationヘッダーを返すCA向け)では引き続き機能するため」非推奨化は見送られ、Godocに注意書きを追加するのみとなりました。
  • 実装は既に提案時点でCL(go.dev/cl/817000)としてgopherbotにより投稿されており、設計と実装がほぼ並行して進んでいます。
  • autocertパッケージ内のCreateOrderCert呼び出し箇所はすべてOrderをすでに保持しているため、新APIへの移行に支障がないと提案者が明言しています。

関連リンク