atlas-chat 0.1.0__py3-none-any.whl

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 (250) hide show
  1. atlas/__init__.py +40 -0
  2. atlas/application/__init__.py +7 -0
  3. atlas/application/chat/__init__.py +7 -0
  4. atlas/application/chat/agent/__init__.py +10 -0
  5. atlas/application/chat/agent/act_loop.py +179 -0
  6. atlas/application/chat/agent/factory.py +142 -0
  7. atlas/application/chat/agent/protocols.py +46 -0
  8. atlas/application/chat/agent/react_loop.py +338 -0
  9. atlas/application/chat/agent/think_act_loop.py +171 -0
  10. atlas/application/chat/approval_manager.py +151 -0
  11. atlas/application/chat/elicitation_manager.py +191 -0
  12. atlas/application/chat/events/__init__.py +1 -0
  13. atlas/application/chat/events/agent_event_relay.py +112 -0
  14. atlas/application/chat/modes/__init__.py +1 -0
  15. atlas/application/chat/modes/agent.py +125 -0
  16. atlas/application/chat/modes/plain.py +74 -0
  17. atlas/application/chat/modes/rag.py +81 -0
  18. atlas/application/chat/modes/tools.py +179 -0
  19. atlas/application/chat/orchestrator.py +213 -0
  20. atlas/application/chat/policies/__init__.py +1 -0
  21. atlas/application/chat/policies/tool_authorization.py +99 -0
  22. atlas/application/chat/preprocessors/__init__.py +1 -0
  23. atlas/application/chat/preprocessors/message_builder.py +92 -0
  24. atlas/application/chat/preprocessors/prompt_override_service.py +104 -0
  25. atlas/application/chat/service.py +454 -0
  26. atlas/application/chat/utilities/__init__.py +6 -0
  27. atlas/application/chat/utilities/error_handler.py +367 -0
  28. atlas/application/chat/utilities/event_notifier.py +546 -0
  29. atlas/application/chat/utilities/file_processor.py +613 -0
  30. atlas/application/chat/utilities/tool_executor.py +789 -0
  31. atlas/atlas_chat_cli.py +347 -0
  32. atlas/atlas_client.py +238 -0
  33. atlas/core/__init__.py +0 -0
  34. atlas/core/auth.py +205 -0
  35. atlas/core/authorization_manager.py +27 -0
  36. atlas/core/capabilities.py +123 -0
  37. atlas/core/compliance.py +215 -0
  38. atlas/core/domain_whitelist.py +147 -0
  39. atlas/core/domain_whitelist_middleware.py +82 -0
  40. atlas/core/http_client.py +28 -0
  41. atlas/core/log_sanitizer.py +102 -0
  42. atlas/core/metrics_logger.py +59 -0
  43. atlas/core/middleware.py +131 -0
  44. atlas/core/otel_config.py +242 -0
  45. atlas/core/prompt_risk.py +200 -0
  46. atlas/core/rate_limit.py +0 -0
  47. atlas/core/rate_limit_middleware.py +64 -0
  48. atlas/core/security_headers_middleware.py +51 -0
  49. atlas/domain/__init__.py +37 -0
  50. atlas/domain/chat/__init__.py +1 -0
  51. atlas/domain/chat/dtos.py +85 -0
  52. atlas/domain/errors.py +96 -0
  53. atlas/domain/messages/__init__.py +12 -0
  54. atlas/domain/messages/models.py +160 -0
  55. atlas/domain/rag_mcp_service.py +664 -0
  56. atlas/domain/sessions/__init__.py +7 -0
  57. atlas/domain/sessions/models.py +36 -0
  58. atlas/domain/unified_rag_service.py +371 -0
  59. atlas/infrastructure/__init__.py +10 -0
  60. atlas/infrastructure/app_factory.py +135 -0
  61. atlas/infrastructure/events/__init__.py +1 -0
  62. atlas/infrastructure/events/cli_event_publisher.py +140 -0
  63. atlas/infrastructure/events/websocket_publisher.py +140 -0
  64. atlas/infrastructure/sessions/in_memory_repository.py +56 -0
  65. atlas/infrastructure/transport/__init__.py +7 -0
  66. atlas/infrastructure/transport/websocket_connection_adapter.py +33 -0
  67. atlas/init_cli.py +226 -0
  68. atlas/interfaces/__init__.py +15 -0
  69. atlas/interfaces/events.py +134 -0
  70. atlas/interfaces/llm.py +54 -0
  71. atlas/interfaces/rag.py +40 -0
  72. atlas/interfaces/sessions.py +75 -0
  73. atlas/interfaces/tools.py +57 -0
  74. atlas/interfaces/transport.py +24 -0
  75. atlas/main.py +564 -0
  76. atlas/mcp/api_key_demo/README.md +76 -0
  77. atlas/mcp/api_key_demo/main.py +172 -0
  78. atlas/mcp/api_key_demo/run.sh +56 -0
  79. atlas/mcp/basictable/main.py +147 -0
  80. atlas/mcp/calculator/main.py +149 -0
  81. atlas/mcp/code-executor/execution_engine.py +98 -0
  82. atlas/mcp/code-executor/execution_environment.py +95 -0
  83. atlas/mcp/code-executor/main.py +528 -0
  84. atlas/mcp/code-executor/result_processing.py +276 -0
  85. atlas/mcp/code-executor/script_generation.py +195 -0
  86. atlas/mcp/code-executor/security_checker.py +140 -0
  87. atlas/mcp/corporate_cars/main.py +437 -0
  88. atlas/mcp/csv_reporter/main.py +545 -0
  89. atlas/mcp/duckduckgo/main.py +182 -0
  90. atlas/mcp/elicitation_demo/README.md +171 -0
  91. atlas/mcp/elicitation_demo/main.py +262 -0
  92. atlas/mcp/env-demo/README.md +158 -0
  93. atlas/mcp/env-demo/main.py +199 -0
  94. atlas/mcp/file_size_test/main.py +284 -0
  95. atlas/mcp/filesystem/main.py +348 -0
  96. atlas/mcp/image_demo/main.py +113 -0
  97. atlas/mcp/image_demo/requirements.txt +4 -0
  98. atlas/mcp/logging_demo/README.md +72 -0
  99. atlas/mcp/logging_demo/main.py +103 -0
  100. atlas/mcp/many_tools_demo/main.py +50 -0
  101. atlas/mcp/order_database/__init__.py +0 -0
  102. atlas/mcp/order_database/main.py +369 -0
  103. atlas/mcp/order_database/signal_data.csv +1001 -0
  104. atlas/mcp/pdfbasic/main.py +394 -0
  105. atlas/mcp/pptx_generator/main.py +760 -0
  106. atlas/mcp/pptx_generator/requirements.txt +13 -0
  107. atlas/mcp/pptx_generator/run_test.sh +1 -0
  108. atlas/mcp/pptx_generator/test_pptx_generator_security.py +169 -0
  109. atlas/mcp/progress_demo/main.py +167 -0
  110. atlas/mcp/progress_updates_demo/QUICKSTART.md +273 -0
  111. atlas/mcp/progress_updates_demo/README.md +120 -0
  112. atlas/mcp/progress_updates_demo/main.py +497 -0
  113. atlas/mcp/prompts/main.py +222 -0
  114. atlas/mcp/public_demo/main.py +189 -0
  115. atlas/mcp/sampling_demo/README.md +169 -0
  116. atlas/mcp/sampling_demo/main.py +234 -0
  117. atlas/mcp/thinking/main.py +77 -0
  118. atlas/mcp/tool_planner/main.py +240 -0
  119. atlas/mcp/ui-demo/badmesh.png +0 -0
  120. atlas/mcp/ui-demo/main.py +383 -0
  121. atlas/mcp/ui-demo/templates/button_demo.html +32 -0
  122. atlas/mcp/ui-demo/templates/data_visualization.html +32 -0
  123. atlas/mcp/ui-demo/templates/form_demo.html +28 -0
  124. atlas/mcp/username-override-demo/README.md +320 -0
  125. atlas/mcp/username-override-demo/main.py +308 -0
  126. atlas/modules/__init__.py +0 -0
  127. atlas/modules/config/__init__.py +34 -0
  128. atlas/modules/config/cli.py +231 -0
  129. atlas/modules/config/config_manager.py +1096 -0
  130. atlas/modules/file_storage/__init__.py +22 -0
  131. atlas/modules/file_storage/cli.py +330 -0
  132. atlas/modules/file_storage/content_extractor.py +290 -0
  133. atlas/modules/file_storage/manager.py +295 -0
  134. atlas/modules/file_storage/mock_s3_client.py +402 -0
  135. atlas/modules/file_storage/s3_client.py +417 -0
  136. atlas/modules/llm/__init__.py +19 -0
  137. atlas/modules/llm/caller.py +287 -0
  138. atlas/modules/llm/litellm_caller.py +675 -0
  139. atlas/modules/llm/models.py +19 -0
  140. atlas/modules/mcp_tools/__init__.py +17 -0
  141. atlas/modules/mcp_tools/client.py +2123 -0
  142. atlas/modules/mcp_tools/token_storage.py +556 -0
  143. atlas/modules/prompts/prompt_provider.py +130 -0
  144. atlas/modules/rag/__init__.py +24 -0
  145. atlas/modules/rag/atlas_rag_client.py +336 -0
  146. atlas/modules/rag/client.py +129 -0
  147. atlas/routes/admin_routes.py +865 -0
  148. atlas/routes/config_routes.py +484 -0
  149. atlas/routes/feedback_routes.py +361 -0
  150. atlas/routes/files_routes.py +274 -0
  151. atlas/routes/health_routes.py +40 -0
  152. atlas/routes/mcp_auth_routes.py +223 -0
  153. atlas/server_cli.py +164 -0
  154. atlas/tests/conftest.py +20 -0
  155. atlas/tests/integration/test_mcp_auth_integration.py +152 -0
  156. atlas/tests/manual_test_sampling.py +87 -0
  157. atlas/tests/modules/mcp_tools/test_client_auth.py +226 -0
  158. atlas/tests/modules/mcp_tools/test_client_env.py +191 -0
  159. atlas/tests/test_admin_mcp_server_management_routes.py +141 -0
  160. atlas/tests/test_agent_roa.py +135 -0
  161. atlas/tests/test_app_factory_smoke.py +47 -0
  162. atlas/tests/test_approval_manager.py +439 -0
  163. atlas/tests/test_atlas_client.py +188 -0
  164. atlas/tests/test_atlas_rag_client.py +447 -0
  165. atlas/tests/test_atlas_rag_integration.py +224 -0
  166. atlas/tests/test_attach_file_flow.py +287 -0
  167. atlas/tests/test_auth_utils.py +165 -0
  168. atlas/tests/test_backend_public_url.py +185 -0
  169. atlas/tests/test_banner_logging.py +287 -0
  170. atlas/tests/test_capability_tokens_and_injection.py +203 -0
  171. atlas/tests/test_compliance_level.py +54 -0
  172. atlas/tests/test_compliance_manager.py +253 -0
  173. atlas/tests/test_config_manager.py +617 -0
  174. atlas/tests/test_config_manager_paths.py +12 -0
  175. atlas/tests/test_core_auth.py +18 -0
  176. atlas/tests/test_core_utils.py +190 -0
  177. atlas/tests/test_docker_env_sync.py +202 -0
  178. atlas/tests/test_domain_errors.py +329 -0
  179. atlas/tests/test_domain_whitelist.py +359 -0
  180. atlas/tests/test_elicitation_manager.py +408 -0
  181. atlas/tests/test_elicitation_routing.py +296 -0
  182. atlas/tests/test_env_demo_server.py +88 -0
  183. atlas/tests/test_error_classification.py +113 -0
  184. atlas/tests/test_error_flow_integration.py +116 -0
  185. atlas/tests/test_feedback_routes.py +333 -0
  186. atlas/tests/test_file_content_extraction.py +1134 -0
  187. atlas/tests/test_file_extraction_routes.py +158 -0
  188. atlas/tests/test_file_library.py +107 -0
  189. atlas/tests/test_file_manager_unit.py +18 -0
  190. atlas/tests/test_health_route.py +49 -0
  191. atlas/tests/test_http_client_stub.py +8 -0
  192. atlas/tests/test_imports_smoke.py +30 -0
  193. atlas/tests/test_interfaces_llm_response.py +9 -0
  194. atlas/tests/test_issue_access_denied_fix.py +136 -0
  195. atlas/tests/test_llm_env_expansion.py +836 -0
  196. atlas/tests/test_log_level_sensitive_data.py +285 -0
  197. atlas/tests/test_mcp_auth_routes.py +341 -0
  198. atlas/tests/test_mcp_client_auth.py +331 -0
  199. atlas/tests/test_mcp_data_injection.py +270 -0
  200. atlas/tests/test_mcp_get_authorized_servers.py +95 -0
  201. atlas/tests/test_mcp_hot_reload.py +512 -0
  202. atlas/tests/test_mcp_image_content.py +424 -0
  203. atlas/tests/test_mcp_logging.py +172 -0
  204. atlas/tests/test_mcp_progress_updates.py +313 -0
  205. atlas/tests/test_mcp_prompt_override_system_prompt.py +102 -0
  206. atlas/tests/test_mcp_prompts_server.py +39 -0
  207. atlas/tests/test_mcp_tool_result_parsing.py +296 -0
  208. atlas/tests/test_metrics_logger.py +56 -0
  209. atlas/tests/test_middleware_auth.py +379 -0
  210. atlas/tests/test_prompt_risk_and_acl.py +141 -0
  211. atlas/tests/test_rag_mcp_aggregator.py +204 -0
  212. atlas/tests/test_rag_mcp_service.py +224 -0
  213. atlas/tests/test_rate_limit_middleware.py +45 -0
  214. atlas/tests/test_routes_config_smoke.py +60 -0
  215. atlas/tests/test_routes_files_download_token.py +41 -0
  216. atlas/tests/test_routes_files_health.py +18 -0
  217. atlas/tests/test_runtime_imports.py +53 -0
  218. atlas/tests/test_sampling_integration.py +482 -0
  219. atlas/tests/test_security_admin_routes.py +61 -0
  220. atlas/tests/test_security_capability_tokens.py +65 -0
  221. atlas/tests/test_security_file_stats_scope.py +21 -0
  222. atlas/tests/test_security_header_injection.py +191 -0
  223. atlas/tests/test_security_headers_and_filename.py +63 -0
  224. atlas/tests/test_shared_session_repository.py +101 -0
  225. atlas/tests/test_system_prompt_loading.py +181 -0
  226. atlas/tests/test_token_storage.py +505 -0
  227. atlas/tests/test_tool_approval_config.py +93 -0
  228. atlas/tests/test_tool_approval_utils.py +356 -0
  229. atlas/tests/test_tool_authorization_group_filtering.py +223 -0
  230. atlas/tests/test_tool_details_in_config.py +108 -0
  231. atlas/tests/test_tool_planner.py +300 -0
  232. atlas/tests/test_unified_rag_service.py +398 -0
  233. atlas/tests/test_username_override_in_approval.py +258 -0
  234. atlas/tests/test_websocket_auth_header.py +168 -0
  235. atlas/version.py +6 -0
  236. atlas_chat-0.1.0.data/data/.env.example +253 -0
  237. atlas_chat-0.1.0.data/data/config/defaults/compliance-levels.json +44 -0
  238. atlas_chat-0.1.0.data/data/config/defaults/domain-whitelist.json +123 -0
  239. atlas_chat-0.1.0.data/data/config/defaults/file-extractors.json +74 -0
  240. atlas_chat-0.1.0.data/data/config/defaults/help-config.json +198 -0
  241. atlas_chat-0.1.0.data/data/config/defaults/llmconfig-buggy.yml +11 -0
  242. atlas_chat-0.1.0.data/data/config/defaults/llmconfig.yml +19 -0
  243. atlas_chat-0.1.0.data/data/config/defaults/mcp.json +138 -0
  244. atlas_chat-0.1.0.data/data/config/defaults/rag-sources.json +17 -0
  245. atlas_chat-0.1.0.data/data/config/defaults/splash-config.json +16 -0
  246. atlas_chat-0.1.0.dist-info/METADATA +236 -0
  247. atlas_chat-0.1.0.dist-info/RECORD +250 -0
  248. atlas_chat-0.1.0.dist-info/WHEEL +5 -0
  249. atlas_chat-0.1.0.dist-info/entry_points.txt +4 -0
  250. atlas_chat-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,168 @@
1
+ """
2
+ Tests for WebSocket authentication using the configured authentication header.
3
+
4
+ These tests validate that the backend correctly extracts the user email from the
5
+ configured authentication header (default: X-User-Email) for WebSocket connections,
6
+ which is critical for the production authentication flow where the reverse proxy
7
+ sets this header. The tests also ensure that fallback mechanisms (query parameter,
8
+ test user from config) work as expected, and that the header takes precedence when
9
+ both are present.
10
+ """
11
+
12
+ from unittest.mock import AsyncMock, MagicMock, patch
13
+
14
+ import pytest
15
+ from fastapi.testclient import TestClient
16
+ from main import app
17
+
18
+
19
+ @pytest.fixture
20
+ def mock_app_factory():
21
+ """Mock app factory to avoid initializing full application."""
22
+ with patch('main.app_factory') as mock_factory:
23
+ # Mock config manager
24
+ mock_config = MagicMock()
25
+ mock_config.app_settings.test_user = 'test@test.com'
26
+ mock_config.app_settings.debug_mode = False
27
+ mock_config.app_settings.auth_user_header = 'X-User-Email'
28
+ mock_config.app_settings.feature_proxy_secret_enabled = False
29
+ mock_factory.get_config_manager.return_value = mock_config
30
+
31
+ # Mock chat service
32
+ mock_chat_service = MagicMock()
33
+ mock_chat_service.handle_chat_message = AsyncMock(return_value={})
34
+ mock_chat_service.handle_attach_file = AsyncMock(return_value={'type': 'file_attach', 'success': True})
35
+ mock_chat_service.end_session = MagicMock()
36
+ mock_factory.create_chat_service.return_value = mock_chat_service
37
+
38
+ yield mock_factory
39
+
40
+
41
+ def test_websocket_uses_x_user_email_header(mock_app_factory):
42
+ """Test that WebSocket connection uses X-User-Email header for authentication."""
43
+ client = TestClient(app)
44
+
45
+ # Connect with X-User-Email header
46
+ with client.websocket_connect("/ws", headers={"X-User-Email": "alice@example.com"}) as websocket:
47
+ # Send a test message
48
+ websocket.send_json({"type": "attach_file", "s3_key": "users/alice@example.com/test.txt"})
49
+
50
+ # Verify that the connection was created with the correct user from header
51
+ # The user_email should be extracted from X-User-Email header
52
+ call_args = mock_app_factory.create_chat_service.call_args
53
+ connection_adapter = call_args[0][0] # First positional argument
54
+
55
+ # The connection adapter should have been created with alice@example.com
56
+ assert connection_adapter.user_email == "alice@example.com"
57
+
58
+
59
+ def test_websocket_rejects_unauthenticated_in_production(mock_app_factory):
60
+ """Test that WebSocket rejects connections without auth header in production mode."""
61
+ from starlette.websockets import WebSocketDisconnect
62
+
63
+ # Ensure debug_mode is False (production)
64
+ mock_app_factory.get_config_manager.return_value.app_settings.debug_mode = False
65
+
66
+ client = TestClient(app)
67
+
68
+ # Connect without header - should be rejected with 1008 (Policy Violation)
69
+ with pytest.raises(WebSocketDisconnect) as exc_info:
70
+ with client.websocket_connect("/ws"):
71
+ pass
72
+
73
+ assert exc_info.value.code == 1008
74
+ assert "Authentication required" in exc_info.value.reason
75
+
76
+
77
+ def test_websocket_rejects_query_param_in_production(mock_app_factory):
78
+ """Test that WebSocket ignores query param auth in production mode."""
79
+ from starlette.websockets import WebSocketDisconnect
80
+
81
+ # Ensure debug_mode is False (production)
82
+ mock_app_factory.get_config_manager.return_value.app_settings.debug_mode = False
83
+
84
+ client = TestClient(app)
85
+
86
+ # Connect with query param but no header - should be rejected in production
87
+ with pytest.raises(WebSocketDisconnect) as exc_info:
88
+ with client.websocket_connect("/ws?user=bob@example.com"):
89
+ pass
90
+
91
+ assert exc_info.value.code == 1008
92
+ assert "Authentication required" in exc_info.value.reason
93
+
94
+
95
+ @pytest.fixture
96
+ def mock_app_factory_debug_mode():
97
+ """Mock app factory with debug mode enabled."""
98
+ with patch('main.app_factory') as mock_factory:
99
+ # Mock config manager with debug_mode=True
100
+ mock_config = MagicMock()
101
+ mock_config.app_settings.test_user = 'test@test.com'
102
+ mock_config.app_settings.debug_mode = True # Debug mode enabled
103
+ mock_config.app_settings.auth_user_header = 'X-User-Email'
104
+ mock_config.app_settings.feature_proxy_secret_enabled = False
105
+ mock_factory.get_config_manager.return_value = mock_config
106
+
107
+ # Mock chat service
108
+ mock_chat_service = MagicMock()
109
+ mock_chat_service.handle_chat_message = AsyncMock(return_value={})
110
+ mock_chat_service.handle_attach_file = AsyncMock(return_value={'type': 'file_attach', 'success': True})
111
+ mock_chat_service.end_session = MagicMock()
112
+ mock_factory.create_chat_service.return_value = mock_chat_service
113
+
114
+ yield mock_factory
115
+
116
+
117
+ def test_websocket_fallback_to_query_param_debug_mode(mock_app_factory_debug_mode):
118
+ """Test that WebSocket falls back to query param in debug mode only."""
119
+ client = TestClient(app)
120
+
121
+ # Connect without header but with query param - should work in debug mode
122
+ with client.websocket_connect("/ws?user=bob@example.com") as websocket:
123
+ # Send a test message
124
+ websocket.send_json({"type": "attach_file", "s3_key": "users/bob@example.com/test.txt"})
125
+
126
+ # Get the chat service instance
127
+ call_args = mock_app_factory_debug_mode.create_chat_service.call_args
128
+ connection_adapter = call_args[0][0]
129
+
130
+ # Should use query param in debug mode
131
+ assert connection_adapter.user_email == "bob@example.com"
132
+
133
+
134
+ def test_websocket_fallback_to_test_user_debug_mode(mock_app_factory_debug_mode):
135
+ """Test that WebSocket falls back to test user in debug mode only."""
136
+ client = TestClient(app)
137
+
138
+ # Connect without header or query param - should work in debug mode
139
+ with client.websocket_connect("/ws") as websocket:
140
+ # Send a test message
141
+ websocket.send_json({"type": "attach_file", "s3_key": "users/test@test.com/test.txt"})
142
+
143
+ # Get the chat service instance
144
+ call_args = mock_app_factory_debug_mode.create_chat_service.call_args
145
+ connection_adapter = call_args[0][0]
146
+
147
+ # Should use test user from config in debug mode
148
+ assert connection_adapter.user_email == "test@test.com"
149
+
150
+
151
+ def test_websocket_header_takes_precedence_over_query_param(mock_app_factory):
152
+ """Test that X-User-Email header takes precedence over query parameter."""
153
+ client = TestClient(app)
154
+
155
+ # Connect with both header and query param (header should win)
156
+ with client.websocket_connect(
157
+ "/ws?user=wrong@example.com",
158
+ headers={"X-User-Email": "correct@example.com"}
159
+ ) as websocket:
160
+ # Send a test message
161
+ websocket.send_json({"type": "attach_file", "s3_key": "users/correct@example.com/test.txt"})
162
+
163
+ # Get the chat service instance
164
+ call_args = mock_app_factory.create_chat_service.call_args
165
+ connection_adapter = call_args[0][0]
166
+
167
+ # Should use header, not query param
168
+ assert connection_adapter.user_email == "correct@example.com"
atlas/version.py ADDED
@@ -0,0 +1,6 @@
1
+ """Application version constant.
2
+
3
+ Single source of truth for the application version number.
4
+ """
5
+
6
+ VERSION = "0.1.0"
@@ -0,0 +1,253 @@
1
+ #############################################
2
+ # Core / Development
3
+ #############################################
4
+ # Development mode - skip authentication when true
5
+ DEBUG_MODE=true
6
+
7
+ #############################################
8
+ # RAG Configuration
9
+ # Enable RAG (Retrieval-Augmented Generation) feature
10
+ # Configure RAG sources in config/overrides/rag-sources.json
11
+ # See docs/admin/external-rag-api.md for configuration details
12
+ #############################################
13
+ FEATURE_RAG_ENABLED=false
14
+
15
+ # RAG source secrets (referenced in rag-sources.json via ${ENV_VAR} syntax)
16
+ # ATLAS_RAG_URL=https://your-atlas-rag-api.example.com
17
+ # ATLAS_RAG_BEARER_TOKEN=your-api-key-here
18
+
19
+ # Server configuration
20
+ PORT=8000
21
+ APP_NAME=ATLAS
22
+
23
+ # Network binding configuration
24
+ # ATLAS_HOST controls which network interface the server binds to
25
+ # Default: 127.0.0.1 (localhost only, secure)
26
+ # Set to 0.0.0.0 for production deployments that need external access
27
+ # ATLAS_HOST=127.0.0.1
28
+
29
+ # Authentication configuration
30
+ # Header name to extract authenticated username from reverse proxy
31
+ # Different reverse proxy setups use different header names (e.g., X-User-Email, X-Authenticated-User, X-Remote-User)
32
+ # Default: X-User-Email
33
+ # AUTH_USER_HEADER=X-User-Email
34
+
35
+ # Proxy secret authentication (optional security layer)
36
+ # When enabled, the reverse proxy must include a secret header to authenticate itself
37
+ # This ensures the application only accepts requests from the trusted reverse proxy
38
+ # FEATURE_PROXY_SECRET_ENABLED=false
39
+ # PROXY_SECRET_HEADER=X-Proxy-Secret
40
+ # PROXY_SECRET=your-secure-random-secret-here
41
+ # AUTH_REDIRECT_URL=/a
42
+ # API Keys for LLM services
43
+ OPENAI_API_KEY=sk-pro
44
+ ANTHROPIC_API_KEY=your_anthropic_api_key_here
45
+ GOOGLE_API_KEY=your_google_api_key_here
46
+ OPENROUTER_API_KEY=sk-or
47
+ CEREBRAS_API_KEY=your_cerebras_api_key_here
48
+ GROQ_API_KEY=your-groq_api_key_here
49
+
50
+
51
+ # Banner system configuration
52
+ BANNER_ENABLED=true
53
+
54
+
55
+ # Example .env configuration for OpenTelemetry logging
56
+
57
+ # Environment mode (development or production)
58
+ ENVIRONMENT=development
59
+
60
+ #############################################
61
+ # UI / Frontend
62
+ #############################################
63
+
64
+ # Frontend build-time app name (Vite will inject this into index.html)
65
+ VITE_APP_NAME=ATLAS
66
+
67
+ # Frontend build-time flag to show the "Powered By Sandia ATLAS" badge
68
+ # on the welcome screen. Other deployments can set this to false
69
+ # to hide the badge while still customizing the main logo.
70
+ VITE_FEATURE_POWERED_BY_ATLAS=false
71
+
72
+ # OpenTelemetry configuration (optional - for future use)
73
+ # OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
74
+ # OTEL_SERVICE_NAME=atlas-ui-3-backend
75
+ # OTEL_SERVICE_VERSION=1.0.0
76
+
77
+ # Log level configuration (DEBUG, INFO, WARNING, ERROR, CRITICAL)
78
+ # Controls verbosity of application logs and sensitive data logging
79
+ # - DEBUG: Verbose logging including user input/output content (for development/testing only)
80
+ # - INFO: Standard logging with metrics and counts, but no sensitive content (recommended for production)
81
+ # - WARNING/ERROR/CRITICAL: Minimal logging, errors and warnings only
82
+ LOG_LEVEL=INFO
83
+
84
+ # Metrics logging configuration
85
+ # Enable tracking of user activities without capturing sensitive data
86
+ # When enabled, logs contain only metadata (counts, sizes, types)
87
+ # Excludes prompts, tool arguments, file names, and error details
88
+ FEATURE_METRICS_LOGGING_ENABLED=false
89
+
90
+ # Suppress LiteLLM verbose logging (independent of LOG_LEVEL)
91
+ # When true, sets LITELLM_LOG=ERROR to silence LiteLLM's noisy stdout/debug output
92
+ # When false, LiteLLM uses its default logging behavior
93
+ FEATURE_SUPPRESS_LITELLM_LOGGING=true
94
+
95
+ USE_NEW_FRONTEND=true
96
+
97
+ #############################################
98
+ # Feature Flags (rollout controls)
99
+ # Toggle advanced capabilities without changing code.
100
+ # Set to true to enable in UI + API; false hides & suppresses data.
101
+ # These are initialized to reflect your current enabled features.
102
+ #############################################
103
+ # Workspace selector (none configured yet)
104
+ FEATURE_WORKSPACES_ENABLED=false
105
+ # Note: RAG is controlled by RAG_PROVIDER setting (see above)
106
+ # MCP / tools panel
107
+ FEATURE_TOOLS_ENABLED=true
108
+ # Marketplace browsing (disabled)
109
+ FEATURE_MARKETPLACE_ENABLED=true
110
+ # Uploaded/session files panel
111
+ FEATURE_FILES_PANEL_ENABLED=true
112
+ # Previous chat history list
113
+ FEATURE_CHAT_HISTORY_ENABLED=false
114
+ # Compliance level filtering for MCP servers and data sources
115
+ FEATURE_COMPLIANCE_LEVELS_ENABLED=false
116
+ # Startup splash screen for displaying policies and information
117
+ FEATURE_SPLASH_SCREEN_ENABLED=false
118
+ # Restrict access to whitelisted email domains (config/defaults/domain-whitelist.json)
119
+ FEATURE_DOMAIN_WHITELIST_ENABLED=false
120
+ # Enable automatic reconnection to failed MCP servers with exponential backoff
121
+ FEATURE_MCP_AUTO_RECONNECT_ENABLED=false
122
+ # Enable automatic file content extraction for uploaded PDFs/images
123
+ # Requires running the file extractor mock service: python mocks/file-extractor-mock/main.py
124
+ FEATURE_FILE_CONTENT_EXTRACTION_ENABLED=false
125
+
126
+ #############################################
127
+ # File Content Extraction Service Configuration
128
+ # These are optional - only needed when using external extraction services
129
+ # The mock extractor service works without these credentials
130
+ #############################################
131
+ # PDF extractor service credentials (optional for mock service)
132
+ # PDF_EXTRACTOR_API_KEY=your_pdf_extractor_api_key_here
133
+ # PDF_EXTRACTOR_CLIENT_ID=your_pdf_extractor_client_id_here
134
+ # Image vision extractor service credentials (optional for mock service)
135
+ # IMAGE_EXTRACTOR_API_KEY=your_image_extractor_api_key_here
136
+ # OCR extractor service credentials (optional for mock service)
137
+ # OCR_EXTRACTOR_API_KEY=your_ocr_extractor_api_key_here
138
+
139
+ # (Adjust above to stage rollouts. For a bare-bones chat set them all to false.)
140
+
141
+ #############################################
142
+ # MCP Auto-Reconnect Settings
143
+ # These settings control the automatic reconnection behavior for failed MCP servers.
144
+ # Only active when FEATURE_MCP_AUTO_RECONNECT_ENABLED=true
145
+ #############################################
146
+ # Base interval in seconds between reconnect attempts (default: 60)
147
+ # MCP_RECONNECT_INTERVAL=60
148
+ # Maximum interval in seconds (caps exponential backoff, default: 300)
149
+ # MCP_RECONNECT_MAX_INTERVAL=300
150
+ # Multiplier for exponential backoff (default: 2.0)
151
+ # MCP_RECONNECT_BACKOFF_MULTIPLIER=2.0
152
+
153
+ #############################################
154
+ # MCP Timeouts
155
+ # Timeout in seconds for MCP discovery calls - list_tools, list_prompts (default: 30)
156
+ MCP_DISCOVERY_TIMEOUT=30
157
+ # Timeout in seconds for MCP tool calls (default: 120)
158
+ MCP_CALL_TIMEOUT=120
159
+ #############################################
160
+
161
+ #############################################
162
+ # MCP Per-User Token Storage
163
+ # Encryption key for storing user API keys/tokens for MCP servers
164
+ # If not set, an ephemeral key is generated and tokens won't persist across restarts
165
+ #############################################
166
+ # MCP_TOKEN_ENCRYPTION_KEY=your-random-string-at-least-32-chars
167
+ # Directory to store encrypted tokens (default: config/secure/)
168
+ # MCP_TOKEN_STORAGE_DIR=config/secure
169
+
170
+ #############################################
171
+ # Configuration File Names
172
+ # Override the default names for configuration files.
173
+ # Useful for testing or managing multiple configurations.
174
+ #############################################
175
+ # Splash screen configuration file name
176
+ # SPLASH_CONFIG_FILE=splash-config.json
177
+ # MCP servers configuration file name
178
+ # MCP_CONFIG_FILE=mcp.json
179
+ # LLM models configuration file name
180
+ # LLM_CONFIG_FILE=llmconfig.yml
181
+ # Help page configuration file name
182
+ # HELP_CONFIG_FILE=help-config.json
183
+
184
+
185
+ # ths might be need for mcp serves to know where to download the files.
186
+ # CHATUI_BACKEND_BASE_URL=http://127.0.0.1:8000
187
+
188
+ #############################################
189
+ # File Access for Remote MCP Servers
190
+ #############################################
191
+ # Public URL of the backend API for file downloads by remote MCP servers
192
+ # This should be the publicly accessible URL (including protocol and port if non-standard)
193
+ # Examples:
194
+ # - Production: https://atlas-ui.example.com
195
+ # - Development: http://localhost:8000
196
+ # - With non-standard port: https://atlas-ui.example.com:8443
197
+ # If not set, relative URLs will be used (only works for local/stdio servers on the same machine)
198
+ # BACKEND_PUBLIC_URL=https://atlas-ui.example.com
199
+
200
+ # Whether to include base64 encoded file content as fallback in tool arguments
201
+ # This allows MCP servers to access files even if they cannot reach the backend URL
202
+ # WARNING: Enabling this can significantly increase message sizes for large files
203
+ # Default: false (recommended - use URL-based access instead)
204
+ # INCLUDE_FILE_CONTENT_BASE64=false
205
+
206
+
207
+ # Agent mode configuration
208
+ AGENT_MAX_STEPS=30
209
+ AGENT_DEFAULT_ENABLED=true
210
+ # Agent mode availability (renamed to align with other FEATURE_* flags)
211
+ FEATURE_AGENT_MODE_AVAILABLE=true
212
+ # Agent loop strategy: react (structured reasoning) or think-act (faster, concise)
213
+ AGENT_LOOP_STRATEGY=think-act
214
+
215
+ # Tool approval configuration
216
+ # Require approval by default for all tools (can be overridden per-tool in mcp.json)
217
+ REQUIRE_TOOL_APPROVAL_BY_DEFAULT=false
218
+ # Force approval for all tools (admin-enforced) regardless of per-tool or default settings
219
+ # Set to true to require approval for every tool call
220
+ FORCE_TOOL_APPROVAL_GLOBALLY=false
221
+
222
+ # APP_LOG_DIR defaults to <project_root>/logs when unset
223
+ # APP_LOG_DIR=/path/to/logs
224
+
225
+ CAPABILITY_TOKEN_SECRET=blablah
226
+
227
+ #############################################
228
+ # S3/MinIO Storage Configuration
229
+ #############################################
230
+ # Choose ONE option below (comment out the other)
231
+
232
+ # --- Option 1: Mock S3 (Default - No Docker required) ---
233
+ USE_MOCK_S3=true
234
+
235
+ # --- Option 2: MinIO (Requires Docker) ---
236
+ # Uncomment below and set USE_MOCK_S3=false to use MinIO
237
+ # USE_MOCK_S3=false
238
+ # S3_ENDPOINT=http://localhost:9000
239
+ # # Must match bucket created in docker-compose.yml
240
+ # S3_BUCKET_NAME=atlas-files
241
+ # S3_ACCESS_KEY=minioadmin
242
+ # S3_SECRET_KEY=minioadmin
243
+ # S3_REGION=us-east-1
244
+ # S3_TIMEOUT=30
245
+ # S3_USE_SSL=false
246
+
247
+
248
+ # Content Security Policy (CSP) configuration
249
+ # IMPORTANT: To allow external URLs in iframes (for MCP tools that use iframe display),
250
+ # add the URLs to the frame-src directive. Example:
251
+ # SECURITY_CSP_VALUE="... frame-src 'self' blob: data: https://example.com https://dashboard.example.com; ..."
252
+ # HERE the www.sandia.gov is added as an allowed iframe source.
253
+ SECURITY_CSP_VALUE="default-src 'self'; img-src 'self' data: blob:; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; frame-src 'self' blob: data: https://www.sandia.gov; frame-ancestors 'self'"
@@ -0,0 +1,44 @@
1
+ {
2
+ "version": "2.0",
3
+ "description": "Defines compliance level types and their allowed combinations",
4
+ "levels": [
5
+ {
6
+ "name": "Public",
7
+ "description": "Publicly accessible data, no restrictions",
8
+ "aliases": [],
9
+ "allowed_with": ["Public"]
10
+ },
11
+ {
12
+ "name": "External",
13
+ "description": "External services with basic enterprise security",
14
+ "aliases": [],
15
+ "allowed_with": ["External"]
16
+ },
17
+ {
18
+ "name": "Internal",
19
+ "description": "Internal systems, can handle company IP information",
20
+ "aliases": [],
21
+ "allowed_with": ["Internal"]
22
+ },
23
+ {
24
+ "name": "SOC2",
25
+ "description": "SOC 2 Type II compliant systems",
26
+ "aliases": ["SOC-2", "SOC 2"],
27
+ "allowed_with": ["SOC2"]
28
+ },
29
+ {
30
+ "name": "HIPAA",
31
+ "description": "HIPAA compliant systems for healthcare data",
32
+ "aliases": ["HIPAA-Compliant"],
33
+ "allowed_with": ["HIPAA", "SOC2"]
34
+ },
35
+ {
36
+ "name": "FedRAMP",
37
+ "description": "FedRAMP authorized systems for government data",
38
+ "aliases": ["FedRAMP-Moderate", "FedRAMP-High"],
39
+ "allowed_with": ["FedRAMP", "SOC2"]
40
+ }
41
+ ],
42
+ "mode": "explicit_allowlist",
43
+ "mode_description": "Each compliance level explicitly defines which other levels can be used in the same session. For example, HIPAA can use HIPAA and SOC2 resources, but not Public or External to prevent data leakage."
44
+ }
@@ -0,0 +1,123 @@
1
+ {
2
+ "version": "1.0",
3
+ "description": "Email domain whitelist for user access control. Enable/disable via FEATURE_DOMAIN_WHITELIST_ENABLED environment variable. When enabled, only users with email addresses from whitelisted domains can access the application.",
4
+ "domains": [
5
+ {
6
+ "domain": "doe.gov",
7
+ "description": "Department of Energy",
8
+ "category": "Government - DOE HQ"
9
+ },
10
+ {
11
+ "domain": "nnsa.doe.gov",
12
+ "description": "National Nuclear Security Administration",
13
+ "category": "Government - DOE HQ"
14
+ },
15
+ {
16
+ "domain": "hq.doe.gov",
17
+ "description": "DOE Headquarters",
18
+ "category": "Government - DOE HQ"
19
+ },
20
+ {
21
+ "domain": "anl.gov",
22
+ "description": "Argonne National Laboratory",
23
+ "category": "National Laboratory"
24
+ },
25
+ {
26
+ "domain": "bnl.gov",
27
+ "description": "Brookhaven National Laboratory",
28
+ "category": "National Laboratory"
29
+ },
30
+ {
31
+ "domain": "fnal.gov",
32
+ "description": "Fermi National Accelerator Laboratory",
33
+ "category": "National Laboratory"
34
+ },
35
+ {
36
+ "domain": "inl.gov",
37
+ "description": "Idaho National Laboratory",
38
+ "category": "National Laboratory"
39
+ },
40
+ {
41
+ "domain": "lbl.gov",
42
+ "description": "Lawrence Berkeley National Laboratory",
43
+ "category": "National Laboratory"
44
+ },
45
+ {
46
+ "domain": "lanl.gov",
47
+ "description": "Los Alamos National Laboratory",
48
+ "category": "National Laboratory"
49
+ },
50
+ {
51
+ "domain": "llnl.gov",
52
+ "description": "Lawrence Livermore National Laboratory",
53
+ "category": "National Laboratory"
54
+ },
55
+ {
56
+ "domain": "ornl.gov",
57
+ "description": "Oak Ridge National Laboratory",
58
+ "category": "National Laboratory"
59
+ },
60
+ {
61
+ "domain": "pnnl.gov",
62
+ "description": "Pacific Northwest National Laboratory",
63
+ "category": "National Laboratory"
64
+ },
65
+ {
66
+ "domain": "sandia.gov",
67
+ "description": "Sandia National Laboratories",
68
+ "category": "National Laboratory"
69
+ },
70
+ {
71
+ "domain": "srnl.doe.gov",
72
+ "description": "Savannah River National Laboratory",
73
+ "category": "National Laboratory"
74
+ },
75
+ {
76
+ "domain": "ameslab.gov",
77
+ "description": "Ames Laboratory",
78
+ "category": "National Laboratory"
79
+ },
80
+ {
81
+ "domain": "jlab.org",
82
+ "description": "Thomas Jefferson National Accelerator Facility",
83
+ "category": "National Laboratory"
84
+ },
85
+ {
86
+ "domain": "princeton.edu",
87
+ "description": "Princeton University (PPPL host institution)",
88
+ "category": "University"
89
+ },
90
+ {
91
+ "domain": "pppl.gov",
92
+ "description": "Princeton Plasma Physics Laboratory",
93
+ "category": "National Laboratory"
94
+ },
95
+ {
96
+ "domain": "slac.stanford.edu",
97
+ "description": "SLAC National Accelerator Laboratory",
98
+ "category": "National Laboratory"
99
+ },
100
+ {
101
+ "domain": "pppl.gov",
102
+ "description": "Princeton Plasma Physics Laboratory",
103
+ "category": "National Laboratory"
104
+ },
105
+ {
106
+ "domain": "nrel.gov",
107
+ "description": "National Renewable Energy Laboratory",
108
+ "category": "National Laboratory"
109
+ },
110
+ {
111
+ "domain": "netl.doe.gov",
112
+ "description": "National Energy Technology Laboratory",
113
+ "category": "National Laboratory"
114
+ },
115
+ {
116
+ "domain": "stanford.edu",
117
+ "description": "Stanford University (SLAC host institution)",
118
+ "category": "University"
119
+ }
120
+ ],
121
+ "subdomain_matching": true,
122
+ "subdomain_matching_description": "When true, subdomains are automatically allowed (e.g., mail.sandia.gov matches sandia.gov)"
123
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "enabled": true,
3
+ "default_behavior": "extract",
4
+
5
+ "extractors": {
6
+ "pdf-text": {
7
+ "url": "http://localhost:8011/extract",
8
+ "method": "POST",
9
+ "timeout_seconds": 30,
10
+ "max_file_size_mb": 50,
11
+ "preview_chars": 2000,
12
+ "request_format": "multipart",
13
+ "form_field_name": "file",
14
+ "response_field": "text",
15
+ "enabled": true
16
+ },
17
+ "image-vision": {
18
+ "url": "http://localhost:8010/analyze",
19
+ "method": "POST",
20
+ "timeout_seconds": 60,
21
+ "max_file_size_mb": 20,
22
+ "preview_chars": 1000,
23
+ "request_format": "base64",
24
+ "response_field": "description",
25
+ "enabled": false,
26
+ "api_key": "${IMAGE_EXTRACTOR_API_KEY}"
27
+ },
28
+ "ocr": {
29
+ "url": "http://localhost:8010/ocr",
30
+ "method": "POST",
31
+ "timeout_seconds": 45,
32
+ "max_file_size_mb": 20,
33
+ "preview_chars": 2000,
34
+ "request_format": "base64",
35
+ "response_field": "text",
36
+ "enabled": false,
37
+ "api_key": "${OCR_EXTRACTOR_API_KEY}"
38
+ },
39
+ "pptx-text": {
40
+ "url": "http://localhost:8011/extract-pptx",
41
+ "method": "POST",
42
+ "timeout_seconds": 120,
43
+ "max_file_size_mb": 100,
44
+ "preview_chars": 2000,
45
+ "request_format": "base64",
46
+ "response_field": "text",
47
+ "enabled": false
48
+ }
49
+ },
50
+
51
+ "extension_mapping": {
52
+ ".pdf": "pdf-text",
53
+ ".png": "image-vision",
54
+ ".jpg": "image-vision",
55
+ ".jpeg": "image-vision",
56
+ ".gif": "image-vision",
57
+ ".webp": "image-vision",
58
+ ".tiff": "ocr",
59
+ ".tif": "ocr",
60
+ ".bmp": "ocr",
61
+ ".pptx": "pptx-text"
62
+ },
63
+
64
+ "mime_mapping": {
65
+ "application/pdf": "pdf-text",
66
+ "image/png": "image-vision",
67
+ "image/jpeg": "image-vision",
68
+ "image/gif": "image-vision",
69
+ "image/webp": "image-vision",
70
+ "image/tiff": "ocr",
71
+ "image/bmp": "ocr",
72
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": "pptx-text"
73
+ }
74
+ }