endpoint-aiops 0.1.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.
Files changed (54) hide show
  1. endpoint_aiops-0.1.0/.gitignore +22 -0
  2. endpoint_aiops-0.1.0/CHANGELOG.md +45 -0
  3. endpoint_aiops-0.1.0/LICENSE +21 -0
  4. endpoint_aiops-0.1.0/PKG-INFO +108 -0
  5. endpoint_aiops-0.1.0/README.md +92 -0
  6. endpoint_aiops-0.1.0/RELEASE_NOTES.md +43 -0
  7. endpoint_aiops-0.1.0/SECURITY.md +75 -0
  8. endpoint_aiops-0.1.0/endpoint_aiops/__init__.py +9 -0
  9. endpoint_aiops-0.1.0/endpoint_aiops/cli/__init__.py +9 -0
  10. endpoint_aiops-0.1.0/endpoint_aiops/cli/_common.py +78 -0
  11. endpoint_aiops-0.1.0/endpoint_aiops/cli/_root.py +58 -0
  12. endpoint_aiops-0.1.0/endpoint_aiops/cli/doctor.py +21 -0
  13. endpoint_aiops-0.1.0/endpoint_aiops/cli/drift.py +45 -0
  14. endpoint_aiops-0.1.0/endpoint_aiops/cli/endpoint.py +90 -0
  15. endpoint_aiops-0.1.0/endpoint_aiops/cli/init.py +101 -0
  16. endpoint_aiops-0.1.0/endpoint_aiops/cli/overview.py +16 -0
  17. endpoint_aiops-0.1.0/endpoint_aiops/cli/secret.py +103 -0
  18. endpoint_aiops-0.1.0/endpoint_aiops/cli/session.py +47 -0
  19. endpoint_aiops-0.1.0/endpoint_aiops/config.py +131 -0
  20. endpoint_aiops-0.1.0/endpoint_aiops/connection.py +163 -0
  21. endpoint_aiops-0.1.0/endpoint_aiops/doctor.py +84 -0
  22. endpoint_aiops-0.1.0/endpoint_aiops/governance/__init__.py +40 -0
  23. endpoint_aiops-0.1.0/endpoint_aiops/governance/audit.py +377 -0
  24. endpoint_aiops-0.1.0/endpoint_aiops/governance/budget.py +225 -0
  25. endpoint_aiops-0.1.0/endpoint_aiops/governance/decorators.py +474 -0
  26. endpoint_aiops-0.1.0/endpoint_aiops/governance/paths.py +23 -0
  27. endpoint_aiops-0.1.0/endpoint_aiops/governance/patterns.py +378 -0
  28. endpoint_aiops-0.1.0/endpoint_aiops/governance/policy.py +411 -0
  29. endpoint_aiops-0.1.0/endpoint_aiops/governance/sanitize.py +39 -0
  30. endpoint_aiops-0.1.0/endpoint_aiops/governance/undo.py +218 -0
  31. endpoint_aiops-0.1.0/endpoint_aiops/ops/__init__.py +1 -0
  32. endpoint_aiops-0.1.0/endpoint_aiops/ops/_util.py +26 -0
  33. endpoint_aiops-0.1.0/endpoint_aiops/ops/drift.py +123 -0
  34. endpoint_aiops-0.1.0/endpoint_aiops/ops/inventory.py +101 -0
  35. endpoint_aiops-0.1.0/endpoint_aiops/ops/remediation.py +56 -0
  36. endpoint_aiops-0.1.0/endpoint_aiops/ops/sessions.py +184 -0
  37. endpoint_aiops-0.1.0/endpoint_aiops/secretstore.py +302 -0
  38. endpoint_aiops-0.1.0/mcp_server/__init__.py +1 -0
  39. endpoint_aiops-0.1.0/mcp_server/_shared.py +99 -0
  40. endpoint_aiops-0.1.0/mcp_server/server.py +33 -0
  41. endpoint_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
  42. endpoint_aiops-0.1.0/mcp_server/tools/drift.py +65 -0
  43. endpoint_aiops-0.1.0/mcp_server/tools/inventory.py +47 -0
  44. endpoint_aiops-0.1.0/mcp_server/tools/remediation.py +62 -0
  45. endpoint_aiops-0.1.0/mcp_server/tools/sessions.py +69 -0
  46. endpoint_aiops-0.1.0/pyproject.toml +59 -0
  47. endpoint_aiops-0.1.0/server.json +21 -0
  48. endpoint_aiops-0.1.0/skills/endpoint-aiops/SKILL.md +103 -0
  49. endpoint_aiops-0.1.0/skills/endpoint-aiops/references/capabilities.md +35 -0
  50. endpoint_aiops-0.1.0/skills/endpoint-aiops/references/cli-reference.md +47 -0
  51. endpoint_aiops-0.1.0/skills/endpoint-aiops/references/setup-guide.md +78 -0
  52. endpoint_aiops-0.1.0/smithery.yaml +9 -0
  53. endpoint_aiops-0.1.0/tests/test_secretstore.py +99 -0
  54. endpoint_aiops-0.1.0/tests/test_smoke.py +331 -0
@@ -0,0 +1,22 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+
8
+ # Virtual envs / build
9
+ .venv/
10
+ dist/
11
+ build/
12
+
13
+ # uv
14
+ uv.lock
15
+
16
+ # Local config / secrets (never commit)
17
+ *.env
18
+ .env
19
+ config.yaml
20
+
21
+ # OS
22
+ .DS_Store
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to endpoint-aiops are documented here. This project adheres
4
+ to [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [0.1.0] — preview
7
+
8
+ Initial preview release: governed AI-ops for managed-endpoint fleets (thin
9
+ clients / VDI) with a bundled governance harness. **Mock-validated only — not
10
+ yet verified against a live endpoint-management server.**
11
+
12
+ ### Added
13
+
14
+ - **9 MCP tools** (7 read, 2 write), every one wrapped with the bundled
15
+ `@governed_tool` harness (audit, policy, token/runaway budget, undo,
16
+ risk-tiers):
17
+ - **Overview** — `overview` (fleet health: online/offline, stale endpoints,
18
+ agent/patch spread).
19
+ - **Inventory** — `endpoint_list`, `endpoint_get`.
20
+ - **Sessions** — `session_list`; `login_storm_analysis` — detect login storms
21
+ (bursts of concurrent logins in a sliding window) and rank the slowest
22
+ login/boot contributors.
23
+ - **Drift** — `drift_report` (endpoints deviating from a per-field baseline,
24
+ fleet-majority derived when none is given); `patch_status` (patch-level
25
+ distribution + endpoints behind the target).
26
+ - **Remediation** — `endpoint_assign_profile` (write, high, reversible:
27
+ captures the prior profile, records an inverse reassign undo descriptor);
28
+ `endpoint_reboot` (write, medium, no safe inverse, captures before-state).
29
+ - **Pure/offline analysis** — `login_storm_analysis`, `drift_report`, and
30
+ `patch_status` accept injected records for analysis without a live server.
31
+ - **Encrypted secret store** — the management-server API key is stored encrypted
32
+ in `~/.endpoint-aiops/secrets.enc` (Fernet + scrypt); never plaintext on disk.
33
+ Legacy `ENDPOINT_<TARGET>_APIKEY` env var honoured as a fallback.
34
+ - **CLI** (`endpoint-aiops`) — `init` wizard, `secret` management, `doctor`,
35
+ `overview`, and the `endpoint` / `session` / `drift` sub-commands.
36
+ - **Bearer-auth REST connection layer** over a generic endpoint-management REST
37
+ API with centralised teaching error translation (`EndpointApiError`).
38
+
39
+ ### Known limitations
40
+
41
+ - Preview / mock-only: the REST paths (`/endpoints`, `/sessions`, `/version`,
42
+ `/endpoints/{id}/profile`, `/endpoints/{id}/reboot`) are modelled generically
43
+ and need live verification against a real management server.
44
+ - Out of scope by design: enrollment/de-enrollment, image/OTA management, and
45
+ any bulk destructive operation.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wei <zhouwei008@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: endpoint-aiops
3
+ Version: 0.1.0
4
+ Summary: Governed AI-ops for managed-endpoint fleets (thin clients / VDI): login-storm & drift analysis with a built-in governance harness (audit, budget, undo, risk tiers)
5
+ Author-email: wei <zhouwei008@gmail.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: cryptography>=42.0
10
+ Requires-Dist: httpx<1.0,>=0.27
11
+ Requires-Dist: mcp[cli]<2.0,>=1.10
12
+ Requires-Dist: pyyaml<7.0,>=6.0
13
+ Requires-Dist: rich<16.0,>=13.0
14
+ Requires-Dist: typer<1.0,>=0.12
15
+ Description-Content-Type: text/markdown
16
+
17
+ <!-- mcp-name: io.github.AIops-tools/endpoint-aiops -->
18
+
19
+ # Endpoint AIops (preview)
20
+
21
+ > **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by any endpoint-management vendor.** Product and trademark names belong to their owners. MIT licensed.
22
+
23
+ Governed AI-ops for **managed-endpoint fleets** — thin clients, VDI endpoints,
24
+ and other centrally-managed devices — with a **built-in governance harness**:
25
+ unified audit log, policy engine, token/runaway budget guard, undo-token
26
+ recording, and graduated-autonomy risk tiers. Vendor-neutral: it talks to an
27
+ endpoint-management server's REST API (Bearer auth). Self-contained: no
28
+ dependencies beyond `httpx` and the MCP SDK. **Preview — mock-validated only,
29
+ not yet verified against a live management server.**
30
+
31
+ ## What it does
32
+
33
+ Two signature analyses, plus the guarded reads and writes around them:
34
+
35
+ - **Login-storm analysis** — during a "everyone logs in at 9am" incident,
36
+ detect the storm (bursts of concurrent logins in a sliding window) and rank
37
+ the endpoints/users dragging login and boot times. Every flag is reported
38
+ with its number, not a black-box verdict.
39
+ - **Patch / config drift** — find endpoints that have drifted from the fleet
40
+ (outdated patch level, stray agent version, divergent OS build or config
41
+ profile). With no declared baseline it derives one by fleet majority, so it
42
+ works before a gold image exists.
43
+
44
+ ## What works
45
+
46
+ - **CLI** (`endpoint-aiops ...`): `init`, `overview`, `endpoint list/get/assign-profile/reboot`, `session list/storm`, `drift report/patch`, `secret set/list/rm/migrate/rotate-password`, `doctor`, `mcp`.
47
+ - **MCP server** (`endpoint-aiops mcp` or `endpoint-aiops-mcp`): **9 tools** (7 read, 2 write), every one wrapped with the bundled `@governed_tool` harness.
48
+ - **Encrypted credentials**: the management-server API key lives in an encrypted store `~/.endpoint-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on disk**. Unlock with a master password from `ENDPOINT_AIOPS_MASTER_PASSWORD` (MCP/CI) or an interactive prompt (CLI).
49
+ - **Reversibility**: `endpoint_assign_profile` (`high` risk) captures the prior profile and records an inverse "reassign the prior profile" undo descriptor. `endpoint_reboot` (`medium` risk) captures the prior online state for the audit record but declares no undo (a reboot has no safe inverse).
50
+ - **Safety**: state-changing CLI ops (`endpoint assign-profile`, `endpoint reboot`) require double confirmation and support `--dry-run`.
51
+
52
+ ## Capability matrix (9 MCP tools)
53
+
54
+ | Category | Tools | Count | R/W |
55
+ |----------|-------|:-----:|:---:|
56
+ | **Overview** | `overview` | 1 | read |
57
+ | **Inventory** | `endpoint_list`, `endpoint_get` | 2 | read |
58
+ | **Sessions** | `session_list`, `login_storm_analysis` | 2 | read |
59
+ | **Drift** | `drift_report`, `patch_status` | 2 | read |
60
+ | **Remediation** | `endpoint_assign_profile` | 1 | write (high) |
61
+ | | `endpoint_reboot` | 1 | write (medium) |
62
+
63
+ The analysis tools (`login_storm_analysis`, `drift_report`, `patch_status`)
64
+ accept injected records for pure/offline analysis, or pull live from a
65
+ configured target.
66
+
67
+ ## Quick start
68
+
69
+ ```bash
70
+ uv tool install endpoint-aiops # or: pipx install endpoint-aiops
71
+ endpoint-aiops init # wizard: add a target + store its API key (encrypted)
72
+ endpoint-aiops doctor # verify config, secrets, connectivity
73
+ endpoint-aiops overview # one-shot fleet health
74
+ endpoint-aiops session storm # detect a login storm + slow contributors
75
+ endpoint-aiops drift report # endpoints drifted from the fleet baseline
76
+ ```
77
+
78
+ Run as an MCP server (stdio):
79
+
80
+ ```bash
81
+ export ENDPOINT_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
82
+ endpoint-aiops-mcp
83
+ ```
84
+
85
+ ## Governance
86
+
87
+ Every MCP tool passes through the bundled `@governed_tool` harness:
88
+
89
+ - **Audit** — every call (params, result, status, duration, risk tier,
90
+ approver, rationale) is logged to `~/.endpoint-aiops/audit.db` (relocatable
91
+ via `ENDPOINT_AIOPS_HOME`).
92
+ - **Budget / runaway guard** — token and call budgets trip a circuit breaker.
93
+ - **Risk tiers** — graduated autonomy; high-risk ops can require a named
94
+ approver (`ENDPOINT_AUDIT_APPROVED_BY` / `ENDPOINT_AUDIT_RATIONALE`).
95
+ - **Undo recording** — reversible writes record an inverse descriptor.
96
+
97
+ ## Scope
98
+
99
+ This is the **IT-endpoint** member of the AIops-tools family (governed AI-ops
100
+ with audit + budget + undo + risk tiers). For **OT / industrial edge**
101
+ (Modbus, OPC-UA, PROFINET, …) see the separate `industrial-aiops` line.
102
+
103
+ ## Status
104
+
105
+ **Preview — mock-validated only.** The endpoint-management REST paths are
106
+ modelled generically (`/endpoints`, `/sessions`, `/version`) and need live
107
+ verification against a real server. Missing a capability or a server dialect?
108
+ Open an issue or PR — contributions welcome.
@@ -0,0 +1,92 @@
1
+ <!-- mcp-name: io.github.AIops-tools/endpoint-aiops -->
2
+
3
+ # Endpoint AIops (preview)
4
+
5
+ > **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by any endpoint-management vendor.** Product and trademark names belong to their owners. MIT licensed.
6
+
7
+ Governed AI-ops for **managed-endpoint fleets** — thin clients, VDI endpoints,
8
+ and other centrally-managed devices — with a **built-in governance harness**:
9
+ unified audit log, policy engine, token/runaway budget guard, undo-token
10
+ recording, and graduated-autonomy risk tiers. Vendor-neutral: it talks to an
11
+ endpoint-management server's REST API (Bearer auth). Self-contained: no
12
+ dependencies beyond `httpx` and the MCP SDK. **Preview — mock-validated only,
13
+ not yet verified against a live management server.**
14
+
15
+ ## What it does
16
+
17
+ Two signature analyses, plus the guarded reads and writes around them:
18
+
19
+ - **Login-storm analysis** — during a "everyone logs in at 9am" incident,
20
+ detect the storm (bursts of concurrent logins in a sliding window) and rank
21
+ the endpoints/users dragging login and boot times. Every flag is reported
22
+ with its number, not a black-box verdict.
23
+ - **Patch / config drift** — find endpoints that have drifted from the fleet
24
+ (outdated patch level, stray agent version, divergent OS build or config
25
+ profile). With no declared baseline it derives one by fleet majority, so it
26
+ works before a gold image exists.
27
+
28
+ ## What works
29
+
30
+ - **CLI** (`endpoint-aiops ...`): `init`, `overview`, `endpoint list/get/assign-profile/reboot`, `session list/storm`, `drift report/patch`, `secret set/list/rm/migrate/rotate-password`, `doctor`, `mcp`.
31
+ - **MCP server** (`endpoint-aiops mcp` or `endpoint-aiops-mcp`): **9 tools** (7 read, 2 write), every one wrapped with the bundled `@governed_tool` harness.
32
+ - **Encrypted credentials**: the management-server API key lives in an encrypted store `~/.endpoint-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on disk**. Unlock with a master password from `ENDPOINT_AIOPS_MASTER_PASSWORD` (MCP/CI) or an interactive prompt (CLI).
33
+ - **Reversibility**: `endpoint_assign_profile` (`high` risk) captures the prior profile and records an inverse "reassign the prior profile" undo descriptor. `endpoint_reboot` (`medium` risk) captures the prior online state for the audit record but declares no undo (a reboot has no safe inverse).
34
+ - **Safety**: state-changing CLI ops (`endpoint assign-profile`, `endpoint reboot`) require double confirmation and support `--dry-run`.
35
+
36
+ ## Capability matrix (9 MCP tools)
37
+
38
+ | Category | Tools | Count | R/W |
39
+ |----------|-------|:-----:|:---:|
40
+ | **Overview** | `overview` | 1 | read |
41
+ | **Inventory** | `endpoint_list`, `endpoint_get` | 2 | read |
42
+ | **Sessions** | `session_list`, `login_storm_analysis` | 2 | read |
43
+ | **Drift** | `drift_report`, `patch_status` | 2 | read |
44
+ | **Remediation** | `endpoint_assign_profile` | 1 | write (high) |
45
+ | | `endpoint_reboot` | 1 | write (medium) |
46
+
47
+ The analysis tools (`login_storm_analysis`, `drift_report`, `patch_status`)
48
+ accept injected records for pure/offline analysis, or pull live from a
49
+ configured target.
50
+
51
+ ## Quick start
52
+
53
+ ```bash
54
+ uv tool install endpoint-aiops # or: pipx install endpoint-aiops
55
+ endpoint-aiops init # wizard: add a target + store its API key (encrypted)
56
+ endpoint-aiops doctor # verify config, secrets, connectivity
57
+ endpoint-aiops overview # one-shot fleet health
58
+ endpoint-aiops session storm # detect a login storm + slow contributors
59
+ endpoint-aiops drift report # endpoints drifted from the fleet baseline
60
+ ```
61
+
62
+ Run as an MCP server (stdio):
63
+
64
+ ```bash
65
+ export ENDPOINT_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
66
+ endpoint-aiops-mcp
67
+ ```
68
+
69
+ ## Governance
70
+
71
+ Every MCP tool passes through the bundled `@governed_tool` harness:
72
+
73
+ - **Audit** — every call (params, result, status, duration, risk tier,
74
+ approver, rationale) is logged to `~/.endpoint-aiops/audit.db` (relocatable
75
+ via `ENDPOINT_AIOPS_HOME`).
76
+ - **Budget / runaway guard** — token and call budgets trip a circuit breaker.
77
+ - **Risk tiers** — graduated autonomy; high-risk ops can require a named
78
+ approver (`ENDPOINT_AUDIT_APPROVED_BY` / `ENDPOINT_AUDIT_RATIONALE`).
79
+ - **Undo recording** — reversible writes record an inverse descriptor.
80
+
81
+ ## Scope
82
+
83
+ This is the **IT-endpoint** member of the AIops-tools family (governed AI-ops
84
+ with audit + budget + undo + risk tiers). For **OT / industrial edge**
85
+ (Modbus, OPC-UA, PROFINET, …) see the separate `industrial-aiops` line.
86
+
87
+ ## Status
88
+
89
+ **Preview — mock-validated only.** The endpoint-management REST paths are
90
+ modelled generically (`/endpoints`, `/sessions`, `/version`) and need live
91
+ verification against a real server. Missing a capability or a server dialect?
92
+ Open an issue or PR — contributions welcome.
@@ -0,0 +1,43 @@
1
+ # Endpoint AIops v0.1.0 — preview
2
+
3
+ Governed AI-ops for **managed-endpoint fleets** (thin clients / VDI) for AI
4
+ agents, with a built-in governance harness (audit, policy, token/runaway
5
+ budget, undo-token recording, graduated risk tiers) and an encrypted credential
6
+ store. Standalone — no external skill-family dependency.
7
+
8
+ > **Preview / mock-only.** All behaviour is validated against mocked REST
9
+ > responses; it has not been run against a live endpoint-management server. The
10
+ > fastest live check is `endpoint-aiops doctor`.
11
+
12
+ ## Highlights
13
+
14
+ - **9 MCP tools** (7 read, 2 write), every one wrapped with `@governed_tool`.
15
+ - Read: fleet `overview`; inventory (`endpoint_list`, `endpoint_get`);
16
+ sessions (`session_list`, `login_storm_analysis`); drift (`drift_report`,
17
+ `patch_status`).
18
+ - Write: `endpoint_assign_profile` (high, reversible — records an inverse
19
+ reassign undo), `endpoint_reboot` (medium, no safe inverse, captures
20
+ before-state).
21
+ - **Two signature analyses** — login-storm detection + slow login/boot ranking,
22
+ and patch/config drift vs a fleet-majority (or explicit) baseline. Both accept
23
+ injected records for offline analysis.
24
+ - **Encrypted API key store** (`~/.endpoint-aiops/secrets.enc`, Fernet + scrypt)
25
+ — never plaintext on disk; legacy `ENDPOINT_<TARGET>_APIKEY` env fallback.
26
+ - **CLI** with an `init` onboarding wizard, `secret` management, and `doctor`.
27
+ - **Bearer-auth REST connection layer** over a generic endpoint-management REST
28
+ API with teaching error translation (`EndpointApiError`).
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ uv tool install endpoint-aiops
34
+ endpoint-aiops init
35
+ endpoint-aiops doctor
36
+ ```
37
+
38
+ ## Caveats
39
+
40
+ - The REST paths are modelled generically (`/endpoints`, `/sessions`,
41
+ `/version`, `/endpoints/{id}/profile|reboot`) and need live verification.
42
+ - Out of scope by design: enrollment/de-enrollment, image/OTA management, and
43
+ any bulk destructive operation.
@@ -0,0 +1,75 @@
1
+ # Security Policy
2
+
3
+ ## Disclaimer
4
+
5
+ Community-maintained open-source project. **Not affiliated with, endorsed by, or
6
+ sponsored by any endpoint-management vendor.** Product and trademark names
7
+ belong to their owners. Source is publicly auditable under the MIT license.
8
+
9
+ ## Reporting Vulnerabilities
10
+
11
+ Report privately via a GitHub Security Advisory on
12
+ [github.com/AIops-tools/Endpoint-AIops](https://github.com/AIops-tools/Endpoint-AIops/security/advisories)
13
+ or email zhouwei008@gmail.com. Please do not open public issues for security
14
+ reports.
15
+
16
+ ## Security Design
17
+
18
+ ### Credential Management
19
+ - Per-target Endpoint API keys live **encrypted** in
20
+ `~/.endpoint-aiops/secrets.enc` (Fernet/AES-128 + scrypt-derived key; chmod
21
+ 600), never in `config.yaml` and never in source. The master password is
22
+ never stored — only a per-store random salt and the ciphertext are on disk.
23
+ - A legacy plaintext env var `ENDPOINT_<TARGET_NAME_UPPER>_APIKEY` is still
24
+ honoured as a fallback with a deprecation warning (migrate with
25
+ `endpoint-aiops secret migrate`).
26
+ - The API key is sent as an `Authorization: Bearer` header at request time and
27
+ held only in memory. Keys are never logged or echoed; the config file holds
28
+ only host, port, api_path, and TLS settings.
29
+
30
+ ### Governed Operations
31
+ Every MCP tool runs through the bundled `@governed_tool` harness
32
+ (`endpoint_aiops.governance`):
33
+ - **Audit** — every call logged to a local SQLite DB under `~/.endpoint-aiops/`
34
+ (relocatable via `ENDPOINT_AIOPS_HOME`), agent-attributed, secret-redacted.
35
+ - **Token/runaway budget** — hard ceilings (`ENDPOINT_MAX_TOOL_CALLS` /
36
+ `ENDPOINT_MAX_TOOL_SECONDS`) plus an on-by-default guard that trips a tight
37
+ poll/retry loop, preventing unbounded API consumption (e.g. polling a slow
38
+ session).
39
+ - **Graduated risk tiers** — `~/.endpoint-aiops/rules.yaml` `risk_tiers` gate
40
+ writes by environment/tag; the highest tiers require a recorded approver.
41
+ - **Undo-token recording** — `endpoint_assign_profile` captures the prior
42
+ profile and records an inverse "reassign the prior profile" descriptor so the
43
+ change can be rolled back.
44
+
45
+ ### State-Changing Operations
46
+ `endpoint assign-profile` and `endpoint reboot` require double confirmation at
47
+ the CLI layer and support `--dry-run`. `endpoint_assign_profile` is
48
+ `risk_level=high` and reversible (captures the prior profile, records an undo
49
+ descriptor); `endpoint_reboot` is `risk_level=medium` and has no safe inverse
50
+ (captures the before-state for the audit record, records no undo token).
51
+
52
+ ### SSL/TLS Verification
53
+ `verify_ssl` defaults to true; disable only for self-signed lab certificates.
54
+
55
+ ### Prompt-Injection Protection
56
+ All server-returned text (hostnames, usernames, profile ids, session fields) is
57
+ passed through a `sanitize()` truncate + control-character strip before reaching
58
+ the agent.
59
+
60
+ ### Network Scope
61
+ No webhooks, no telemetry, no outbound calls beyond the configured
62
+ endpoint-management REST API endpoint. No post-install scripts or background
63
+ services.
64
+
65
+ ## Static Analysis
66
+
67
+ ```bash
68
+ uvx bandit -r endpoint_aiops/ mcp_server/
69
+ uv run ruff check .
70
+ ```
71
+
72
+ ## Supported Versions
73
+
74
+ The latest released version receives security fixes. This is a preview (0.x);
75
+ pin a version in production.
@@ -0,0 +1,9 @@
1
+ """endpoint-aiops — governed Endpoint SCALE operations for AI agents.
2
+
3
+ Standalone and self-contained: the governance harness (audit, token budget,
4
+ undo-token recording, graduated risk tiers, prompt-injection sanitize) is
5
+ bundled under ``endpoint_aiops.governance`` — this package has no external
6
+ skill-family dependency. Preview: not yet full-coverage.
7
+ """
8
+
9
+ __version__ = "0.1.0"
@@ -0,0 +1,9 @@
1
+ """CLI package for endpoint-aiops.
2
+
3
+ Re-exports ``app`` so the pyproject entry point
4
+ ``endpoint-aiops = "endpoint_aiops.cli:app"`` works unchanged.
5
+ """
6
+
7
+ from endpoint_aiops.cli._root import app
8
+
9
+ __all__ = ["app"]
@@ -0,0 +1,78 @@
1
+ """Shared helpers for endpoint-aiops CLI sub-modules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import functools
6
+ from collections.abc import Callable
7
+ from pathlib import Path
8
+ from typing import Annotated, Any
9
+
10
+ import typer
11
+ from rich.console import Console
12
+
13
+ console = Console()
14
+
15
+ # ─── Shared Option types ───────────────────────────────────────────────────
16
+
17
+ TargetOption = Annotated[
18
+ str | None, typer.Option("--target", "-t", help="Target name from config")
19
+ ]
20
+ DryRunOption = Annotated[
21
+ bool, typer.Option("--dry-run", help="Print the API call without executing")
22
+ ]
23
+
24
+
25
+ def _cli_error_types() -> tuple[type[BaseException], ...]:
26
+ """Exceptions translated to a one-line teaching error instead of a traceback."""
27
+ from endpoint_aiops.connection import EndpointApiError
28
+
29
+ return (EndpointApiError, KeyError, OSError, ValueError)
30
+
31
+
32
+ def cli_errors(fn: Callable) -> Callable:
33
+ """Translate known exceptions into one red line + exit code 1."""
34
+
35
+ @functools.wraps(fn)
36
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
37
+ try:
38
+ return fn(*args, **kwargs)
39
+ except (typer.Exit, typer.Abort):
40
+ raise
41
+ except _cli_error_types() as e:
42
+ message = str(e)
43
+ if isinstance(e, KeyError):
44
+ message = f"Missing required key or environment variable: {message}"
45
+ console.print(f"[red]Error: {message}[/]")
46
+ raise typer.Exit(1) from e
47
+
48
+ return wrapper
49
+
50
+
51
+ def get_connection(target: str | None, config_path: Path | None = None):
52
+ """Return a (conn, config) tuple for the given target."""
53
+ from endpoint_aiops.config import load_config
54
+ from endpoint_aiops.connection import ConnectionManager
55
+
56
+ cfg = load_config(config_path)
57
+ mgr = ConnectionManager(cfg)
58
+ return mgr.connect(target), cfg
59
+
60
+
61
+ def dry_run_print(*, operation: str, api_call: str, parameters: dict | None = None) -> None:
62
+ """Print a dry-run preview of the API call that would be made."""
63
+ console.print("\n[bold magenta][DRY-RUN] No changes will be made.[/]")
64
+ console.print(f"[magenta] Operation: {operation}[/]")
65
+ console.print(f"[magenta] API Call: {api_call}[/]")
66
+ for k, v in (parameters or {}).items():
67
+ console.print(f"[magenta] Param: {k} = {v}[/]")
68
+ console.print("[magenta] Run without --dry-run to execute.[/]\n")
69
+
70
+
71
+ def double_confirm(action: str, resource: str) -> None:
72
+ """Require two confirmations for a destructive operation."""
73
+ console.print(f"[bold yellow]⚠️ About to: {action} '{resource}'[/]")
74
+ typer.confirm(f"Confirm 1/2: {action} '{resource}'?", abort=True)
75
+ typer.confirm(
76
+ f"Confirm 2/2: really {action} '{resource}'? This may be irreversible.",
77
+ abort=True,
78
+ )
@@ -0,0 +1,58 @@
1
+ """Top-level Typer app: assembles sub-apps and top-level commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import typer
6
+
7
+ from endpoint_aiops.cli._common import cli_errors
8
+ from endpoint_aiops.cli.doctor import doctor_cmd
9
+ from endpoint_aiops.cli.drift import drift_app
10
+ from endpoint_aiops.cli.endpoint import endpoint_app
11
+ from endpoint_aiops.cli.init import init_cmd
12
+ from endpoint_aiops.cli.overview import overview_cmd
13
+ from endpoint_aiops.cli.secret import secret_app
14
+ from endpoint_aiops.cli.session import session_app
15
+
16
+ app = typer.Typer(
17
+ name="endpoint-aiops",
18
+ help="Governed AI-ops for managed-endpoint fleets (thin clients / VDI).",
19
+ no_args_is_help=True,
20
+ )
21
+
22
+ app.add_typer(endpoint_app, name="endpoint")
23
+ app.add_typer(session_app, name="session")
24
+ app.add_typer(drift_app, name="drift")
25
+ app.add_typer(secret_app, name="secret")
26
+ app.command("init")(init_cmd)
27
+ app.command("overview")(overview_cmd)
28
+ app.command("doctor")(doctor_cmd)
29
+
30
+
31
+ @app.command("mcp")
32
+ @cli_errors
33
+ def mcp_cmd() -> None:
34
+ """Start the MCP server (stdio transport).
35
+
36
+ Single-command entry point for MCP clients (does not go through uvx/PyPI
37
+ resolution at launch):
38
+ endpoint-aiops mcp
39
+ """
40
+ import sys
41
+
42
+ if sys.version_info < (3, 11):
43
+ typer.echo(
44
+ f"ERROR: endpoint-aiops requires Python >= 3.11 "
45
+ f"(got {sys.version_info.major}.{sys.version_info.minor}).\n"
46
+ f"Fix: uv python install 3.12 && "
47
+ f"uv tool install --python 3.12 --force endpoint-aiops",
48
+ err=True,
49
+ )
50
+ raise typer.Exit(2)
51
+
52
+ from mcp_server.server import main as _mcp_main
53
+
54
+ _mcp_main()
55
+
56
+
57
+ if __name__ == "__main__":
58
+ app()
@@ -0,0 +1,21 @@
1
+ """Doctor top-level command: environment and connectivity check."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+
9
+ from endpoint_aiops.cli._common import cli_errors
10
+
11
+
12
+ @cli_errors
13
+ def doctor_cmd(
14
+ skip_auth: Annotated[
15
+ bool, typer.Option("--skip-auth", help="Skip connectivity check (faster)")
16
+ ] = False,
17
+ ) -> None:
18
+ """Check environment, config, secrets, and connectivity."""
19
+ from endpoint_aiops.doctor import run_doctor
20
+
21
+ raise typer.Exit(run_doctor(skip_auth=skip_auth))
@@ -0,0 +1,45 @@
1
+ """``endpoint-aiops drift`` — patch/config drift + patch-level status."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from typing import Annotated
7
+
8
+ import typer
9
+
10
+ from endpoint_aiops.cli._common import TargetOption, cli_errors, console, get_connection
11
+
12
+ drift_app = typer.Typer(
13
+ name="drift",
14
+ help="Fleet drift: config/patch deviation vs a baseline, patch-level status.",
15
+ no_args_is_help=True,
16
+ )
17
+
18
+
19
+ @drift_app.command("report")
20
+ @cli_errors
21
+ def drift_report(target: TargetOption = None) -> None:
22
+ """Report endpoints drifted from the fleet-majority baseline."""
23
+ from endpoint_aiops.ops import drift as ops
24
+ from endpoint_aiops.ops import inventory as inv
25
+
26
+ conn, _ = get_connection(target)
27
+ console.print_json(json.dumps(ops.config_drift(inv.list_endpoints(conn))))
28
+
29
+
30
+ @drift_app.command("patch")
31
+ @cli_errors
32
+ def drift_patch(
33
+ target_patch: Annotated[
34
+ str | None, typer.Option("--target-patch", help="Desired patch level")
35
+ ] = None,
36
+ target: TargetOption = None,
37
+ ) -> None:
38
+ """Patch-level distribution + which endpoints are behind the target."""
39
+ from endpoint_aiops.ops import drift as ops
40
+ from endpoint_aiops.ops import inventory as inv
41
+
42
+ conn, _ = get_connection(target)
43
+ console.print_json(
44
+ json.dumps(ops.patch_status(inv.list_endpoints(conn), target_patch=target_patch))
45
+ )