splunkctl 0.13.0__tar.gz → 0.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- splunkctl-0.15.0/PKG-INFO +111 -0
- splunkctl-0.15.0/README.md +67 -0
- splunkctl-0.15.0/docs/guides/alerts.md +98 -0
- splunkctl-0.15.0/docs/guides/apps.md +94 -0
- splunkctl-0.15.0/docs/guides/audit.md +92 -0
- splunkctl-0.15.0/docs/guides/auth.md +96 -0
- splunkctl-0.15.0/docs/guides/conf.md +105 -0
- splunkctl-0.15.0/docs/guides/configure.md +156 -0
- splunkctl-0.15.0/docs/guides/dashboards.md +101 -0
- splunkctl-0.15.0/docs/guides/datamodels.md +98 -0
- splunkctl-0.15.0/docs/guides/doctor.md +88 -0
- splunkctl-0.15.0/docs/guides/es-detections.md +98 -0
- splunkctl-0.15.0/docs/guides/es.md +101 -0
- splunkctl-0.15.0/docs/guides/exit-codes.md +46 -0
- splunkctl-0.15.0/docs/guides/hec.md +113 -0
- splunkctl-0.15.0/docs/guides/indexes.md +117 -0
- splunkctl-0.15.0/docs/guides/inputs.md +109 -0
- splunkctl-0.15.0/docs/guides/install.md +101 -0
- splunkctl-0.15.0/docs/guides/keycloak-lab.md +75 -0
- splunkctl-0.15.0/docs/guides/knowledge.md +97 -0
- splunkctl-0.15.0/docs/guides/kvstore.md +139 -0
- splunkctl-0.15.0/docs/guides/lookups.md +115 -0
- splunkctl-0.15.0/docs/guides/mcp.md +184 -0
- splunkctl-0.15.0/docs/guides/parsers.md +144 -0
- splunkctl-0.15.0/docs/guides/rules.md +227 -0
- splunkctl-0.15.0/docs/guides/search.md +135 -0
- splunkctl-0.15.0/docs/guides/server.md +159 -0
- splunkctl-0.15.0/docs/guides/soar-actions.md +133 -0
- splunkctl-0.15.0/docs/guides/soar-admin.md +126 -0
- splunkctl-0.15.0/docs/guides/soar-approvals.md +82 -0
- splunkctl-0.15.0/docs/guides/soar-apps.md +76 -0
- splunkctl-0.15.0/docs/guides/soar-assets.md +104 -0
- splunkctl-0.15.0/docs/guides/soar-automation.md +8 -0
- splunkctl-0.15.0/docs/guides/soar-cases.md +141 -0
- splunkctl-0.15.0/docs/guides/soar-functions.md +96 -0
- splunkctl-0.15.0/docs/guides/soar-incidents.md +186 -0
- splunkctl-0.15.0/docs/guides/soar-indicators.md +119 -0
- splunkctl-0.15.0/docs/guides/soar-ingest.md +144 -0
- splunkctl-0.15.0/docs/guides/soar-lists.md +135 -0
- splunkctl-0.15.0/docs/guides/soar-playbooks.md +171 -0
- splunkctl-0.15.0/docs/guides/soar.md +128 -0
- splunkctl-0.15.0/docs/guides/splunk-cli.md +42 -0
- splunkctl-0.15.0/docs/guides/state.md +197 -0
- splunkctl-0.15.0/docs/guides/users.md +137 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/pyproject.toml +7 -4
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/__init__.py +1 -1
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/client.py +28 -4
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/auth.py +2 -2
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/commands_meta.py +21 -10
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/config_cmd.py +16 -8
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/dashboards.py +10 -10
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/docs_cmd.py +69 -16
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/doctor.py +56 -3
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/hec.py +8 -8
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/lookups.py +9 -7
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/search.py +7 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/_client.py +3 -3
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/_ingest_helpers.py +3 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/artifacts.py +6 -2
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/assets.py +21 -3
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/functions.py +2 -1
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/playbooks.py +2 -1
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state_io_blobs.py +6 -8
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state_io_soar_assets.py +10 -6
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/config.py +70 -12
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/errors.py +5 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/guard.py +2 -2
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/main.py +29 -3
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/dynamic_server.py +9 -1
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/resources.py +2 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/runner.py +3 -1
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/output.py +2 -1
- splunkctl-0.15.0/splunkctl/rest_adapters.py +269 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/soar/client.py +1 -1
- splunkctl-0.15.0/splunkctl/spl_safety.py +64 -0
- splunkctl-0.15.0/splunkctl.egg-info/PKG-INFO +111 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl.egg-info/SOURCES.txt +6 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl.egg-info/entry_points.txt +1 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl.egg-info/requires.txt +1 -1
- splunkctl-0.13.0/PKG-INFO +0 -274
- splunkctl-0.13.0/README.md +0 -232
- splunkctl-0.13.0/docs/guides/alerts.md +0 -79
- splunkctl-0.13.0/docs/guides/apps.md +0 -65
- splunkctl-0.13.0/docs/guides/audit.md +0 -125
- splunkctl-0.13.0/docs/guides/auth.md +0 -61
- splunkctl-0.13.0/docs/guides/conf.md +0 -84
- splunkctl-0.13.0/docs/guides/configure.md +0 -120
- splunkctl-0.13.0/docs/guides/dashboards.md +0 -17
- splunkctl-0.13.0/docs/guides/datamodels.md +0 -164
- splunkctl-0.13.0/docs/guides/doctor.md +0 -70
- splunkctl-0.13.0/docs/guides/es.md +0 -236
- splunkctl-0.13.0/docs/guides/exit-codes.md +0 -44
- splunkctl-0.13.0/docs/guides/hec.md +0 -59
- splunkctl-0.13.0/docs/guides/indexes.md +0 -76
- splunkctl-0.13.0/docs/guides/inputs.md +0 -80
- splunkctl-0.13.0/docs/guides/install.md +0 -55
- splunkctl-0.13.0/docs/guides/keycloak-lab.md +0 -20
- splunkctl-0.13.0/docs/guides/knowledge.md +0 -113
- splunkctl-0.13.0/docs/guides/kvstore.md +0 -125
- splunkctl-0.13.0/docs/guides/lookups.md +0 -127
- splunkctl-0.13.0/docs/guides/mcp.md +0 -173
- splunkctl-0.13.0/docs/guides/parsers.md +0 -67
- splunkctl-0.13.0/docs/guides/rules.md +0 -183
- splunkctl-0.13.0/docs/guides/search.md +0 -144
- splunkctl-0.13.0/docs/guides/server.md +0 -257
- splunkctl-0.13.0/docs/guides/soar-actions.md +0 -130
- splunkctl-0.13.0/docs/guides/soar-admin.md +0 -120
- splunkctl-0.13.0/docs/guides/soar-approvals.md +0 -99
- splunkctl-0.13.0/docs/guides/soar-apps.md +0 -56
- splunkctl-0.13.0/docs/guides/soar-automation.md +0 -132
- splunkctl-0.13.0/docs/guides/soar-cases.md +0 -178
- splunkctl-0.13.0/docs/guides/soar-functions.md +0 -94
- splunkctl-0.13.0/docs/guides/soar-indicators.md +0 -123
- splunkctl-0.13.0/docs/guides/soar-ingest.md +0 -161
- splunkctl-0.13.0/docs/guides/soar-lists.md +0 -110
- splunkctl-0.13.0/docs/guides/soar-playbooks.md +0 -267
- splunkctl-0.13.0/docs/guides/soar.md +0 -440
- splunkctl-0.13.0/docs/guides/state.md +0 -270
- splunkctl-0.13.0/docs/guides/users.md +0 -86
- splunkctl-0.13.0/splunkctl.egg-info/PKG-INFO +0 -274
- {splunkctl-0.13.0 → splunkctl-0.15.0}/LICENSE +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/MANIFEST.in +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/setup.cfg +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/__main__.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/auth/__init__.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/auth/adapters.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/auth/broker.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/auth/detector.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/auth/session.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/__init__.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/alerts.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/apps.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/audit.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/audit_parse.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/common.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/conf.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/conf_ops.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/datamodels.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/es.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/es_threat_intel.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/indexes.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/info.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/inputs.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/knowledge.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/kvstore.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/lookups_wiring.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/mcp_cmd.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/parsers.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/parsers_io.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/rules.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/rules_io.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/rules_schedule.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/server.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/server_auth.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/server_deployment.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/server_tokens.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/server_topology.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/server_workloads.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/__init__.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/actions.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/admin.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/admin_roles_audit.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/admin_views.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/approvals.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/apps.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/cases.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/containers.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/containers_assign.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/containers_write.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/indicators.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/ingest.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/lists.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/notes.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/playbook_runs.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/playbooks_delete.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/search.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/system.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/vault.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/soar/workbook_templates.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state_io.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state_io_confs.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state_io_soar.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/state_types.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/commands/users.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/__init__.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/output_cap.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/prompts.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/server.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/tools.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/mcp/transport.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/py.typed +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/soar/__init__.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/soar/cimcef.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl/soar/web.py +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl.egg-info/dependency_links.txt +0 -0
- {splunkctl-0.13.0 → splunkctl-0.15.0}/splunkctl.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: splunkctl
|
|
3
|
+
Version: 0.15.0
|
|
4
|
+
Summary: Open-source MCP server and CLI for Splunk Enterprise SIEM and Splunk SOAR.
|
|
5
|
+
Author: dannyota
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/dannyota/splunkctl
|
|
8
|
+
Project-URL: Documentation, https://splunkctl.danny.vn
|
|
9
|
+
Project-URL: Repository, https://github.com/dannyota/splunkctl
|
|
10
|
+
Project-URL: Issues, https://github.com/dannyota/splunkctl/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/dannyota/splunkctl/blob/master/CHANGELOG.md
|
|
12
|
+
Keywords: splunk,mcp,model-context-protocol,siem,soar,security,cli,detection,spl
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Classifier: Topic :: System :: Systems Administration
|
|
23
|
+
Requires-Python: >=3.12
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: splunk-sdk>=2.0
|
|
27
|
+
Requires-Dist: click>=8.2
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: tabulate>=0.9
|
|
30
|
+
Requires-Dist: requests>=2.32
|
|
31
|
+
Requires-Dist: defusedxml>=0.7
|
|
32
|
+
Requires-Dist: mcp<3,>=2.3
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
36
|
+
Requires-Dist: mypy>=1.11; extra == "dev"
|
|
37
|
+
Requires-Dist: types-requests; extra == "dev"
|
|
38
|
+
Requires-Dist: types-PyYAML; extra == "dev"
|
|
39
|
+
Requires-Dist: types-tabulate; extra == "dev"
|
|
40
|
+
Requires-Dist: types-defusedxml; extra == "dev"
|
|
41
|
+
Provides-Extra: browser
|
|
42
|
+
Requires-Dist: playwright>=1.45; extra == "browser"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# splunkctl
|
|
46
|
+
|
|
47
|
+
<a href="https://splunkctl.danny.vn"><img src="https://raw.githubusercontent.com/dannyota/splunkctl/master/docs/assets/banner.svg" alt="splunkctl: CLI and MCP server for Splunk Enterprise, Enterprise Security, and SOAR" width="600"></a>
|
|
48
|
+
|
|
49
|
+
Operate Splunk Enterprise, Enterprise Security, and Splunk SOAR from a terminal, or give an AI agent the same commands through MCP.
|
|
50
|
+
|
|
51
|
+
Requires Python 3.12+ and credentials for your Splunk instance.
|
|
52
|
+
|
|
53
|
+
## Quickstart
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python -m pip install splunkctl
|
|
57
|
+
splunkctl config init
|
|
58
|
+
splunkctl doctor
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
[Documentation](https://splunkctl.danny.vn) · [Installation requirements](https://splunkctl.danny.vn/#/guides/install)
|
|
62
|
+
|
|
63
|
+
## Tasks
|
|
64
|
+
|
|
65
|
+
- Investigate: run SPL, read fired alerts, and triage Enterprise Security notables. [Search](https://splunkctl.danny.vn/#/guides/search), [Triage notables](https://splunkctl.danny.vn/#/guides/es)
|
|
66
|
+
- Deploy detections: export saved searches to YAML, review the diff, and import them on another instance. [Manage detection rules](https://splunkctl.danny.vn/#/guides/rules)
|
|
67
|
+
- Respond with SOAR: work containers, artifacts, vault files, notes, and playbook runs. [Work SOAR incidents](https://splunkctl.danny.vn/#/guides/soar-incidents)
|
|
68
|
+
- Review configuration drift: pull live state, diff it against version control, and push approved changes with a change report. [Manage configuration as code](https://splunkctl.danny.vn/#/guides/state)
|
|
69
|
+
|
|
70
|
+
## Safety
|
|
71
|
+
|
|
72
|
+
Every command that changes a remote Splunk or SOAR instance is guarded. Without `--yes` it prints a preview and exits without changing anything; some previews read the current state first to show a diff. The preview names the target host, and the active profile for Splunk Enterprise, so a change aimed at production is visible before it happens:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
$ splunkctl --profile uat rules delete 'My Rule'
|
|
76
|
+
[DRY RUN] Delete saved search 'My Rule' (profile: uat @ uat.splunk.internal:8089)
|
|
77
|
+
Pass --yes to apply.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Add `--yes` to apply. `splunkctl state push --report FILE` writes a change report with the before and after state for each object, which you can attach to a change ticket.
|
|
81
|
+
|
|
82
|
+
Local configuration writes are not guarded: `splunkctl config init`, `splunkctl config use`, `splunkctl auth login`, and `splunkctl mcp install` write to your own machine immediately.
|
|
83
|
+
|
|
84
|
+
## Agent access
|
|
85
|
+
|
|
86
|
+
The MCP server exposes the command tree to Claude Code, Claude Desktop, Cursor, or any other MCP client. Setup, transports, and the progressive tool-loading model are in the [MCP guide](https://splunkctl.danny.vn/#/guides/mcp).
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
splunkctl mcp install # register the server in ./.mcp.json
|
|
90
|
+
splunkctl commands --json # machine-readable command tree
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Guarded tools keep the same contract as the CLI: a call previews until the agent passes `yes=true` explicitly.
|
|
94
|
+
|
|
95
|
+
## Requirements and limitations
|
|
96
|
+
|
|
97
|
+
- Python 3.12 or newer.
|
|
98
|
+
- A Splunk account with REST API access on port 8089 (or your configured port). Each command needs the Splunk capability or SOAR permission its action requires; `splunkctl doctor` reports which checks pass for the active profile.
|
|
99
|
+
- Enterprise Security commands (`splunkctl es ...`) check for the `SplunkEnterpriseSecuritySuite` app and exit 1 with a `not_found` error when it is not installed.
|
|
100
|
+
- Browser SAML login needs the `browser` extra: `python -m pip install 'splunkctl[browser]'`.
|
|
101
|
+
|
|
102
|
+
## Project and support
|
|
103
|
+
|
|
104
|
+
splunkctl is an independent community project. It is not affiliated with or endorsed by Splunk Inc.
|
|
105
|
+
|
|
106
|
+
Splunk Inc. publishes an unrelated Go CLI with the same executable name, [`splunk/splunkctl`](https://github.com/splunk/splunkctl). This package also installs `splunkctl-py` and leaves a Splunk-format config file untouched, so both tools can be installed together; see [Relationship to Splunk's splunkctl](https://splunkctl.danny.vn/#/guides/splunk-cli).
|
|
107
|
+
|
|
108
|
+
- [Releases](https://github.com/dannyota/splunkctl/releases) and [changelog](https://github.com/dannyota/splunkctl/blob/master/CHANGELOG.md)
|
|
109
|
+
- [Issues](https://github.com/dannyota/splunkctl/issues) for bugs and feature requests; see [SECURITY.md](SECURITY.md) for vulnerabilities
|
|
110
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) for development setup
|
|
111
|
+
- License: [Apache-2.0](https://github.com/dannyota/splunkctl/blob/master/LICENSE)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# splunkctl
|
|
2
|
+
|
|
3
|
+
<a href="https://splunkctl.danny.vn"><img src="https://raw.githubusercontent.com/dannyota/splunkctl/master/docs/assets/banner.svg" alt="splunkctl: CLI and MCP server for Splunk Enterprise, Enterprise Security, and SOAR" width="600"></a>
|
|
4
|
+
|
|
5
|
+
Operate Splunk Enterprise, Enterprise Security, and Splunk SOAR from a terminal, or give an AI agent the same commands through MCP.
|
|
6
|
+
|
|
7
|
+
Requires Python 3.12+ and credentials for your Splunk instance.
|
|
8
|
+
|
|
9
|
+
## Quickstart
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python -m pip install splunkctl
|
|
13
|
+
splunkctl config init
|
|
14
|
+
splunkctl doctor
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
[Documentation](https://splunkctl.danny.vn) · [Installation requirements](https://splunkctl.danny.vn/#/guides/install)
|
|
18
|
+
|
|
19
|
+
## Tasks
|
|
20
|
+
|
|
21
|
+
- Investigate: run SPL, read fired alerts, and triage Enterprise Security notables. [Search](https://splunkctl.danny.vn/#/guides/search), [Triage notables](https://splunkctl.danny.vn/#/guides/es)
|
|
22
|
+
- Deploy detections: export saved searches to YAML, review the diff, and import them on another instance. [Manage detection rules](https://splunkctl.danny.vn/#/guides/rules)
|
|
23
|
+
- Respond with SOAR: work containers, artifacts, vault files, notes, and playbook runs. [Work SOAR incidents](https://splunkctl.danny.vn/#/guides/soar-incidents)
|
|
24
|
+
- Review configuration drift: pull live state, diff it against version control, and push approved changes with a change report. [Manage configuration as code](https://splunkctl.danny.vn/#/guides/state)
|
|
25
|
+
|
|
26
|
+
## Safety
|
|
27
|
+
|
|
28
|
+
Every command that changes a remote Splunk or SOAR instance is guarded. Without `--yes` it prints a preview and exits without changing anything; some previews read the current state first to show a diff. The preview names the target host, and the active profile for Splunk Enterprise, so a change aimed at production is visible before it happens:
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
$ splunkctl --profile uat rules delete 'My Rule'
|
|
32
|
+
[DRY RUN] Delete saved search 'My Rule' (profile: uat @ uat.splunk.internal:8089)
|
|
33
|
+
Pass --yes to apply.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Add `--yes` to apply. `splunkctl state push --report FILE` writes a change report with the before and after state for each object, which you can attach to a change ticket.
|
|
37
|
+
|
|
38
|
+
Local configuration writes are not guarded: `splunkctl config init`, `splunkctl config use`, `splunkctl auth login`, and `splunkctl mcp install` write to your own machine immediately.
|
|
39
|
+
|
|
40
|
+
## Agent access
|
|
41
|
+
|
|
42
|
+
The MCP server exposes the command tree to Claude Code, Claude Desktop, Cursor, or any other MCP client. Setup, transports, and the progressive tool-loading model are in the [MCP guide](https://splunkctl.danny.vn/#/guides/mcp).
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
splunkctl mcp install # register the server in ./.mcp.json
|
|
46
|
+
splunkctl commands --json # machine-readable command tree
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Guarded tools keep the same contract as the CLI: a call previews until the agent passes `yes=true` explicitly.
|
|
50
|
+
|
|
51
|
+
## Requirements and limitations
|
|
52
|
+
|
|
53
|
+
- Python 3.12 or newer.
|
|
54
|
+
- A Splunk account with REST API access on port 8089 (or your configured port). Each command needs the Splunk capability or SOAR permission its action requires; `splunkctl doctor` reports which checks pass for the active profile.
|
|
55
|
+
- Enterprise Security commands (`splunkctl es ...`) check for the `SplunkEnterpriseSecuritySuite` app and exit 1 with a `not_found` error when it is not installed.
|
|
56
|
+
- Browser SAML login needs the `browser` extra: `python -m pip install 'splunkctl[browser]'`.
|
|
57
|
+
|
|
58
|
+
## Project and support
|
|
59
|
+
|
|
60
|
+
splunkctl is an independent community project. It is not affiliated with or endorsed by Splunk Inc.
|
|
61
|
+
|
|
62
|
+
Splunk Inc. publishes an unrelated Go CLI with the same executable name, [`splunk/splunkctl`](https://github.com/splunk/splunkctl). This package also installs `splunkctl-py` and leaves a Splunk-format config file untouched, so both tools can be installed together; see [Relationship to Splunk's splunkctl](https://splunkctl.danny.vn/#/guides/splunk-cli).
|
|
63
|
+
|
|
64
|
+
- [Releases](https://github.com/dannyota/splunkctl/releases) and [changelog](https://github.com/dannyota/splunkctl/blob/master/CHANGELOG.md)
|
|
65
|
+
- [Issues](https://github.com/dannyota/splunkctl/issues) for bugs and feature requests; see [SECURITY.md](SECURITY.md) for vulnerabilities
|
|
66
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) for development setup
|
|
67
|
+
- License: [Apache-2.0](https://github.com/dannyota/splunkctl/blob/master/LICENSE)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<!-- summary: Review fired alerts, inspect alert actions, and manage alert suppression on a Splunk instance from the terminal. -->
|
|
2
|
+
|
|
3
|
+
# Review fired alerts
|
|
4
|
+
|
|
5
|
+
When to use: an incident is under way and you need to see which rules fired, when, and at what severity; a maintenance window is coming and noisy rules must be throttled before they flood the on-call channel; or an auditor asks which alerts fired and which were suppressed.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A profile that passes `splunkctl doctor` (see [Configure](configure.md)).
|
|
10
|
+
- Read access to fired alerts for `list`, `get`, and `actions`.
|
|
11
|
+
- Write access to the saved search that owns the rule for `suppress` and `unsuppress`.
|
|
12
|
+
|
|
13
|
+
## Synopsis
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
splunkctl alerts list [--filter SUBSTRING] [--limit N] [--offset N]
|
|
17
|
+
splunkctl alerts get <NAME>
|
|
18
|
+
splunkctl alerts actions
|
|
19
|
+
splunkctl alerts suppress <NAME> [--duration SECONDS] [--yes]
|
|
20
|
+
splunkctl alerts unsuppress <NAME> [--yes]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`NAME` is the rule's saved search name, matched exactly and case-sensitively.
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
### Triage during an incident
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
splunkctl alerts list
|
|
31
|
+
splunkctl alerts list --filter brute
|
|
32
|
+
splunkctl alerts get 'Brute Force Login Attempts'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Expected result: one row per firing with `rule`, `triggered`, `severity`, `sid`, and `actions`. `--filter` matches the rule name; `--limit` and `--offset` page the firing rows client side, so a row is one firing, not one rule. `get` prints every firing of one rule and the firing count.
|
|
36
|
+
|
|
37
|
+
### Check alert action types
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
splunkctl alerts actions
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Expected result: the action types (email, webhook, script, and app-provided actions) configured on the instance. Check this before creating or changing saved searches that fire alerts.
|
|
44
|
+
|
|
45
|
+
### Suppress during a maintenance window
|
|
46
|
+
|
|
47
|
+
> **Safety:** Target is the Splunk host in the active profile. Impact: `alert.suppress=1` and `alert.suppress.period=<SECONDS>s` are written to the rule's saved search, so repeat firings are throttled for that window. Preview with `splunkctl alerts suppress 'Brute Force Login Attempts' --duration 7200`, apply by adding `--yes`, and verify with `splunkctl conf get savedsearches 'Brute Force Login Attempts' --key alert.suppress`.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
splunkctl alerts suppress 'Brute Force Login Attempts' --duration 7200
|
|
51
|
+
splunkctl alerts suppress 'Brute Force Login Attempts' --duration 7200 --yes
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Expected result: the preview prints `[DRY RUN] Throttle alerts for rule (profile: NAME @ HOST:8089)` and the settings it will write; the apply prints `Throttled 'Brute Force Login Attempts' for 7200s.`. `--duration` is in seconds and defaults to 3600. Splunk's fired-alerts endpoint cannot be edited; throttling is a property of the underlying saved search.
|
|
55
|
+
|
|
56
|
+
Suppress several rules during a planned outage:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
for rule in 'Brute Force Login Attempts' 'Failed VPN Auth' 'DNS Exfil'; do
|
|
60
|
+
splunkctl alerts suppress "$rule" --duration 14400 --yes
|
|
61
|
+
done
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Remove suppression after the window
|
|
65
|
+
|
|
66
|
+
> **Safety:** Target is the Splunk host in the active profile. Impact: `alert.suppress=0` is written to the rule's saved search and it alerts normally again. Preview with `splunkctl alerts unsuppress 'Brute Force Login Attempts'`, apply by adding `--yes`, and verify with `splunkctl conf get savedsearches 'Brute Force Login Attempts' --key alert.suppress`.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
splunkctl alerts unsuppress 'Brute Force Login Attempts'
|
|
70
|
+
splunkctl alerts unsuppress 'Brute Force Login Attempts' --yes
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Expected result: `Removed throttling from 'Brute Force Login Attempts'.`. The throttle setting stays on the saved search until you remove it; it does not expire on its own.
|
|
74
|
+
|
|
75
|
+
### Produce JSON for scripts and agents
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
splunkctl alerts list --json
|
|
79
|
+
splunkctl alerts list --json | jq '.[] | select((.severity | tonumber) >= 5)'
|
|
80
|
+
splunkctl alerts get 'Brute Force Login Attempts' --json > alert_detail.json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Expected result: a JSON array of firing rows, suitable for `jq`, an agent, or audit evidence. `--format table|json|csv|jsonl` picks another output format. An agent can consume the JSON directly to correlate fired alerts with a change calendar or file tickets for high-severity triggers.
|
|
84
|
+
|
|
85
|
+
## Troubleshooting
|
|
86
|
+
|
|
87
|
+
- `not_found` from `alerts get`: the name must match the rule exactly; run `splunkctl alerts list --filter <text>` to find the spelling.
|
|
88
|
+
- `not_found` from `suppress` or `unsuppress`: no saved search with that name is visible to your account; check `splunkctl rules list --filter <text>`.
|
|
89
|
+
- `permission` from `suppress` or `unsuppress`: your role cannot edit the saved search in its owning app.
|
|
90
|
+
- `No fired alerts.`: nothing has fired within Splunk's fired-alert retention; this is not an error.
|
|
91
|
+
- A rule keeps firing after `suppress --yes`: throttling suppresses repeat firings for the period after a trigger; it does not disable the search. Disable the rule itself with the commands in [Manage detection rules](rules.md).
|
|
92
|
+
|
|
93
|
+
## See also
|
|
94
|
+
|
|
95
|
+
- [Manage detection rules](rules.md)
|
|
96
|
+
- [Triage ES notables](es.md)
|
|
97
|
+
- [Edit any conf file](conf.md)
|
|
98
|
+
- [Command reference: alerts](../commands/alerts.md)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<!-- summary: Install, update, reload, and uninstall Splunk apps from local packages with a preview before every change. -->
|
|
2
|
+
|
|
3
|
+
# Manage apps
|
|
4
|
+
|
|
5
|
+
When to use: you need to deploy or upgrade a Technology Add-on, a content pack such as Enterprise Security content, or a custom detection app on a remote instance, disable an app during an incident, or audit what is installed, without SSH or the Web UI.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A profile that passes `splunkctl doctor`, including the `Web UI reachable` check: `install` uploads the package through the Splunk Web UI handler.
|
|
10
|
+
- An account allowed to install and edit apps (for example the `admin` role).
|
|
11
|
+
- For `install`: a local `.spl` or `.tar.gz` package.
|
|
12
|
+
|
|
13
|
+
## Synopsis
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
splunkctl apps list [--filter SUBSTRING] [--limit N] [--offset N]
|
|
17
|
+
splunkctl apps get <NAME>
|
|
18
|
+
splunkctl apps install --path <PACKAGE.spl|PACKAGE.tar.gz> [--force] [--yes]
|
|
19
|
+
splunkctl apps update <NAME> [--enabled|--disabled] [--visible|--hidden] [--yes]
|
|
20
|
+
splunkctl apps uninstall <NAME> [--yes]
|
|
21
|
+
splunkctl apps reload [--yes]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
### List and inspect
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
splunkctl apps list
|
|
30
|
+
splunkctl apps list --filter TA-
|
|
31
|
+
splunkctl apps get SplunkForwarder
|
|
32
|
+
splunkctl apps list --json | jq '.[] | {name, version, disabled}'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Expected result: one row per installed app; `get` prints the app's full settings. `--filter`, `--limit`, and `--offset` apply client side.
|
|
36
|
+
|
|
37
|
+
### Install or upgrade from a local package
|
|
38
|
+
|
|
39
|
+
> **Safety:** Target is the Splunk host in the active profile. Impact: the package is uploaded through Splunk Web and installed; with `--force` an existing app of the same name is overwritten. Preview with `splunkctl apps install --path ./Splunk_TA_windows-8.9.0.spl`, apply by adding `--yes`, and verify with `splunkctl apps get Splunk_TA_windows`.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
splunkctl apps install --path ./Splunk_TA_windows-8.9.0.spl
|
|
43
|
+
splunkctl apps install --path ./Splunk_TA_windows-8.9.0.spl --yes
|
|
44
|
+
splunkctl apps install --path ./DA-ESS-ContentUpdate-4.29.0.spl --force --yes
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Expected result: the app appears in `splunkctl apps list`. The upload goes from your machine to the Splunk Web UI handler, so no SSH, SCP, or server filesystem access is needed. `--force` is required when the app already exists on the instance (reinstall or upgrade). An install may still need a Splunk restart to activate new modular inputs or scripted lookups; the CLI does not restart Splunk.
|
|
48
|
+
|
|
49
|
+
### Disable an app during an incident
|
|
50
|
+
|
|
51
|
+
> **Safety:** Target is the Splunk host in the active profile. Impact: the app's scheduled searches and knowledge objects stop running until re-enabled. Preview with `splunkctl apps update SplunkEnterpriseSecuritySuite --disabled`, apply by adding `--yes`, and verify with `splunkctl apps get SplunkEnterpriseSecuritySuite --json` (check `disabled`).
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
splunkctl apps update SplunkEnterpriseSecuritySuite --disabled
|
|
55
|
+
splunkctl apps update SplunkEnterpriseSecuritySuite --disabled --yes
|
|
56
|
+
splunkctl apps update SplunkEnterpriseSecuritySuite --enabled --yes
|
|
57
|
+
splunkctl apps update my_app --enabled --visible --yes
|
|
58
|
+
splunkctl apps update my_app --disabled --hidden --yes
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Expected result: `Updated app 'NAME'.`. `--visible` and `--hidden` control whether the app shows in the Splunk Web app menu; at least one of the four flags is required.
|
|
62
|
+
|
|
63
|
+
### Uninstall an app
|
|
64
|
+
|
|
65
|
+
> **Safety:** Target is the Splunk host in the active profile. Impact: the app and its configuration are removed from the instance. Preview with `splunkctl apps uninstall my_app`, apply by adding `--yes`, and verify with `splunkctl apps list --filter my_app`.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
splunkctl apps uninstall my_app
|
|
69
|
+
splunkctl apps uninstall my_app --yes
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Reload all apps after a bulk change
|
|
73
|
+
|
|
74
|
+
> **Safety:** Target is the Splunk host in the active profile. Impact: every app's configuration is re-read by splunkd. Preview with `splunkctl apps reload`, apply with `splunkctl apps reload --yes`, and verify with `splunkctl apps list`.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
splunkctl apps reload --yes
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Troubleshooting
|
|
81
|
+
|
|
82
|
+
- `not_found` from `get`, `update`, or `uninstall`: the app id (directory name) differs from its label; find it with `splunkctl apps list --filter <text>`.
|
|
83
|
+
- `App install failed` or a `web` error: Splunk Web is not reachable from this machine; run `splunkctl doctor` and check `Web UI reachable`.
|
|
84
|
+
- Install fails because the app already exists: add `--force`.
|
|
85
|
+
- `No settings specified`: `update` needs `--enabled`, `--disabled`, `--visible`, or `--hidden`.
|
|
86
|
+
- `permission` on `update` or `uninstall`: the account lacks app administration rights; use an `admin` account.
|
|
87
|
+
- New inputs or lookups from an installed app do not run: restart Splunk from the server; the CLI does not restart it.
|
|
88
|
+
|
|
89
|
+
## See also
|
|
90
|
+
|
|
91
|
+
- [Diagnose a connection](doctor.md)
|
|
92
|
+
- [Manage detection rules](rules.md)
|
|
93
|
+
- [Manage configuration as code](state.md)
|
|
94
|
+
- [Command reference: apps](../commands/apps.md)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<!-- summary: Produce change-audit and role-based access control attestation reports from Splunk for regulators and reviewers. -->
|
|
2
|
+
|
|
3
|
+
# Audit changes and attest RBAC
|
|
4
|
+
|
|
5
|
+
When to use: a regulator or reviewer asks who changed a saved search, role, or index and when (`audit changes`), or who holds which capabilities and index access for periodic access recertification (`audit rbac`). Both commands are read-only: no guard, no `--yes`.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- A profile that passes `splunkctl doctor` (see [Configure](configure.md)).
|
|
10
|
+
- For `changes`: search access to `index=_audit` (the `admin` role has it by default).
|
|
11
|
+
- For `rbac`: read access to users and roles (`edit_user` and `edit_roles`, or an `admin` account).
|
|
12
|
+
|
|
13
|
+
## Synopsis
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
splunkctl audit changes [--since TIME] [--until TIME] [--user USER] [--action SUBSTRING] [--object-type TYPE] [--limit N]
|
|
17
|
+
splunkctl audit rbac [--roles-only] [--format csv] [--out FILE]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
### Pull the change log for a window
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
splunkctl audit changes
|
|
26
|
+
splunkctl audit changes --since -7d --until -1d
|
|
27
|
+
splunkctl audit changes --limit 2000 --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Expected result: one row per `_audit` event, newest first, with exactly six keys in this order: `time`, `user`, `action`, `object`, `object_type`, `app`. The default window is the last 24 hours (`--since -24h`, `--until now`) and the display cap is 500 rows. Splunk mixes two incompatible event shapes in `_audit`; this command normalizes both:
|
|
31
|
+
|
|
32
|
+
| Sourcetype | Shape | Mapping |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `audittrail` (legacy) | `Audit:[timestamp=..., user=..., action=..., <tail>]` plain text | `user` and `action` parsed directly; `object` only when the line carries a literal `object="..."` marker (common on capability checks like `edit_user` and `edit_roles`); `object_type` always empty, the legacy format has no per-action type field; `app` from `app="..."` or unquoted `app=...` when present |
|
|
35
|
+
| `audittrailv2` (structured) | one JSON object per line | `user` = `actor.name`; `action` = top-level `action`; `object` = `data.name`; `object_type` = `data.type`; `app` = `data.ownership.app` or `data.attributes.app` |
|
|
36
|
+
|
|
37
|
+
`time` always comes from Splunk's indexed `_time`, not a re-parse of either embedded timestamp, so every row has one consistent, sortable value. Real `audittrailv2` events have no `data.object` or `data.object_type` key; `data.name` and `data.type` are the nearest equivalents and are present on object and system category events (config changes). Action, authn, and check category events (ad-hoc searches, logins, capability grants) carry `data.type` sometimes but rarely `data.name`, so `object` stays empty for them, which is correct: they are not changes to a named object. An event matching neither shape is never dropped; it comes back as `action: "unparsed"` with the full raw line in `object`, so evidence stays complete for formats the parser does not know yet.
|
|
38
|
+
|
|
39
|
+
### Filter by user, action, or object type
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
splunkctl audit changes --user jdoe
|
|
43
|
+
splunkctl audit changes --action edit
|
|
44
|
+
splunkctl audit changes --object-type saved_search
|
|
45
|
+
splunkctl audit changes --since -30d --user svc_deploy --action edit --format csv --out changes.csv
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Expected result: only matching rows. `--user` and `--object-type` are case-insensitive exact matches; `--action` is a case-insensitive substring match. Filters run client side on the normalized rows after the fetch, and `--limit` applies after filtering. The raw fetch is unbounded (`count=0`) within the `--since` and `--until` window, so a filter never misses a match because of an arbitrary raw-fetch cutoff. A very wide `--since` over a large `_audit` index fetches every event in that range before limiting, which can be slow; narrow `--since` when you can.
|
|
49
|
+
|
|
50
|
+
### Confirm no flag value reaches the SPL
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
splunkctl --debug audit changes --user 'x" | delete' --action 'y | outputlookup evil.csv'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Expected result: the debug log shows `POST .../search/v2/jobs/ (body: {'search': 'search index=_audit', ...})`. The dispatched search is always the constant `search index=_audit`; `--since` and `--until` go through the job's `earliest_time` and `latest_time` arguments, and the other flags filter rows client side. No flag value, however adversarial, is composed into the SPL string.
|
|
57
|
+
|
|
58
|
+
### Export an RBAC recertification report
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
splunkctl audit rbac
|
|
62
|
+
splunkctl audit rbac --format csv --out recert-2026-07.csv
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Expected result: one row per user with `user`, `email`, `roles` (direct roles, semicolon-joined), `capabilities`, and `srch_indexes_allowed`. The last two are aggregated across the user's direct roles and the full transitive closure of their imported roles, deduplicated, sorted, and semicolon-joined. Example: role `soc_analyst` imports `power`, which imports `user`; a `soc_analyst` user's effective `capabilities` is the union of all three roles' own capabilities. This is what a role with zero capabilities of its own needs (Splunk's built-in `splunk-system-role` only imports `admin`) to show its real effective grant instead of an empty cell. `rbac` reads roles and users through the SDK only; it dispatches no search.
|
|
66
|
+
|
|
67
|
+
### Attest per role instead of per user
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
splunkctl audit rbac --roles-only
|
|
71
|
+
splunkctl audit rbac --roles-only --format csv --out roles-2026-07.csv
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Expected result: one row per role with `role`, `imported_roles` (direct only), `capabilities`, and `srch_indexes_allowed`, the last two aggregated the same transitive way, rooted at that role.
|
|
75
|
+
|
|
76
|
+
Multi-value fields (`roles`, `capabilities`, `srch_indexes_allowed`, `imported_roles`) join with `;`, never a newline. Splunk role, capability, and index names cannot contain a semicolon, so the join is lossless and never produces an embedded newline inside a CSV cell; `--format csv` output round-trips through Python's `csv` module.
|
|
77
|
+
|
|
78
|
+
## Troubleshooting
|
|
79
|
+
|
|
80
|
+
- `permission` or an empty result from `changes`: your role cannot search `index=_audit`; use an `admin` account or add `_audit` to the role's allowed indexes.
|
|
81
|
+
- `timeout` on `changes`: the window is too wide; narrow `--since` or raise the global `--timeout`.
|
|
82
|
+
- Rows show `action: "unparsed"`: the event matched neither audit shape; the raw line is in `object`, so the evidence is still complete.
|
|
83
|
+
- `object_type` is empty on every row: the instance writes only the legacy `audittrail` shape, which has no type field; filter on `--action` instead.
|
|
84
|
+
- `permission` from `rbac`: the account cannot list users or roles; it needs `edit_user` and `edit_roles` or an `admin` role.
|
|
85
|
+
- Fewer rows than expected: `--limit` defaults to 500 after filtering; raise it.
|
|
86
|
+
|
|
87
|
+
## See also
|
|
88
|
+
|
|
89
|
+
- [Manage users and roles](users.md)
|
|
90
|
+
- [Run searches](search.md)
|
|
91
|
+
- [Exit codes](exit-codes.md)
|
|
92
|
+
- [Command reference: audit](../commands/audit.md)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<!-- summary: Complete Splunk and SOAR SAML single sign-on, including a second factor, in a browser and reuse the session from every splunkctl command. -->
|
|
2
|
+
|
|
3
|
+
# Log in through browser SAML
|
|
4
|
+
|
|
5
|
+
When to use: your Splunk or SOAR instance authenticates through a SAML identity provider (with or without a second factor), so a username and password or a token cannot be stored in the profile, and you want every splunkctl command to reuse one browser login until it expires.
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- splunkctl with the browser extra and Chromium:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
python -m pip install 'splunkctl[browser]'
|
|
13
|
+
python -m playwright install chromium
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Configuration succeeds without them; `splunkctl auth login` prints these commands when they are missing.
|
|
17
|
+
|
|
18
|
+
- A machine with a display: login opens a headed Chromium window. The browser handles the identity provider; splunkctl never reads or stores TOTP secrets or codes.
|
|
19
|
+
- A profile in browser mode (`auth_mode: browser` with a `web_url`), written by `config init` as shown below.
|
|
20
|
+
- Not supported: reading or storing TOTP secrets, native Splunk Duo or RSA flows, OpenID Connect or OAuth, logging in to both products in one command, and a local splunkctl callback redirect.
|
|
21
|
+
|
|
22
|
+
## Synopsis
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
splunkctl config init --web-url <https://splunk.example.com:8000> [--profile NAME] [--auth-mode auto|browser]
|
|
26
|
+
splunkctl config init --soar --web-url <https://soar.example.com> [--sso-url URL] [--profile NAME]
|
|
27
|
+
splunkctl auth login --target <siem|soar>
|
|
28
|
+
splunkctl auth status [--target siem|soar|both]
|
|
29
|
+
splunkctl auth logout [--target siem|soar|both]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Workflow
|
|
33
|
+
|
|
34
|
+
### Detect SAML during setup
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
splunkctl config init --web-url https://splunk.example.com:8000
|
|
38
|
+
splunkctl config init --soar --web-url https://soar.example.com --sso-url 'https://soar.example.com/saml2/login?idp=okta&next=/'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Expected result: `config init` probes the product's public login route. When it sees a redirect to an external identity provider it records `auth_mode: browser` and stores the product `web_url` in the profile. SAML detection runs only when `--web-url` is given. Pass `--auth-mode browser` to force browser mode without probing. For SOAR, pass `--sso-url` because SOAR's `/login` route is local-only.
|
|
42
|
+
|
|
43
|
+
### Log in
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
splunkctl auth login --target siem
|
|
47
|
+
splunkctl auth login --target soar
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Expected result: Chromium opens at the product login route; you complete the identity provider prompts, including any TOTP code; splunkctl extracts only the product session (the Splunk `splunkd_<port>` cookie, or the SOAR `sessionid` and `csrftoken` cookies), proves it against the product API, and prints `siem session stored (profile 'NAME').`. `login` requires exactly one target because two back-to-back browser flows are easy to confuse.
|
|
51
|
+
|
|
52
|
+
### Check the session
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
splunkctl auth status
|
|
56
|
+
splunkctl auth status --target siem
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Expected result: one row per target with `status` set to `missing`, `valid`, `expired`, or `unreachable`. Without `--target`, only targets configured for browser mode are checked; if none are, it prints `No browser-authenticated targets configured.`.
|
|
60
|
+
|
|
61
|
+
### Use the session from normal commands
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
splunkctl search oneshot 'index=_internal | head 5'
|
|
65
|
+
splunkctl soar test
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Expected result: commands reuse the cached session whenever the active profile selects browser mode. A missing or expired session never opens a browser; the command fails with the exact `splunkctl auth login --target ...` instruction to run instead.
|
|
69
|
+
|
|
70
|
+
### Log out
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
splunkctl auth logout --target siem
|
|
74
|
+
splunkctl auth logout --target both
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Expected result: a best-effort remote logout, then `Logout complete.`. The local session is always removed, even if the remote endpoint refuses; a refused remote logout prints a warning.
|
|
78
|
+
|
|
79
|
+
Sessions live under `~/.splunkctl/sessions/<profile>/<target>.json` with directory mode `0700` and file mode `0600`. A record holds only the target, profile, product origin, product session values, and validation timestamps. It never stores passwords, Playwright storage state, identity-provider cookies, or TOTP secrets, and session values are redacted from all output.
|
|
80
|
+
|
|
81
|
+
## Troubleshooting
|
|
82
|
+
|
|
83
|
+
- `usage` error `siem is configured for token authentication, not browser login`: the profile has `auth_mode: token` or `password`; rerun `splunkctl config init --web-url URL` so SAML is detected, or pass `--auth-mode browser`.
|
|
84
|
+
- `login` prints `pip install` and `playwright install` commands: the browser extra is missing; run them and retry.
|
|
85
|
+
- `auth` error `login finished but the product session was rejected`: the browser ended on a different origin than `web_url`, or the identity provider flow did not complete; check `web_url` with `splunkctl config show` and log in again.
|
|
86
|
+
- `connection` error `SIEM is unreachable while checking the browser session`: the product API is down or blocked; fix connectivity with [Diagnose a connection](doctor.md).
|
|
87
|
+
- A command reports the session is missing or expired: run the `splunkctl auth login --target ...` command it prints; commands never open a browser on their own.
|
|
88
|
+
- `remote logout failed; clearing local session`: the product refused the logout call; the local file is still removed and a new `login` is required.
|
|
89
|
+
|
|
90
|
+
## See also
|
|
91
|
+
|
|
92
|
+
- [Configure](configure.md)
|
|
93
|
+
- [Install](install.md)
|
|
94
|
+
- [Set up and check SOAR](soar.md)
|
|
95
|
+
- [Contributor lab: Keycloak SAML](keycloak-lab.md)
|
|
96
|
+
- [Command reference: auth](../commands/auth.md)
|