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

Go Proposal Weekly Digest

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

#77865active

crypto/x509: support SSL\\_CERT\\_FILE on darwin

新規提案

要約

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

概要

crypto/x509 パッケージにおいて、現在 Unix 系(macOS を除く)でのみ有効な環境変数 SSL_CERT_FILE および SSL_CERT_DIR を、darwin(macOS)でもサポートするよう提案するものです。これにより、Goプログラムのバイナリを変更せずに証明書の検証ルートをユーザーが制御できるようになります。

ステータス変更

(新規)active
2026年4月22日に開催されたProposal Reviewミーティングで active に昇格しました。@aclements による議事録では、SSL_CERT_FILE だけでなく SSL_CERT_DIR も合わせてサポートすること、および既存動作を維持するための GODEBUG=x509sslcertoverrideplatform の導入が検討されている旨が記録されています。@rsc は「業界標準として SSL_CERT_FILE は広く普及しており、サポートすべき」と明言しています。

技術的背景

現状の問題点

darwinでは、GoはデフォルトでmacOSのプラットフォーム証明書検証機構(trustd デーモン経由)を使用します。そのため SSL_CERT_FILE は明示的に無視されており、Unix系の他OSとは異なります。
問題が顕在化するシナリオとして、サンドボックス環境などで com.apple.trustd.agent へのアクセスが制限される場合があります。このような環境では、ghterraformkubectl などのGoで書かれたCLIツールがTLS証明書の検証に失敗してしまいます。
また、Goバイナリを直接変更できない状況(サードパーティのGoプログラムなど)では、x509.SetFallbackRoots() による回避策も取れません。

// 現在のワークアラウンド(バイナリを変更できる場合のみ有効)
roots := x509.NewCertPool()
roots.AppendCertsFromPEM(certData)
x509.SetFallbackRoots(roots)
// さらに GODEBUG=x509usefallbackroots=1 の設定も必要

現在の SystemCertPool() のドキュメントには以下のように明記されています:

On Unix systems other than macOS the environment variables SSL_CERT_FILE and SSL_CERT_DIR can be used to override...

提案された解決策

SSL_CERT_FILE(および SSL_CERT_DIR)が設定されている場合、darwinでもその値を尊重し、プラットフォーム検証器の代わりにGoネイティブの検証器へフォールバックする。
後方互換性の問題を軽減するため、新たに GODEBUG=x509sslcertoverrideplatform を導入することが検討されています:

  • デフォルト値 1: SSL_CERT_FILE/SSL_CERT_DIR を尊重する(新しい動作)
  • 0: 従来の動作(darwinでは変数を無視)を維持する
    なお、Linuxではプラットフォーム検証器自体が SSL_CERT_FILE を参照するため、このGODEBUGの設定はLinuxには影響しません。

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

コード例

// Before: darwinでは SSL_CERT_FILE を設定しても無視される
// $ SSL_CERT_FILE=/path/to/custom-ca.pem my-go-program
// → Goが trustd デーモンを使って検証するため、カスタムCAは無視される
// After: SSL_CERT_FILE が設定されていれば、Goネイティブ検証器へフォールバック
// $ SSL_CERT_FILE=/path/to/custom-ca.pem my-go-program
// → Goが /path/to/custom-ca.pem に含まれるCAを使って証明書を検証する

実践的なユースケース:

  1. サンドボックス環境: trustd へのアクセスが制限された実行環境(コンテナやセキュリティ制限されたサンドボックス)で、GoのCLIツールが正常にTLS接続できる
  2. 開発・テスト: 自己署名証明書を使うローカル開発環境やテスト環境で、バイナリを変更せずにカスタムCAを信頼させられる
  3. 企業環境: 企業の中間CA証明書を全社的な設定ファイルや環境変数で管理しており、Go製ツール(Terraform, kubectl等)にも一貫して適用したい場合

議論のハイライト

  • SSL_CERT_DIR も合わせて対応: @aclements が「SSL_CERT_FILE を対応するなら SSL_CERT_DIR も対応すべき(残念ながら)」と言及。一貫性のためセットで実装される見込み
  • 後方互換性の懸念: 既存の文書では「darwinでは SSL_CERT_FILE は無視」と明記されており、これを変更すると動作変化が生じる可能性がある。偶然この変数を設定しているプログラムに予期しない影響が出るリスクへの対応として GODEBUG が提案された
  • #71924との関係: @FiloSottile は「これは #71924(全プラットフォームでのシステムルートオーバーライド提案)のサブセット」と指摘したが、@rsc は「業界が SSL_CERT_FILE に標準化しているのだから、この個別提案として進めるべき」と反論し、独立したproposalとして推進することになった
  • Linuxとの動作差異の明確化: Linuxでは trustd のような仕組みがないため、プラットフォーム検証器自体が SSL_CERT_FILE を使用しており、本変更の影響を受けない
  • 動機の具体性: Anthropicのサンドボックスランタイムにおける実際の障害事例(Go製CLI多数が trustd ブロックにより機能不全)が具体的なユースケースとして示され、proposalの必要性を裏付けた

関連リンク