11#! /usr/bin/env bash
22#
33# ═══════════════════════════════════════════════════════════════════════
4- # Whitelist Manager — Quick Demo
4+ # Whitelist Manager v2.0 — Quick Demo
55# ═══════════════════════════════════════════════════════════════════════
66#
77# Spins up a standalone Splunk instance in Docker, installs the
8- # Whitelist Manager app from the .spl package, and seeds demo data
9- # so you can evaluate the app immediately.
8+ # Whitelist Manager app from the .spl package, creates demo users
9+ # with different roles, and seeds sample data so you can evaluate
10+ # the full feature set including approval workflows.
1011#
1112# Usage:
1213# bash demo/demo.sh # build .spl, start Splunk, seed data
2021#
2122# Access after startup:
2223# URL: http://localhost:9000
23- # Username: admin
24- # Password: Chang3d!
24+ #
25+ # Demo accounts:
26+ # admin / Chang3d! — full Splunk admin
27+ # analyst1 / Chang3d! — editor (can edit whitelists)
28+ # viewer1 / Chang3d! — viewer (read-only)
29+ # wladmin1 / Chang3d! — WL admin (can approve/reject, configure limits)
2530#
2631
2732set -euo pipefail
2833
2934# ── Configuration ────────────────────────────────────────────────────
3035CONTAINER_NAME=" wl_manager_demo"
3136SPLUNK_IMAGE=" splunk/splunk:9.3.1"
32- SPLUNK_PASSWORD=" Chang3d!"
37+ SPLUNK_PASSWORD=" ${SPLUNK_PASSWORD :- Chang3d! } "
3338WEB_PORT=9000
3439API_PORT=9089
3540VOLUME_NAME=" wl_manager_demo_var"
@@ -59,7 +64,6 @@ wait_for_splunk() {
5964 fi
6065 sleep 3
6166 elapsed=$(( elapsed + 3 ))
62- # Print progress every 15 seconds
6367 if [ $(( elapsed % 15 )) -eq 0 ]; then
6468 info " Still waiting... (${elapsed} s)"
6569 fi
@@ -69,6 +73,18 @@ wait_for_splunk() {
6973 return 1
7074}
7175
76+ splunk_api () {
77+ # Helper: make a Splunk REST API call
78+ # Usage: splunk_api POST /services/authentication/users -d "name=foo&..."
79+ local method=" $1 "
80+ local endpoint=" $2 "
81+ shift 2
82+ curl -sk -X " $method " \
83+ -u " admin:${SPLUNK_PASSWORD} " \
84+ " https://localhost:${API_PORT}${endpoint} " \
85+ " $@ " -o /dev/null -w " %{http_code}"
86+ }
87+
7288# ── Handle --stop / --clean ──────────────────────────────────────────
7389
7490if [[ " ${1:- } " == " --stop" ]]; then
94110
95111echo " "
96112echo " ═══════════════════════════════════════════════════════════════"
97- echo " Whitelist Manager — Quick Demo"
113+ echo " Whitelist Manager v2.0 — Quick Demo"
98114echo " ═══════════════════════════════════════════════════════════════"
99115echo " "
100116
101117# ── Step 1: Check Docker ────────────────────────────────────────────
102118
103- echo " Step 1/6 : Checking Docker..."
119+ echo " Step 1/7 : Checking Docker..."
104120if ! docker info & > /dev/null; then
105121 err " Docker is not running. Please start Docker Desktop and try again."
106122 exit 1
@@ -110,15 +126,13 @@ ok "Docker is running."
110126# ── Step 2: Find or build .spl ──────────────────────────────────────
111127
112128echo " "
113- echo " Step 2/6 : Locating .spl package..."
129+ echo " Step 2/7 : Locating .spl package..."
114130
115131SPL_FILE=" "
116132if [[ -n " ${1:- } " && -f " ${1:- } " ]]; then
117- # User passed a path to an existing .spl
118133 SPL_FILE=" $1 "
119134 ok " Using provided .spl: $SPL_FILE "
120135else
121- # Look for existing .spl in dist/
122136 SPL_FILE=$( ls -t " $PROJECT_DIR " /dist/wl_manager-* .spl 2> /dev/null | head -1 || true)
123137 if [[ -n " $SPL_FILE " ]]; then
124138 ok " Found existing .spl: $SPL_FILE "
137151# ── Step 3: Start container ─────────────────────────────────────────
138152
139153echo " "
140- echo " Step 3/6 : Starting Splunk container..."
154+ echo " Step 3/7 : Starting Splunk container..."
141155
142- # Stop existing demo container if running
143156if docker ps -a --format ' {{.Names}}' | grep -q " ^${CONTAINER_NAME} $" ; then
144157 info " Removing existing demo container..."
145158 docker stop " $CONTAINER_NAME " 2> /dev/null || true
@@ -163,49 +176,78 @@ wait_for_splunk "$API_PORT"
163176# ── Step 4: Install .spl ────────────────────────────────────────────
164177
165178echo " "
166- echo " Step 4/6 : Installing Whitelist Manager app..."
179+ echo " Step 4/7 : Installing Whitelist Manager app..."
167180
168- # Copy .spl into the container and fix ownership
169181docker cp " $SPL_FILE " " ${CONTAINER_NAME} :/tmp/wl_manager.spl"
170182MSYS_NO_PATHCONV=1 docker exec -u 0 " $CONTAINER_NAME " \
171183 chown splunk:splunk /tmp/wl_manager.spl 2> /dev/null || true
172184
173- # Install via Splunk CLI (must run as splunk user)
174185MSYS_NO_PATHCONV=1 docker exec -u splunk " $CONTAINER_NAME " \
175186 /opt/splunk/bin/splunk install app /tmp/wl_manager.spl \
176187 -auth " admin:${SPLUNK_PASSWORD} " 2>&1 | grep -v " ^$" || true
177188
178189ok " App installed."
179190
180- # Restart Splunk to load the new app (--answer-yes avoids interactive prompt)
181191info " Restarting Splunk to load the app..."
182192MSYS_NO_PATHCONV=1 docker exec -u splunk " $CONTAINER_NAME " \
183193 /opt/splunk/bin/splunk restart --answer-yes 2>&1 | tail -1 || true
184194
185195wait_for_splunk " $API_PORT "
186196
187- # ── Step 5: Seed demo data ── ────────────────────────────────────────
197+ # ── Step 5: Create demo users ────────────────────────────────────────
188198
189199echo " "
190- echo " Step 5/6: Seeding demo data..."
200+ echo " Step 5/7: Creating demo users..."
201+
202+ # analyst1 — editor role (can edit whitelists, subject to daily limits and approval gates)
203+ STATUS=$( splunk_api POST " /services/authentication/users" \
204+ -d " name=analyst1&password=${SPLUNK_PASSWORD} &roles=wl_analyst_editor&roles=user" )
205+ if [[ " $STATUS " == " 201" || " $STATUS " == " 409" ]]; then
206+ ok " analyst1 (editor) — can edit whitelists"
207+ else
208+ info " analyst1 create returned HTTP $STATUS "
209+ fi
210+
211+ # viewer1 — viewer role (read-only access to whitelists and audit trail)
212+ STATUS=$( splunk_api POST " /services/authentication/users" \
213+ -d " name=viewer1&password=${SPLUNK_PASSWORD} &roles=wl_analyst_viewer&roles=user" )
214+ if [[ " $STATUS " == " 201" || " $STATUS " == " 409" ]]; then
215+ ok " viewer1 (viewer) — read-only access"
216+ else
217+ info " viewer1 create returned HTTP $STATUS "
218+ fi
219+
220+ # wladmin1 — WL admin (can approve/reject requests, configure limits, view usage)
221+ STATUS=$( splunk_api POST " /services/authentication/users" \
222+ -d " name=wladmin1&password=${SPLUNK_PASSWORD} &roles=wl_admin&roles=user" )
223+ if [[ " $STATUS " == " 201" || " $STATUS " == " 409" ]]; then
224+ ok " wladmin1 (admin) — approve/reject, configure limits"
225+ else
226+ info " wladmin1 create returned HTTP $STATUS "
227+ fi
228+
229+ # ── Step 6: Seed demo data ──────────────────────────────────────────
230+
231+ echo " "
232+ echo " Step 6/7: Seeding demo data..."
191233
192234APP_LOOKUPS=" /opt/splunk/etc/apps/wl_manager/lookups"
193235
194236# Calculate demo dates
195- FUTURE_7D=$( date -u -d " +7 days" " +%Y-%m-%d 00:00" 2> /dev/null || date -u -v+7d " +%Y-%m-%d 00:00" 2> /dev/null || echo " 2026-03-02 00:00" )
196- FUTURE_30D=$( date -u -d " +30 days" " +%Y-%m-%d 00:00" 2> /dev/null || date -u -v+30d " +%Y-%m-%d 00:00" 2> /dev/null || echo " 2026-03 -25 00:00" )
197- FUTURE_6M=$( date -u -d " +180 days" " +%Y-%m-%d 00:00" 2> /dev/null || date -u -v+180d " +%Y-%m-%d 00:00" 2> /dev/null || echo " 2026-08-22 00:00" )
237+ FUTURE_7D=$( date -u -d " +7 days" " +%Y-%m-%d 00:00" 2> /dev/null || date -u -v+7d " +%Y-%m-%d 00:00" 2> /dev/null || echo " 2026-04-01 00:00" )
238+ FUTURE_30D=$( date -u -d " +30 days" " +%Y-%m-%d 00:00" 2> /dev/null || date -u -v+30d " +%Y-%m-%d 00:00" 2> /dev/null || echo " 2026-04 -25 00:00" )
239+ FUTURE_6M=$( date -u -d " +180 days" " +%Y-%m-%d 00:00" 2> /dev/null || date -u -v+180d " +%Y-%m-%d 00:00" 2> /dev/null || echo " 2026-09-20 00:00" )
198240PAST_DATE=" 2025-01-15 08:00"
199241
200- # 1. Master mapping CSV
242+ # 1. Master mapping CSV — 3 demo rules
201243MSYS_NO_PATHCONV=1 docker exec -u splunk " $CONTAINER_NAME " bash -c " cat > ${APP_LOOKUPS} /rule_csv_map.csv << 'CSVEOF'
202244rule_name,csv_file,app_context
203245Brute_Force_Login,brute_force_whitelist.csv,wl_manager
204246Suspicious_Process,suspicious_process_whitelist.csv,wl_manager
205247Impossible_Travel,impossible_travel_whitelist.csv,wl_manager
206248CSVEOF"
207249
208- # 2. Brute Force whitelist (has Expires column — demonstrates expiration features )
250+ # 2. Brute Force whitelist (has Expires — demonstrates expiration + approval gates )
209251MSYS_NO_PATHCONV=1 docker exec -u splunk " $CONTAINER_NAME " bash -c " cat > ${APP_LOOKUPS} /brute_force_whitelist.csv << CSVEOF
210252user,src_ip,threshold,Comment,Expires
211253svc_monitoring,10.1.1.50,100,Service account - high threshold expected,${FUTURE_6M}
@@ -236,30 +278,42 @@ CSVEOF"
236278MSYS_NO_PATHCONV=1 docker exec -u 0 " $CONTAINER_NAME " \
237279 chown -R splunk:splunk " ${APP_LOOKUPS} /" 2> /dev/null || true
238280
239- ok " Demo data seeded (3 rules, 3 CSV files)."
281+ ok " Demo data seeded (3 rules, 3 CSV files, 1 expired row for auto-removal demo )."
240282
241- # ── Step 6 : Summary ─────────────────────────────────────────────────
283+ # ── Step 7 : Summary ─────────────────────────────────────────────────
242284
243285echo " "
244286echo " ═══════════════════════════════════════════════════════════════"
245287echo " DEMO READY"
246288echo " "
247289echo " Splunk Web: http://localhost:${WEB_PORT} "
248- echo " Username: admin"
249- echo " Password: ${SPLUNK_PASSWORD} "
290+ echo " "
291+ echo " Demo Accounts:"
292+ echo " admin / ${SPLUNK_PASSWORD} — full Splunk admin"
293+ echo " analyst1 / ${SPLUNK_PASSWORD} — editor (edit whitelists)"
294+ echo " viewer1 / ${SPLUNK_PASSWORD} — viewer (read-only)"
295+ echo " wladmin1 / ${SPLUNK_PASSWORD} — WL admin (approve/reject)"
250296echo " "
251297echo " What to try:"
252- echo " 1. Go to Apps > Whitelist Manager"
253- echo " 2. Select a detection rule from the dropdown"
254- echo " - Brute_Force_Login (has expiration dates)"
255- echo " - Suspicious_Process (simple whitelist)"
256- echo " - Impossible_Travel (has expiration dates)"
257- echo " 3. Select a CSV file and explore the table"
258- echo " 4. Try editing a cell, adding a row, or removing one"
259- echo " 5. Click Save Changes and see the diff summary"
260- echo " 6. Click the Audit Trail tab to see change history"
261- echo " 7. Notice the expired row in Brute_Force_Login was"
262- echo " auto-removed (check the yellow banner on load)"
298+ echo " "
299+ echo " As analyst1 (editor):"
300+ echo " 1. Apps > Whitelist Manager"
301+ echo " 2. Select Brute_Force_Login — notice the expired row"
302+ echo " is auto-removed (yellow banner)"
303+ echo " 3. Edit a cell, add a row, save with a comment"
304+ echo " 4. Try removing 3+ rows — approval is required!"
305+ echo " 5. Check the Audit Trail tab for change history"
306+ echo " "
307+ echo " As wladmin1 (admin):"
308+ echo " 6. Log in as wladmin1"
309+ echo " 7. Go to the Control Panel tab"
310+ echo " 8. Review and approve/reject analyst1's request"
311+ echo " 9. Check Analyst Usage and Limits & Permissions tabs"
312+ echo " "
313+ echo " As viewer1 (viewer):"
314+ echo " 10. Log in as viewer1"
315+ echo " 11. Notice you can view but NOT edit (Save is disabled)"
316+ echo " 12. Control Panel tab is NOT visible"
263317echo " "
264318echo " Tear down:"
265319echo " bash demo/demo.sh --stop # stop + remove container"
0 commit comments