Skip to content

feat(agent): CSPM AI agent - ReAct loop, 6 tools, CLI, MCP server, security hardening - #397

Open
TFT444 wants to merge 12 commits into
devfrom
feat/355-cspm-ai-agent
Open

TFT444 wants to merge 12 commits into
devfrom
feat/355-cspm-ai-agent

Conversation

@TFT444

@TFT444 TFT444 commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds POST /api/agent/query - a natural-language CSPM Q&A endpoint powered by a ReAct loop over 6 tool functions (get_findings, get_compliance_posture, get_attack_paths, explain_finding, suggest_remediation, scan_subscription)
  • Adds openshield ask CLI command for terminal-based querying
  • Adds an MCP server exposing all 6 tools to Claude Desktop and GitHub Copilot
  • Hardens security: fail-closed tenant guard (empty tenant -> 403), subscription allowlist check on agent route, viewer-role exemption for Q&A POST, rollback safety on all DB tool functions, encoding fixes in tests

Changes by area

api/agent/

  • agent.py - ReAct loop with guardrails (max iterations, prompt injection filter, confidence scoring)
  • tools.py - 6 CSPM tool functions with tenant isolation; added db_conn.rollback() in all except blocks

api/routes/agent.py

  • POST /api/agent/query with rate limiting (20 req/min), JWT auth, fail-closed tenant guard, subscription allowlist check

api/app.py

  • _READ_ACCESSIBLE_POSTS exempts /api/agent/query from the write-role gate so viewer tokens can use Q&A

cli/ - openshield ask command with --subscription-id, --framework, --tenant-id flags

mcp_server.py - MCP server wiring all 6 tools for Claude Desktop / Copilot integration

tests/

  • Full coverage: test_agent_tools, test_agent_loop, test_agent_route, test_cli_ask, test_mcp_server (38 tests)
  • conftest: synthetic tenant injection hook so shared-secret-mode tests pass the tenant guard

Test plan

  • python -m pytest tests/test_agent_tools.py tests/test_agent_loop.py tests/test_agent_route.py tests/test_cli_ask.py tests/test_mcp_server.py -q - 38 passed
  • Tenant with no claim returns 403
  • Viewer role can POST to /api/agent/query (read-only Q&A)
  • Subscription not in allowlist returns 403

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
…ests

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
…equest body

The route was reading g.tenant_id and g.subscription_id which are never set
by verify_jwt. Fixed to read tenant_id from g.user['tenant'] (matches the
principal dict set by auth.py) and subscription_id from the validated
request body, consistent with how scans.py handles it.

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
…nt isolation test

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
…opilot

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
…ty, and role access

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

…ial scan false positive

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
…quirements-dev

Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
Signed-off-by: Tanvir Farhad <tamimtarafder12@gmail.com>
@TFT444 TFT444 self-assigned this Oct 19, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant