splunk-setup-page-builder について
Splunk アプリやアドオン向けに、非推奨の setup.xml を使わず初回起動時の設定ビューを作成するスキルです。通常設定とシークレットの保存先を分け、実装と検証を案内します。
主な機能
- 01初回起動時の設定ビュー作成
- 02configurations REST コレクションによる設定保存
- 03storage/passwords でのシークレット保存
- 04フィールド検証とセットアップ完了処理
- 05splunk-appinspect によるパッケージ検証
活用シーン
- 01アプリに API エンドポイントとトークン設定を追加
- 02非推奨の setup.xml ページを置き換え
- 03リリース前にアプリパッケージを検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ splunk/ splunk-agent-skills --skill splunk-setup-page-builderインストール後、Claude Code で/splunk-setup-page-builderを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/appinspect-checklist.mdsetup-page.js詳細
Splunk セットアップページビルダー
Splunk アプリまたはアドオン向けに、初回起動時のセットアップページを作成します。ユーザーがアプリを初めて起動したときに表示され、必要な設定(エンドポイント URL、API トークン、機能の有効・無効など)を収集し、非推奨の setup.xml の仕組みを使わずにセットアップを完了する画面です。
これは机上の話ではありません。以下のワークフローは、実際の Splunk Enterprise 10.4 インスタンスで最初から最後まで構築され、splunk-appinspect の test モードと precert モードの両方で検証済みです。また、手動テストで見つかった実際のバグ 2 件を修正して改訂しました(既知の落とし穴を参照してください。どちらも再発させないでください)。さらに、事前のコンテキストがない新しいエージェントセッションで独立に 2 回再検証され、それぞれが手順だけをもとに異なるサンプルアプリを構築しました。
前提条件
- セットアップページを追加する Splunk アプリのディレクトリ(既存のアプリ、または
default/app.conf、default/data/ui/、metadata/default.metaを用意して新規作成したアプリ)。 - 対象:Splunk Enterprise 9.x 以降、または Splunk Cloud Platform(同等のリリース)。ファイルを作成する際にローカルの Splunk インスタンスは不要ですが、検証するには実際のインスタンスへのインストールが必要です。検証を参照してください。
- 静的検証用の
splunk-appinspectをローカルにインストールしておく必要があります(pip install splunk-appinspect。macOS では、正常にインポートするためにbrew install libmagicも必要になる場合があります)。
使用する場面
ユーザーが実行前に設定を入力する必要がある Splunkbase 向け(または社内 TA 向け)の Splunk アプリ/アドオンを作成していて、適切な「アプリをセットアップ」エクスペリエンスを用意したい場合に、このスキルを使用します。よくある設定項目は、API エンドポイント、認証情報/トークン、少数の機能設定などです。インストール後に .conf ファイルを手動編集する方法は避けたい場合にも適しています。
この目的に default/setup.xml を使用しないでください。これは非推奨であり、Splunk Cloud Platform とサーチヘッドクラスターではサポートされず、Splunk AppInspect のクラウドチェック(check_setup_xml_in_default)にも確実に失敗します。初回設定が必要で、Cloud との互換性も求めるアプリでは、代わりにセットアップ ビュー(Simple XML または React)を使用し、app.conf の [install] is_configured/[ui] setup_view で接続する必要があります。
ユーザーが対象を明示的に確認しない限り、本番環境または共有 Splunk インスタンスをインストール/再設定しないでください。Splunk 管理者の生の認証情報をユーザーに尋ねてはいけません。Splunk Web がすでに提供しているセッション/認証を JS SDK 経由で使用してください。
対象はセットアップページ自体の作成に限定してください。関連する依頼は次のように振り分けます。
- セットアップページに関係しない、一般的なアプリ/アドオンのパッケージ化、互換性、アップグレード、非推奨化、削除に関するガイダンス →
app-and-add-on-lifecycle-advisor(助言のみを行います。書き込みやインストールは行いません。このスキルが引き続きセットアップページを実際に作成します)。 - このアプリ固有の
default.metaを超える、既存の共有ナレッジオブジェクトのガバナンス(所有権、孤立オブジェクト、ACL レビュー、名前の競合) →knowledge-object-governance。 - HEC またはその他のデータ取り込みの設定/トラブルシューティング →
hec-setup-and-troubleshooting。 - セットアップページに関係しない、フィールド抽出、CIM マッピング、アドホック SPL の作成 →
field-extraction-and-cim-mappingまたはsplunk-search。 - セットアップページに関係しない、一般的な Splunk 製品に関する質問 →
splunk-product-question-navigator。
アーキテクチャ
<app>/
├── app.manifest # required metadata for packaging/AppInspect
├── default/
│ ├── app.conf # [install] is_configured, [ui] setup_view, [triggers]
│ └── data/ui/
│ ├── views/
│ │ ├── setup_page_dashboard.xml # the setup view (Simple XML)
│ │ └── home.xml # minimal landing view (see below)
│ └── nav/
│ └── default.xml # declares home.xml as the default view
├── metadata/
│ └── default.meta # permissions for the app + any custom conf file
├── appserver/static/
│ ├── javascript/setup_page.js # setup logic, uses the Splunk JS SDK
│ └── styles/setup_page.css
└── README/
└── <settings_conf_file>.conf.spec # spec for any custom conf file you introduce
フィールドごとに選択する 2 つのストレージバックエンド:
| フィールドの種類 | ストレージ | 理由 |
|---|---|---|
| シークレットではない設定(URL、切り替え設定、間隔など) | 組み込みの configurations REST コレクション。定義したカスタム <name>.conf ファイルを対象とします | カスタム Python REST ハンドラーは不要です。そのまま使用でき、Cloud にも安全です。 |
| シークレット(トークン、パスワード、API キー) | storage/passwords | Splunk はこれを暗号化して passwords.conf に保存します。平文の conf ファイルにシークレットを書き込まないでください。AppInspect に失敗するだけでなく、実際のセキュリティリスクも生じます。 |
ワークフローの概要
1. 要件を確認する
ユーザーに確認するか、コンテキストから推測します。
- アプリの ID/ディレクトリ(
app.conf [package] idと一致する必要があります。使用できるのは英字、数字、ピリオド、アンダースコアのみです)。 - シークレットではない設定とシークレットの各フィールド。各フィールドについて、名前、型、必須/任意、検証ルールを確認します。
- アプリにほかのビューがすでにあるかどうか。ない場合は、セットアップ後にアプリを開いたユーザーが無関係な共有コンテンツに誘導されないよう、手順 6 で最小限のホームビューを追加します。
- このアプリに拡張できるセットアップページがすでにあるか、それとも新規作成が必要か。
2. app.conf を設定する
[install]
is_configured = 0
[package]
id = <app_id>
check_for_updates = false
[id]
name = <app_id>
version = 1.0.0
[ui]
is_visible = 1
label = <Human Readable Label>
# No file extension; resolves to default/data/ui/views/setup_page_dashboard.xml
setup_view = setup_page_dashboard
[launcher]
author = <author>
description = <description>
version = 1.0.0
[triggers]
# One reload.<conf_file> line per custom conf file the setup page writes.
reload.<settings_conf_file> = simple
check_for_updates = false と [triggers] の再読み込み行は、記述を省略するとどちらも AppInspect で指摘されます。詳しくは想定される AppInspect の指摘事項と修正方法を参照してください。
[id] version と [launcher] version は別々のフィールドで、同じ値に保つ必要があります。これらの値は自動的には連動しません。各リリース時に両方をまとめて更新してください。更新しない場合、チェックによって読み取るフィールドが異なり、AppInspect/Splunkbase でバージョンの不一致が検出されることがあります。
3. セットアップ画面を作成する(シンプルな XML + JS)
default/data/ui/views/setup_page_dashboard.xml:
<dashboard isDashboard="false"
script="javascript/setup_page.js"
stylesheet="styles/setup_page.css"
hideTitle="true"
version="1.1">
<row>
<panel>
<html>
<div id="main_container">
<h3><Human Readable Label></h3>
</div>
</html>
</panel>
</row>
</dashboard>
appserver/static/javascript/setup_page.js では Splunk JS SDK
(require で読み込む splunkjs/splunk)を使用します。検証、シークレット以外の設定の保存、シークレットの保存、セットアップの完了、再読み込みとリダイレクト、エラーの表示を含む、実績のある完全な実装は
references/setup-page.js にあります。これをコピーしてフィールド名と検証を調整してください。SDK の処理を一から書き直さないでください。この実装では、すでに実際のバグが 2 件見つかり、修正されています(既知の落とし穴(再発した場合は修正してください)を参照)。以下の規約はこのファイル内に暗黙的に含まれています。コードから逆算する必要がないよう、ここで改めて説明します。
- 設定用 conf ファイル自体の名前:アプリにもっと具体的な名前がすでにある場合を除き、
<app_id>_settings(例:my_app_settings)を使用します。これはconfigurationsコレクションが作成する<name>.confファイルです。Splunk によって固定されているものではないため、名前を 1 つ選び、JS、.conf.spec、[triggers]の再読み込み行など、すべての箇所で一貫して使用してください。 - スタンザの名前:同様に、この conf ファイル内のスタンザ名も Splunk によって固定されていません。設定グループに関連する説明的な名前(例:
regionフィールドにはregion_settings、ポーリング間隔フィールドにはpolling_settings)を選んでください。JS と手順 7 で作成する.conf.specで一貫して使用してください。 storage/passwordsのレルムと名前の命名:レルムはアプリに関連付けた名前(<app_id>_realm)、名前は特定のシークレットフィールドの名前(フィールド自体の名前。例:api_token、webhook_signing_secret)にします。これにより、同じアプリ内の複数のシークレットを区別でき、以下のキー形式とも一致します。default/<settings_conf_file>.confは一切同梱しません。 セットアップページで初めて保存するときに、configurationsREST コレクションがlocal/内にファイルとスタンザを作成します。これが、カスタム REST ハンドラーの代わりにこれを使用する理由です。作成するのはdefault/app.conf、default/data/ui/*、metadata/default.meta、app.manifestのみです。設定 conf ファイルは実行時に作成される出力であり、ソースファイルではありません。storage/passwordsの検索キー形式は<realm>:<name>:です。レルム、名前、末尾のコロンをコロンで連結します。資格情報がすでに存在するかを確認する際(passwords.item(key))、createするかupdateするかを判断する前に、この文字列を正確にこの形式で作成してください。形式を間違えると、「更新」が何もせず不一致になるか、重複が作成されます。- すべてのフィールドを、単に存在するか、接頭辞が一致するかではなく、実際の形式に基づいて検証してください。 既知の落とし穴(再発した場合は修正してください)の #1 にある URL の例は、一般的な原則の 1 つです。存在確認だけ、あるいは接頭辞だけのチェックでは、不正な値が通ってしまいます。フィールドの実際の内容(リージョンコード、ポート番号、メールアドレスなど)に合わせて、適切なパターンや範囲のチェックを実装してください。「空でないこと」だけを確認するのでは不十分です。
4. 最小限のホーム画面とナビゲーションを追加する
アプリにほかのビューがない場合は、次を追加します。
default/data/ui/views/home.xml — アプリの機能と、後で設定を変更する場所を説明する 1 パネルのダッシュボード。
default/data/ui/nav/default.xml:
<nav search_view="search" color="#5C6773">
<view name="home" default="true" />
</nav>
これがないと、Splunk Web のサイドバーでアプリをクリックしたときに、インスタンス上にある共有またはグローバルなダッシュボード(たとえば、別のインストール済みアプリからグローバルにエクスポートされたダッシュボード)に遷移してしまいます。セットアップページ自体は正しく動作していても、混乱を招き、壊れているように見えます。
5. metadata/default.meta で権限を設定する
[]
access = read : [ * ], write : [ admin, power, sc_admin ]
export = none
[<settings_conf_file>]
access = read : [ admin, power, sc_admin ], write : [ admin, power, sc_admin ]
export = none
admin だけでなく sc_admin も含めてください。admin だけでは Splunk Cloud のお客様が利用できず、AppInspect で警告が表示されます(check_kos_are_accessible)。
6. app.manifest を追加する
パッケージ化/AppInspect に必要です(check_for_valid_package_id)。最小構成は次のとおりです。
{
"schemaVersion": "2.0.0",
"info": {
"title": "<Human Readable Label>",
"id": { "group": null, "name": "<app_id>", "version": "1.0.0" },
"author": [{ "name": "<author>", "email": null, "company": null }],
"releaseDate": null,
"description": "<description>",
"classification": { "intendedAudience": null, "categories": [], "developmentStatus": null },
"commonInformationModels": null,
"license": { "name": null, "text": null, "uri": null },
"privacyPolicy": { "name": null, "text": null, "uri": null },
"releaseNotes": { "name": null, "text": null, "uri": null }
},
"dependencies": {},
"tasks": [],
"inputGroups": {},
"incompatibleApps": {},
"platformRequirements": { "splunk": { "Enterprise": "*" } }
}
7. カスタム設定ファイルの conf.spec を作成する
導入するすべてのスタンザ/キーを記載した README/<settings_conf_file>.conf.spec を作成します。標準的な Splunk .conf.spec 構文([stanza] ヘッダー、各設定の key = <type>、その直下に * で始まる説明行)を使用します。
[<settings_stanza>]
<field_name> = <string>
* <what this field is and any format constraint, e.g. "Must look like a
region code, e.g. us-east-1.">
* No default.
常に <string> を使うのではなく、フィールドに実際に合った値の型トークンを使用します。よく使われるものは <string>、<integer>、<bool>、<seconds> です。たとえば、範囲が制約された整数フィールドは次のようになります。
[<settings_stanza>]
poll_interval_seconds = <integer>
* How often, in seconds, the app polls its data source.
* Must be an integer between 30 and 3600 inclusive.
* No default.
このファイルは管理者向けのドキュメントであり、configurations REST エンドポイント自体は、これらの型や制約を適用しません。クライアント側の JS による検証はセットアップページの操作性を高めるだけです。後からこれらの値を使用するバックエンドコードやモジュラー入力は、使用前に必ず再検証する必要があります。基盤となる conf ファイルには、JS を一切経由しない経路から値が書き込まれる可能性があります。たとえば、local/<file>.conf を直接編集したり、同じエンドポイントに生の REST 呼び出しを送信したりする場合です。そのため、下流の処理でセットアップページの検証が実行済みだと想定してはいけません。
シークレットフィールドはここに記載しないでください。そもそもシークレットはプレーンな conf ファイルに保存されないため、このファイルには一切記載しません。
既知の落とし穴(再発していたら修正してください)
これらはコードを確認しただけでなく、このパターンを実際に最初から最後までテストして見つかったものです。古い参考例を注意せずにコピーすると、どちらも簡単に再発します。
-
存在確認のみ、またはプレフィックス確認のみの検証。 これは URL に限らない一般的なルールです。「空でないか」または「正しいプレフィックスで始まるか」だけを確認する検証では、無効な値が通過します。実際に見つかった具体例は、
/^https?:\/\//のような正規表現です。これは、後続部分が何もないリテラル文字列http://を「有効な」URL として受け入れます。ホストを必須にすることで修正しました。/^https?:\/\/[^\s]+\..+/i。すべてのフィールドに同じ基準を適用し、単に存在を確認するのではなく、フィールドの実際の形式に合った正規表現、範囲、形式チェックを記述してください(リージョンコード、ポート番号、空ではなく形式も正しいシークレットなど)。 -
is_configuredを保存の条件にしないでください。 Splunk の公式セットアップページの例では、送信ハンドラーの先頭でis_configuredを確認し、すでに1であれば保存を行わず、そのまま再読み込みとリダイレクトに進みます。これにより、ユーザーが後からセットアップページを再度開いて(たとえば アプリの管理 > セットアップ から)、トークンのローテーションや設定変更を行おうとした際に、新しい値が黙って破棄されます。実際に再現して確認したところ、保存処理が実行されなかったため、「更新」後もpasswords.conf内の暗号化済みパスワードはバイト単位でまったく変わっていませんでした。現在のis_configuredの値にかかわらず、送信時には常にワークフローの手順 2~5 を実行してください。Splunk のプラットフォームレベルのリダイレクト動作(is_configuredによって制御されます)によって、設定済みのユーザーにこのページが強制表示されることはすでに防がれています。送信ハンドラーでこれを再度強制する必要はありません。このルールで重要なのは動作であり、特定の変数名ではありません。 送信ハンドラー(
completeSetup、onSubmitなど、名前は問いません)は、保存処理(設定の書き込み、シークレットの書き込み、is_configuredの設定、再読み込み、リダイレクト)を、ユーザーが送信をクリックするたびに必ず無条件で呼び出す必要があります。保存処理の前にis_configuredを確認する早期終了のガードを、どんな名前であっても一切追加しないでください。isAlreadyConfigured、isConfigured、alreadyConfigured、configuredAlready、skipIfConfigured、skipSaveなど、これらと同等のものも含みます。is_configuredを読み取り、保存処理に到達する前にreturnする可能性のあるif文を書いていることに気づいたら、それを削除してください。変数名にかかわらず、それがまさにこのバグです。
検証
静的解析だけでは十分な証明になりません。次の両方を検証してください。
-
AppInspect(構造上の問題や認定上の問題を検出します):
splunk-appinspect inspect <app_dir_or_package> --mode test splunk-appinspect inspect <app_dir_or_package> --mode precerterror/failureが 0 件であることを確認します。新しいアプリでよく見つかる問題とその修正方法については、references/appinspect-checklist.mdを参照してください。 -
実際の Splunk インスタンス(上記の 2 つの落とし穴のように、AppInspect では検出できない動作上の問題を検出します)。明示的な確認なしに、本番環境または共有インスタンスへインストールしないでください。最低限、次の手動テストを行います。
is_configured=0の状態で新規インストールし、セットアップページにリダイレクトされることを確認します。- 必須フィールドを空のまま送信し、検証によって送信がブロックされ、REST 呼び出しが行われないことを確認します。
- 「空ではない」という条件は満たすものの、実際の形式検証には合致しないフィールド値(例:URL フィールドに
http://のみ)を送信し、それでも拒否されることを確認します。 - 有効な値を送信し、成功メッセージとリダイレクトを確認します。また、秘密ではない設定がカスタム conf ファイルに保存され、秘密情報が
passwords.confに暗号化されて保存されることを確認します(平文は不可)。 - Splunk を再起動し、
is_configured=1が保持され、アプリがセットアップにリダイレクトされないことを確認します。 - セットアップを再度開き、秘密情報に新しい値を送信し、上記の落とし穴 #2 のとおり、既存のパスワードエントリがその場で更新されること(重複するスタンザが作成されないこと)を確認します。
- サイドバーでアプリをクリックし、無関係な共有コンテンツではなく、アプリ独自のホームビューが表示されることを確認します。
例
- 「このアドオンに、アプリを実行する前にベース API URL と API トークンを収集するセットアップページを追加してください。」→ 2 つのフィールドを収集し、
app.confを連携させ、references/setup-page.jsを基にセットアップビューと JS を作成し、ホームビュー/ナビゲーションを追加して、default.metaを設定し、app.manifestを追加してから、AppInspect と実際のインスタンスで検証します。 - 「このアプリにはすでに
app.confとナビゲーションがあります。初回起動時のセットアップを追加し、webhook 署名シークレットと 30~3600 秒のポーリング間隔を保存してください。」→ 同じワークフローを使いますが、ステップ 4(ホームビュー/ナビゲーションはすでに存在するため)は省略し、「すべてのフィールドを実際の形式に合わせて検証する」というルールに従って、URL パターンではなく範囲/長さの検証を使用します。 - 「セットアップ画面で
default/setup.xmlを使用していますが、Splunk Cloud AppInspect の審査に通りません。」→default/setup.xmlを完全に削除し、このスキルのワークフローに従って同じフィールドをsetup_viewとして再構築します。既存のsetup.xmlにパッチを適用したり、移動したりしないでください。
トラブルシューティング
- AppInspect で「Cloud 環境では
default/setup.xmlを使用しないでください。」と報告される場合。 ファイルを削除してください。Cloud との互換性を保ったまま残す方法はサポートされていません。同じ設定をsetup_viewとして再構築してください(このスキルではこの方法全体を説明しています)。 - AppInspect で「無効な XML ファイル」または未定義のエンティティに関するエラー(例:
mdash)が報告される場合。 XML で定義されている組み込みエンティティは 5 つだけです(& < > ' ")。名前付き HTML エンティティ(—、 など)は、数値形式(—、 )に置き換えてください。 - 再インストール/再起動しても
setup_page.jsの変更が反映されないように見える場合。 Splunk Web(およびブラウザー)は静的な JS を積極的にキャッシュします。splunk restartだけでは、確実に最新のファイルが取得されるわけではありません。修正が機能しなかったと結論づける前に、ハードリフレッシュ(Cmd/Ctrl+Shift+R)を行うか、プライベート/シークレットウィンドウでページを開いてください。 - 後からセットアップページを再度開き(Manage Apps の「Set up」から)、値を変更しても反映されない場合 — 送信後も値が変わっていないように見えます。これは落とし穴 #2です。
is_configuredゲートにより保存がひそかにスキップされています。ゲートを削除してください。 - Splunk Web のサイドバーでアプリをクリックすると、別のアプリの無関係なダッシュボードが表示される場合。 このアプリには独自のホームビュー/ナビゲーションがないため、Splunk が別のアプリの共有/グローバルにエクスポートされたコンテンツにフォールバックしています。
default/data/ui/views/home.xmlとdefault/data/ui/nav/default.xmlを追加してください(手順 4)。 - 「Manage Apps」または「Set up」にアクセスできない場合、または Splunk でライセンス機能エラー(例:
Requires license feature='Auth')が報告される場合。 対象のインスタンスは Free ライセンスで実行されており、認証/RBAC が完全に無効になっています。このスキルのセットアップページはロール/機能とstorage/passwordsに依存しており、いずれも Auth システムの一部です。検証には Free ではなく、Trial または Enterprise ライセンスのインスタンスが必要です。
安全性
- シークレットは
storage/passwords以外の場所に保存しないでください。ユーザーに表示するエラーメッセージを含め、シークレットの値をログに記録しないでください。 - 作成するものに Splunk 管理者の認証情報をそのまま入力するようユーザーに求めないでください。Splunk Web 経由で JS SDK がすでに使用しているセッションを利用してください。
- ユーザーから対象を明示的に確認されない限り、共有/本番環境の Splunk インスタンスをインストール、再起動、または再設定しないでください。
- 別のアプリに属するナレッジオブジェクトを変更しないでください。