接続先と資格情報はなぜ分けるか(sys_connection)
ServiceNow から外部システムへ連携するとき、必ず必要になるのが「どこへつなぐか(接続先)」と「だれとして認証するか(資格情報)」の2つです。ServiceNow はこれを別々のテーブルに分けて持っています。接続先は sys_connection(Connection)、ログイン用の資格情報は discovery_credentials(Credential)です。
この記事は、REST 連携や MID Server、Discovery、IntegrationHub を設定し始めた管理者・開発者を想定しています。PDI(Zurich / OOTB)で Connection と Credential を実際に開き、次を確認します。
接続先と資格情報がなぜ分離されているのか
資格情報の password がどう暗号化・マスクされるのか
認証方式を表す type
両者を束ねる Connection alias
OAuth 設定(oauth_entity)との役割分担
この記事で分かること
連携の「接続先」を sys_connection、「資格情報」を discovery_credentials が別々に持つこと
資格情報の password 系フィールドは暗号化(type=password2)で保存され、画面でも ●●● でマスクされること(復号できない)
認証方式を表す type(Basic Auth / SSH / SNMP / JDBC / Windows / OAuth 2.0 など全17種)
PDI 実機の件数(Connection 2件 / Credential 4件)と type の内訳
Connection が credential で資格情報を参照し、Connection alias が両者を束ねること
OAuth 設定(oauth_entity)と Credential の役割の違い
この記事の内容は ServiceNow の PDI(Personal Developer Instance)Zurich(ズーリッヒ)リリースの OOTB(初期設定)で確認した個人メモです。本番環境やカスタマイズ済み環境では、件数・type の内訳・フィールドが異なります。資格情報の実際の値(パスワード・トークン・秘密鍵)は一切取得しておらず、本文・画像にも含めていません。
Connection と Credential とは
外部連携を一言でいうと、「ある接続先に、ある資格情報でログインして通信する」ことです。ServiceNow はこの2つを意図的に分けています。接続先(host や protocol)を持つのが sys_connection(Connection)です。ログイン情報(ユーザー名やパスワード)を持つのが discovery_credentials(Credential)です。
下の画面は、PDI(Zurich / OOTB)の Credential 一覧です。アプリナビで「Connections & Credentials」を開くとたどり着きます。それぞれの資格情報に type(認証方式) と active が並び、パスワードそのものは一覧にも表示されません。

なぜ分けるのか。1つの資格情報を複数の接続先で使い回せるようにし、かつパスワードを資格情報側に隔離して暗号化するためです。接続先の情報(host など)は隠す必要がありませんが、資格情報は厳重に守る必要があります。役割を分けることで、この管理がきれいになります。

PDI(Zurich / OOTB)には、Connection が2件、Credential が4件ありました。いずれも Slack / Teams 連携(Sidebar)や MID Server 用のデモ用レコードです。Connection と Credential の責務を整理すると次のようになります。

sys_connection:接続先(どこへ)
sys_connection は「どこへつなぐか」を持つテーブルです。host(接続先ホスト)・protocol(http / https など)・port などの接続先情報と、使う資格情報への参照を持ちます。
下は PDI(Zurich / OOTB)の Connection 一覧です。2件とも HTTP(s) Connection(実体は子クラス http_connection)でした。sys_connection はベーステーブルで、実際のレコードは接続方式ごとの子クラスに入ります。

Connection のフォームを開くと、接続先と資格情報の参照がはっきり分かれているのが見えます。下は Slack 連携の Connection です。Host が slack.com、Protocol が https、そして Credential フィールドが資格情報レコードを参照しています。接続先(host/protocol)はここに、認証情報は参照先の Credential に、という分担です。

PDI 実機の2件は、どちらも公開エンドポイント(graph.microsoft.com / slack.com)を host に持ちます。credential で対応する資格情報を指していました。接続先と資格情報が別レコードに分かれていることが、ここで実機として確認できます。
discovery_credentials:暗号化された資格情報
discovery_credentials は「だれとして認証するか」を持つテーブルです。名前は Discovery 由来ですが、Discovery 専用ではありません。MID Server・IntegrationHub・Flow・送信側 REST 連携が共通で参照する資格情報ストアです。
参考:送信側 REST 連携
ここで最も重要なのが、パスワード系フィールドが暗号化されて保存される点です。下は Windows 資格情報のフォームです。Password 欄は ●●● でマスクされ、平文は表示されません。

このマスクは見た目だけではありません。password / authentication_key / privacy_key / ssh_passphrase は秘密情報のフィールドです。内部型は password2(暗号化フィールド) です。保存時に暗号化され、画面でも REST でもマスクされ、平文では取り出せません。実際、今回の調査でもこれらの値は一切取得できていません(取得していません)。

資格情報レコードの主なフィールドは次のとおりです。password 系の4フィールドが暗号化(password2)である点に注目してください。

このフィールド定義は、次のURLで自分のインスタンスでも確認できます(先頭の <YourInstance> は置き換えてください)。
https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=discovery_credentials^elementISNOTEMPTY
type:資格情報の認証方式
資格情報には、認証方式を表す type があります。Basic 認証、SSH、Windows 認証、OAuth 2.0 など複数の種類があります。この type によって、フォームに表示される項目(パスワードだけ/秘密鍵/コミュニティ文字列など)が変わります。
PDI(Zurich / OOTB)で type の選択肢を開くと、全17種ありました。

種類を整理すると次のとおりです。Basic 認証や SSH のような汎用的なものから、SNMP / JDBC / VMware / AWS のような対象システム特化のものまで揃っています。

PDI 実機の4件を type で集計すると、OAuth 2.0 が3件、Windows が1件でした。OAuth 2.0 の3件は Slack / Teams 連携(Sidebar)用、Windows の1件は MID Server のサービスアカウント用です。つまり OOTB のデモでも、外部 SaaS 連携には OAuth、オンプレ寄りの処理には Windows 認証、と type が使い分けられています。
Connection alias が両者を束ねる
接続先(Connection)と資格情報(Credential)が別レコードだとすると、連携処理はどうやってこの2つにたどり着くのでしょうか。その入口が Connection alias(sys_alias) です。
sys_connection には connection_alias(必須)というフィールドがあります。Flow や IntegrationHub のアクションは、このエイリアスを名前で指定します。エイリアスをたどると Connection(接続先)が決まり、Connection の credential をたどると Credential(資格情報)が決まります。PDI 実機でも、各 Connection は sn_oe_sfs.Sidebar_Slack_Credentials のような alias を持っていました。
この仕組みのおかげで、連携ロジックの中に host やパスワードを直接書かずに済みます。接続先や資格情報を後から差し替えても、エイリアスさえ同じなら連携処理は変更不要です。環境(開発/本番)ごとに接続先を切り替える設計が、これで自然に実現できます。
OAuth 設定(oauth_entity)との役割分担
type=oauth_2_0 の資格情報を見て、「OAuth 設定(oauth_entity)と何が違うのか」と迷う人もいます。両者は連携しますが、役割が違います。

discovery_credentials(type=oauth_2_0) … 「この接続でどの OAuth 認証を使うか」を表す資格情報レコード。Connection から credential で参照されます。
oauth_entity(OAuth 設定) … client_id / client_secret やトークンの取得・更新そのものを定義します。OAuth クライアント/プロバイダの設定です。詳しくは姉妹記事で扱っています。
ざっくり言えば3層構造です。
接続先=sys_connection
使う資格情報=discovery_credentials
OAuth のトークン発行元の定義=oauth_entity
なお、discovery_credentials から oauth_entity へつなぐ具体的な参照フィールドの詳細は、今回の検証範囲外です。
実機で確認するときに見るべきURL
最後に、今回見た画面を自分のインスタンスで開くためのURLをまとめます(<YourInstance> は置き換えてください)。
# 資格情報(Credential)一覧
https://<YourInstance>/discovery_credentials_list.do
# 接続先(Connection)一覧
https://<YourInstance>/sys_connection_list.do
# 資格情報の type 選択肢
https://<YourInstance>/sys_choice_list.do?sysparm_query=name=discovery_credentials^element=type^inactive=false^ORDERBYsequence
# 資格情報のフィールド定義(password が password2 になっている)
https://<YourInstance>/sys_dictionary_list.do?sysparm_query=name=discovery_credentials^elementISNOTEMPTYまとめ
外部連携は「接続先」と「資格情報」が必要。ServiceNow は sys_connection(接続先) と discovery_credentials(資格情報) に分離して持つ。
資格情報の password 系フィールドは暗号化(type=password2) で保存され、画面でも REST でも ●●● でマスクされる。平文では取り出せない。
資格情報には認証方式を表す type(全17種) があり、Basic Auth / SSH / SNMP / JDBC / Windows / OAuth 2.0 などを使い分ける。PDI 実機は OAuth 2.0 ×3 / Windows ×1。
Connection は credential で資格情報を参照し、Connection alias が両者を束ねる。連携ロジックに host やパスワードを直接書かずに済む。
OAuth では役割が3層に分かれる。接続先=Connection、資格情報=Credential、トークン発行元の定義=oauth_entity。
Connection & Credential が分かると、次のテーマが「接続先と資格情報を用意する → 認証する → 外部とメッセージをやり取りする」という連携の流れでつながって見えてきます。
送信側 REST 連携(REST Message)
OAuth 設定(oauth_entity)
ECC Queue
参考:送信側 REST 連携(REST Message) / OAuth 設定(oauth_entity) / ECC Queue