agentdiscover 2.9.1__tar.gz → 2.9.2__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 (146) hide show
  1. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/PKG-INFO +1 -1
  2. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/pyproject.toml +1 -1
  3. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/platform.py +9 -6
  4. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_platform_enrichment.py +104 -0
  5. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/uv.lock +1 -1
  6. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/.claude/commands/grow-scanner.md +0 -0
  7. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/.github/workflows/aibom.yml +0 -0
  8. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/.github/workflows/ci.yml +0 -0
  9. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/.github/workflows/scan.yml +0 -0
  10. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/.gitignore +0 -0
  11. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/.python-version +0 -0
  12. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/CHANGELOG.md +0 -0
  13. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/CLAUDE.md +0 -0
  14. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/COMMIT_NOTES.md +0 -0
  15. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/CONTRIBUTING.md +0 -0
  16. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/Dockerfile +0 -0
  17. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/LICENSE +0 -0
  18. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/README.md +0 -0
  19. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/README_BADGES.txt +0 -0
  20. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/RELEASE_NOTES.md +0 -0
  21. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/ROADMAP.md +0 -0
  22. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/SECURITY.md +0 -0
  23. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/action.yml +0 -0
  24. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/k8s/agents-configmap.yaml +0 -0
  25. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/k8s/crewai-agent.yaml +0 -0
  26. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/k8s/langchain-agent.yaml +0 -0
  27. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/k8s/shadow-agent.yaml +0 -0
  28. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/mcp-governance/DESIGN.md +0 -0
  29. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/mcp-governance/README.md +0 -0
  30. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/mcp-governance/sample-policy.yaml +0 -0
  31. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/run-demo.sh +0 -0
  32. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/sample-repo/agents/autogen_agent.py +0 -0
  33. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/sample-repo/agents/crewai_agent.py +0 -0
  34. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/sample-repo/agents/direct_client.py +0 -0
  35. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/sample-repo/agents/langchain_agent.py +0 -0
  36. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/sample-repo/requirements.txt +0 -0
  37. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/demo/setup.sh +0 -0
  38. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/deployment/kubernetes/tracing-policy.yaml +0 -0
  39. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/deployment/systemd/README.md +0 -0
  40. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/deployment/systemd/agent-discover-scanner.service +0 -0
  41. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docker-compose.yml +0 -0
  42. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/EXAMPLES.md +0 -0
  43. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/TETRAGON_SETUP.md +0 -0
  44. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/architecture.svg +0 -0
  45. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/comparisons/vs-grep.md +0 -0
  46. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/comparisons/vs-nudge-security.md +0 -0
  47. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/ghost-detection.svg +0 -0
  48. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/integrations/elastic.md +0 -0
  49. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/integrations/github-actions.md +0 -0
  50. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/integrations/kubernetes-daemonset.md +0 -0
  51. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/integrations/splunk.md +0 -0
  52. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/known-apps-example.txt +0 -0
  53. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/layer4-setup.md +0 -0
  54. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/docs/nist-mapping.md +0 -0
  55. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/examples/k8s/test-workload.yaml +0 -0
  56. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/examples/tetragon-sample-events.json +0 -0
  57. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/install.sh +0 -0
  58. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/__init__.py +0 -0
  59. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/aibom.py +0 -0
  60. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/audit_reports.py +0 -0
  61. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/behavioral_patterns.py +0 -0
  62. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/cli.py +0 -0
  63. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/correlator.py +0 -0
  64. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/__init__.py +0 -0
  65. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/cloud_audit/__init__.py +0 -0
  66. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/cloud_audit/aws_cloudtrail.py +0 -0
  67. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/cloud_audit/azure_monitor.py +0 -0
  68. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/cloud_audit/base.py +0 -0
  69. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/cloud_audit/gcp_audit.py +0 -0
  70. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/cloudtrail.py +0 -0
  71. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/sse_proxy/__init__.py +0 -0
  72. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/sse_proxy/base.py +0 -0
  73. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/sse_proxy/netskope.py +0 -0
  74. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/sse_proxy/prisma_access.py +0 -0
  75. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/detectors/sse_proxy/zscaler_zia.py +0 -0
  76. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/errors.py +0 -0
  77. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/exporters/__init__.py +0 -0
  78. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/exporters/mcpfw_policy.py +0 -0
  79. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/git_scanner.py +0 -0
  80. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/high_risk_agents.py +0 -0
  81. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/__init__.py +0 -0
  82. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/base.py +0 -0
  83. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/sse/__init__.py +0 -0
  84. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/sse/netskope.py +0 -0
  85. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/sse/prisma_access.py +0 -0
  86. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/sse/umbrella.py +0 -0
  87. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/interceptors/sse/zscaler.py +0 -0
  88. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/js_signatures.py +0 -0
  89. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/known_apps.py +0 -0
  90. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/layer4/__init__.py +0 -0
  91. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/layer4/osquery_executor.py +0 -0
  92. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/layer4/osquery_queries.py +0 -0
  93. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/layer4/result_parser.py +0 -0
  94. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/macos_detector.py +0 -0
  95. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/mcp_detector.py +0 -0
  96. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/models/endpoint_discovery.py +0 -0
  97. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/monitors/__init__.py +0 -0
  98. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/monitors/json_output.py +0 -0
  99. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/monitors/k8s_monitor.py +0 -0
  100. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/monitors/tetragon_events.py +0 -0
  101. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/monitors/tetragon_monitor.py +0 -0
  102. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/monitors/vendor_mapping.py +0 -0
  103. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/network_monitor.py +0 -0
  104. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/process_introspection.py +0 -0
  105. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/reports/layer4_report.py +0 -0
  106. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/saas_detector.py +0 -0
  107. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/sarif_output.py +0 -0
  108. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/sbom_analyzer.py +0 -0
  109. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/scan_runner.py +0 -0
  110. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/scanner.py +0 -0
  111. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/signatures.py +0 -0
  112. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/visitor.py +0 -0
  113. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/src/agent_discover_scanner/windows_detector.py +0 -0
  114. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/__init__.py +0 -0
  115. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/autogen_safe.py +0 -0
  116. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/autogen_unsafe.py +0 -0
  117. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/bedrock_safe.py +0 -0
  118. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/bedrock_unsafe.py +0 -0
  119. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/clean_code.py +0 -0
  120. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/crewai_safe.py +0 -0
  121. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/crewai_unsafe.py +0 -0
  122. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/langchain_agents.py +0 -0
  123. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/langchain_js_agent.js +0 -0
  124. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/langgraph_workflow.py +0 -0
  125. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/safe_with_gateway.py +0 -0
  126. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/shadow_anthropic.py +0 -0
  127. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/shadow_openai.py +0 -0
  128. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/fixtures/shadow_openai_js.js +0 -0
  129. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_aibom.py +0 -0
  130. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_audit_bundle.py +0 -0
  131. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_bedrock_signatures.py +0 -0
  132. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_behavioral_patterns.py +0 -0
  133. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_cloud_audit_layer5.py +0 -0
  134. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_cloudtrail.py +0 -0
  135. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_cloudtrail_wiring.py +0 -0
  136. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_correlator.py +0 -0
  137. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_correlator_layer5.py +0 -0
  138. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_forward_dns.py +0 -0
  139. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_git_scanner.py +0 -0
  140. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_install.sh +0 -0
  141. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_interceptors.py +0 -0
  142. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_l2_process_introspection.py +0 -0
  143. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_mcpfw_export.py +0 -0
  144. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_network_monitor.py +0 -0
  145. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_scanner.py +0 -0
  146. {agentdiscover-2.9.1 → agentdiscover-2.9.2}/tests/test_sse_proxy.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentdiscover
3
- Version: 2.9.1
3
+ Version: 2.9.2
4
4
  Summary: Discover every AI agent in your infrastructure. 5-layer detection: static analysis, network monitoring, eBPF/Kubernetes runtime, endpoint, and cloud audit (CloudTrail). Company-level correlation. AIBOM export. MCP server detection.
5
5
  Project-URL: Homepage, https://defendai.ai
6
6
  Project-URL: Documentation, https://github.com/Defend-AI-Tech-Inc/agent-discover-scanner/blob/main/README.md
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agentdiscover"
7
- version = "2.9.1"
7
+ version = "2.9.2"
8
8
  description = "Discover every AI agent in your infrastructure. 5-layer detection: static analysis, network monitoring, eBPF/Kubernetes runtime, endpoint, and cloud audit (CloudTrail). Company-level correlation. AIBOM export. MCP server detection."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -215,14 +215,17 @@ def load_credentials() -> Optional[Dict[str, str]]:
215
215
  tenant_token = data.get("tenant_token") or data.get("tenant-token")
216
216
  wawsdb_url = data.get("wawsdb_url") or data.get("wawsdb-url")
217
217
 
218
- if not (api_key and tenant_token and wawsdb_url):
218
+ # Only api_key is required; tenant_token and wawsdb_url are optional.
219
+ # A config with just api_key (and optionally wawsdb_url) is valid.
220
+ if not api_key:
219
221
  return None
220
222
 
221
- return {
222
- "api_key": str(api_key),
223
- "tenant_token": str(tenant_token),
224
- "wawsdb_url": str(wawsdb_url),
225
- }
223
+ result: dict[str, str] = {"api_key": str(api_key)}
224
+ if tenant_token:
225
+ result["tenant_token"] = str(tenant_token)
226
+ if wawsdb_url:
227
+ result["wawsdb_url"] = str(wawsdb_url)
228
+ return result
226
229
  except Exception:
227
230
  # Never propagate errors from credential loading
228
231
  return None
@@ -7,6 +7,10 @@ Tests for platform.py enrichment functions added in v2.8.0 / v2.9.0:
7
7
  - format_agents_for_upload (L5 enrichment + credential_files_found + L2 enrichment)
8
8
  """
9
9
 
10
+ import json
11
+ import os
12
+ import tempfile
13
+
10
14
  import pytest
11
15
 
12
16
  from agent_discover_scanner.platform import (
@@ -15,6 +19,7 @@ from agent_discover_scanner.platform import (
15
19
  build_cloud_audit_summary,
16
20
  build_network_summary,
17
21
  format_agents_for_upload,
22
+ load_credentials,
18
23
  )
19
24
 
20
25
 
@@ -558,3 +563,102 @@ class TestFormatAgentsL2Enrichment:
558
563
  agent = self._fmt(report)[0]
559
564
  assert "evidence" in agent
560
565
  assert isinstance(agent["evidence"], list)
566
+
567
+
568
+ # ── TestLoadCredentials ──────────────────────────────────────────────────────
569
+
570
+ class TestLoadCredentials:
571
+ """
572
+ load_credentials() unit tests.
573
+
574
+ Verifies that:
575
+ - api_key alone (without tenant_token) is sufficient to return credentials
576
+ - tenant_token and wawsdb_url are optional fields
577
+ - Missing api_key always returns None
578
+ - Malformed / missing config file returns None cleanly
579
+ """
580
+
581
+ def _write_config(self, tmpdir: str, data: dict) -> str:
582
+ path = os.path.join(tmpdir, ".defendai", "config")
583
+ os.makedirs(os.path.dirname(path), exist_ok=True)
584
+ with open(path, "w") as f:
585
+ json.dump(data, f)
586
+ return path
587
+
588
+ def _load(self, config_path: str):
589
+ """Patch the expanduser path and call load_credentials()."""
590
+ import agent_discover_scanner.platform as plat
591
+ original = plat.os.path.expanduser
592
+ plat.os.path.expanduser = lambda p: config_path if "config" in p else original(p)
593
+ try:
594
+ return load_credentials()
595
+ finally:
596
+ plat.os.path.expanduser = original
597
+
598
+ def test_api_key_and_all_fields_returns_full_dict(self):
599
+ with tempfile.TemporaryDirectory() as tmp:
600
+ cfg = self._write_config(tmp, {
601
+ "api_key": "key-abc",
602
+ "tenant_token": "tok-xyz",
603
+ "wawsdb_url": "https://custom.example.com",
604
+ })
605
+ result = self._load(cfg)
606
+ assert result is not None
607
+ assert result["api_key"] == "key-abc"
608
+ assert result["tenant_token"] == "tok-xyz"
609
+ assert result["wawsdb_url"] == "https://custom.example.com"
610
+
611
+ def test_api_key_only_returns_credentials(self):
612
+ """tenant_token absence must NOT prevent credential loading."""
613
+ with tempfile.TemporaryDirectory() as tmp:
614
+ cfg = self._write_config(tmp, {"api_key": "key-abc"})
615
+ result = self._load(cfg)
616
+ assert result is not None
617
+ assert result["api_key"] == "key-abc"
618
+ assert "tenant_token" not in result
619
+
620
+ def test_api_key_and_url_no_tenant_token(self):
621
+ with tempfile.TemporaryDirectory() as tmp:
622
+ cfg = self._write_config(tmp, {
623
+ "api_key": "key-abc",
624
+ "wawsdb_url": "https://custom.example.com",
625
+ })
626
+ result = self._load(cfg)
627
+ assert result is not None
628
+ assert result["api_key"] == "key-abc"
629
+ assert result["wawsdb_url"] == "https://custom.example.com"
630
+ assert "tenant_token" not in result
631
+
632
+ def test_missing_api_key_returns_none(self):
633
+ with tempfile.TemporaryDirectory() as tmp:
634
+ cfg = self._write_config(tmp, {
635
+ "tenant_token": "tok-xyz",
636
+ "wawsdb_url": "https://custom.example.com",
637
+ })
638
+ result = self._load(cfg)
639
+ assert result is None
640
+
641
+ def test_empty_config_returns_none(self):
642
+ with tempfile.TemporaryDirectory() as tmp:
643
+ cfg = self._write_config(tmp, {})
644
+ result = self._load(cfg)
645
+ assert result is None
646
+
647
+ def test_api_key_hyphen_variant_accepted(self):
648
+ """Both api_key and api-key spellings should work."""
649
+ with tempfile.TemporaryDirectory() as tmp:
650
+ cfg = self._write_config(tmp, {"api-key": "key-hyphen"})
651
+ result = self._load(cfg)
652
+ assert result is not None
653
+ assert result["api_key"] == "key-hyphen"
654
+
655
+ def test_missing_config_file_returns_none(self):
656
+ """A path that doesn't exist must return None without raising."""
657
+ import agent_discover_scanner.platform as plat
658
+ original = plat.os.path.expanduser
659
+ plat.os.path.expanduser = lambda p: "/nonexistent/path/config"
660
+ try:
661
+ result = load_credentials()
662
+ finally:
663
+ plat.os.path.expanduser = original
664
+ assert result is None
@@ -4,7 +4,7 @@ requires-python = ">=3.10"
4
4
 
5
5
  [[package]]
6
6
  name = "agentdiscover"
7
- version = "2.9.0"
7
+ version = "2.9.2"
8
8
  source = { editable = "." }
9
9
  dependencies = [
10
10
  { name = "certifi" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes