x/crypto/acme: support for acme profiles
要約
概要
IETFで策定中の「ACME Profiles」ドラフト仕様(証明書発行時にプロファイル名で挙動を切り替える仕組み)に対応するため、Goのx/crypto/acmeパッケージにProfiles情報の取得とOrderへのプロファイル指定機能を追加する提案です。
ステータス変更
likely_accept → accepted
2026年7月23日のレビュー会議で「likely accept」と判定され、コメント期間を経て2026年7月29日の会議で異論が出なかった(no change in consensus)ため、正式にacceptedとなりました。実装作業(CL)は既に進行中で、この後はIssueが実装作業のトラッキング用として使われます。
技術的背景
現状の問題点
Let's Encrypt(Boulder/Pebble)は2026年1月に「短命証明書(short-lived certificates)」や「IPアドレス証明書」などの新しい発行モードを一般提供しましたが、これらはACMEのDirectoryエンドポイントに含まれるprofilesという新フィールドと、注文(Order)作成時にプロファイル名を指定する仕組みによって選択されます。この仕様(draft-ietf-acme-profiles)はx/crypto/acmeにはまだ実装されておらず、利用者はプロファイルを指定した証明書発行(例: 6日間有効な短命証明書やIPアドレス向け証明書)をGoから直接行えませんでした。
提案された解決策
ACMEサーバーのDirectoryにプロファイル一覧を保持するフィールドを追加し、Orderにプロファイル名を持たせられるようにします。最終的に合意された最小限のAPIは以下の通りです(レビュー中にtype ProfileName stringという名前付き型を使う方針に修正されましたが、説明文字列自体は単なるstringのままとされました)。
type ProfileName string
type Directory struct {
// ...既存フィールド...
// Profiles is a map of profile identifiers to the description of the
// profile. The identifiers can be used with WithOrderIssuanceProfile to
// request issuance with a specific profile. If the map is empty, the
// CA does not support issuance profiles.
Profiles map[ProfileName]string
}
type Order struct {
// ...既存フィールド...
// Profile is the optional issuance profile used for this order.
Profile ProfileName
}
// WithOrderIssuanceProfile sets the order's profile field. It should be used
// with a profile present in the CA's Directory.Profiles.
func WithOrderIssuanceProfile(profile ProfileName) OrderOption
これによって何ができるようになるか
- Let's Encryptが提供する「短命証明書(shortlived)」プロファイルを指定してTLS証明書を取得できるようになります。
- IPアドレス向け証明書プロファイルを使い、ドメイン名を持たないサーバー(IPのみで運用する環境)にも標準的な方法で証明書を発行できます。
- CAがサポートするプロファイル一覧を
Directory.Profilesから取得し、事前にプロファイル名の妥当性を確認した上でエラーハンドリングを行えます。
コード例
// Before: プロファイルを指定する標準APIが存在せず、
// 短命証明書やIP証明書を取得する手段がなかった(サードパーティのフォークや
// PRで独自対応するしかなかった)
client := &acme.Client{DirectoryURL: "https://acme-v02.api.letsencrypt.org/directory"}
order, err := client.AuthorizeOrder(ctx, acme.DomainIDs("example.com"))
// After: プロファイル名を指定して注文を作成できる
dir, err := client.Discover(ctx)
if _, ok := dir.Profiles["shortlived"]; !ok {
// プロファイル未対応のCAへは事前にエラーを返せる
}
order, err := client.AuthorizeOrder(ctx,
acme.DomainIDs("203.0.113.1"), // 将来的にはIPアドレスにも対応予定
acme.WithOrderIssuanceProfile("shortlived"),
)
議論のハイライト
- 当初(2025年3月〜6月)は@rolandshoemakerらが「x/crypto/acmeは仕様が固まる前に機能を取り込みすぎてきた歴史がある」ことを理由に慎重姿勢を示し、ドラフトがACME WGに正式採択されるまで保留とされました。
- 2026年1月、Let's EncryptがACMEプロファイル機構を用いた短命証明書・IPアドレス証明書のGA提供を開始し、ドラフトもWGに採択されたことで議論が再開しました。
Directory.Profilesの型について、単純なmap[string]stringにするか、より構造化した型(map[string]struct{Doc string}等)にするか議論がありましたが、ACME profilesドラフトの編集者である@aarongableが「複雑な提案はサードパーティからの思いつきであり支持しない」と述べ、シンプルな形を推す立場を示しました。- レビュー会議では、説明文字列自体は単純な文字列のままとしつつ、プロファイル識別子には
ProfileNameという名前付き型を導入する妥協案が採用されました。 - 承認後、
autocertパッケージ側での対応(IPアドレスをホストポリシーに渡すことで短命IP証明書フローを利用する案)についても追加の議論が始まっており、今後の実装過程で検討される見込みです。 - 実装は@cthayerによるPR(golang/crypto#336、短命IP証明書対応)や、issue内で共有されたフォーク実装が参考にされ、正式な実装CL(go.dev/cl/788000)が既に提出されています。