Commit a15806b
authored
feat: Add Workflow Analytics Dashboards with OpenSearch integration (#229)
* feat(infra): add nginx reverse proxy and production security
- Add nginx reverse proxy for unified entry point at http://localhost
- Routes: / (frontend), /api (backend), /analytics (OpenSearch Dashboards)
- Configure OpenSearch Dashboards with /analytics base path
- Add production deployment with TLS and security plugin
- SaaS multitenancy with per-customer tenant isolation
- Certificate generation script (just generate-certs)
- New commands: just dev, just prod-secure
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* feat(workflows): add STALE status and workflow improvements
- Add STALE status for orphaned run records (DB/Temporal mismatch)
- Improve status inference from trace events when Temporal not found
- Use correct TraceEventType values for status detection
- Add amber badge color for STALE status
- Extract WorkflowNode into modular directory structure
- Document all execution statuses with transition diagram
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* feat(analytics): add Security Analytics platform with OpenSearch integration
Analytics Sink Component (core.analytics.sink):
- Index output data from any upstream node to OpenSearch
- Auto-detect asset correlation keys (host, domain, url, ip, etc.)
- Fire-and-forget with retry logic (3 attempts, exponential backoff)
- Configurable index suffix and fail-on-error modes
OpenSearch Integration:
- Daily index rotation: security-findings-{orgId}-{YYYY.MM.DD}
- Index template with standard metadata fields
- Multi-tenant data isolation per organization
Analytics API:
- POST /api/v1/analytics/query with OpenSearch DSL support
- Auto-scope queries to organization's index pattern
- Rate limiting: 100 req/min per user
- Protected routes require authentication
- Session cookie support for analytics route auth
UI Integration:
- Analytics Settings page with tier-based retention
- Dashboards link in sidebar (opens in new tab)
- View Analytics button uses Discover app with proper URL state
- Uses .keyword fields for exact match filtering
Component SDK Extensions:
- generateFindingHash() for deduplication
- Workflow context (workflowId, workflowName, organizationId)
- Results output port on nuclei, trufflehog, supabase-scanner
- Support for optional inputs in components
Bug fixes:
- Fix webhook URLs to include global API prefix (ENG-115)
- Add proper connectionType for list variable types
- Handle invalid_value errors for placeholder fields
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* feat(analytics): add multi-tenant OpenSearch Security with dynamic provisioning
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* docs(analytics): add multi-tenant architecture and troubleshooting guide
Document the OpenSearch tenant identity resolution flow, Clerk active
org session vs membership distinction, tenant provisioning details,
and security guarantees. Add troubleshooting entry for workspace-user
fallback with screenshots and diagnostic commands.
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* feat(analytics): lock down Dashboards for SaaS tenants and fix saved objects
Two-layer SaaS lockdown for OpenSearch Dashboards:
1. nginx whitelist: PCRE negative lookahead blocks non-whitelisted
/analytics/app/* routes (returns 403). Allowed: Discover, Visualize,
Dashboards, Alerting, Dev Tools, Data Explorer, Home.
Blocked: ISM, Security, Management, Anomaly Detection, Maps, etc.
Admin retains full access via direct Dashboards port (5601).
2. Role permissions: Replace ISM cluster permissions with Alerting
permissions (monitor CRUD, alerts, destinations) for tenant roles.
Add indices:data/write/bulk cluster permission required for
Dashboards saved objects (visualizations, dashboards, saved searches).
Without this, multitenancy's kibana_all_write grant is never reached.
3. Default landing page set to Discover instead of Home (which exposes
all plugin links including blocked ones).
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* refactor(dev): unify justfile commands and harden Dashboards lockdown
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* feat(infra): lock down service ports to localhost-only in dev, disable in prod
Base compose configs (infra.yml, full.yml) now use `expose` instead of
`ports` for all internal services. Dev-ports overlay binds everything to
127.0.0.1. Only nginx port 80 remains publicly accessible.
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* fix(analytics): harden tenant security roles and restore bulk write permission
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* chore(infra): consolidate duplicate configs and remove orphaned files
- Merge nginx.full.conf into nginx.prod.conf (95% identical, prod has better proxy_redirect)
- Consolidate DB init scripts: merge temporal DB creation into 01-create-instance-databases.sh
- Remove orphaned scripts: dev-instance-manager.sh, instance-bootstrap.sh (unreferenced)
- Remove deprecated opensearch-security/whitelist.yml (superseded by allowlist.yml)
- Update docker-compose.full.yml and docs to reference nginx.prod.conf
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* fix(test): mock AnalyticsModule in MCP integration test
The AnalyticsModule's controller and services depend on ConfigService
and OpenSearchClient which aren't available in the MCP test module.
Use overrideModule to replace the entire AnalyticsModule with mocks.
Also add explicit ConfigModule import to AnalyticsModule.
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* fix(infra): correct PM2 process names, Kafka port, and security init
- Fix PM2 --only filter to use instance-suffixed names (shipsec-backend-0)
- Fix Kafka broker port from 19092 to 9092 (matches single-listener Redpanda)
- Add whitelist.yml required by securityadmin.sh alongside allowlist.yml
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* refactor(ui): move Analytics Settings under Manage sidebar section
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* docs: update port references to reflect nginx routing in dev mode
Update all documentation to reflect that services are accessed through nginx
on port 80 in both dev and production modes:
- docker/README.md: Add nginx routing table for dev mode
- docs/installation.mdx: Update service endpoints and analytics URLs
- docs/quickstart.mdx: Update access points
- docs/architecture.mdx: Update development URLs
- docs/command-reference.mdx: Update dev and prod access points
- README.md: Correct production access URL from 8090 to 80
Individual service ports (5173, 3211, 5601) remain available for debugging
but should not be used in normal development.
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* docs: update env examples and remaining port references to nginx routing
Update environment variable examples and remaining documentation to reflect
nginx routing for all application services:
- backend/.env.example: Update OPENSEARCH_DASHBOARDS_URL comment
- worker/.env.example: Update OPENSEARCH_DASHBOARDS_URL to use nginx route
- docs/development/component-development.mdx: Update API examples to use nginx
- docs/user-guide.md: Update access URL from 8090 to 80
- docs/installation.mdx: Update env examples and production endpoints
- docs/analytics.md: Update dashboard access URLs and SSH tunneling
- docs/development/workflow-analytics.mdx: Update dashboard URL example
All services now accessed via nginx on port 80 with proper routing:
- Frontend: http://localhost/
- Backend API: http://localhost/api/
- Analytics: http://localhost/analytics/
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
* docs(justfile): clarify debug port messages for nginx routing
Update development mode port messages to explicitly indicate that direct
service ports are for debugging only and nginx should be used in normal
development. This aligns with the port isolation pattern from PR #265.
Changes:
- Add "(debugging only, use nginx in normal development)" to port messages
- Consistent messaging across secure and local auth modes
- Production mode already correctly shows nginx routing and port isolation
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
---------
Signed-off-by: Aseem Shrey <LuD1161@users.noreply.github.com>
Co-authored-by: Aseem Shrey <LuD1161@users.noreply.github.com>1 parent fe8b35d commit a15806b
132 files changed
Lines changed: 9171 additions & 973 deletions
File tree
- .ai
- backend
- scripts
- src
- analytics
- dto
- auth
- providers
- config
- database
- schema
- dsl
- mcp/__tests__
- workflows
- docker
- certs
- init-db
- nginx
- opensearch-security
- scripts
- docs
- components
- development
- media
- workflows
- e2e-tests
- frontend
- src
- auth
- components
- auth
- layout
- workflow
- config
- features/workflow-builder
- hooks
- pages
- store
- utils
- packages
- component-sdk/src
- scripts
- worker
- src
- components
- core
- security
- __tests__
- test
- __tests__
- temporal
- __tests__
- activities
- workflows
- utils
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
92 | 93 | | |
93 | 94 | | |
94 | 95 | | |
| |||
98 | 99 | | |
99 | 100 | | |
100 | 101 | | |
| 102 | + | |
101 | 103 | | |
102 | 104 | | |
103 | 105 | | |
| |||
129 | 131 | | |
130 | 132 | | |
131 | 133 | | |
| 134 | + | |
132 | 135 | | |
133 | 136 | | |
134 | 137 | | |
| |||
138 | 141 | | |
139 | 142 | | |
140 | 143 | | |
| 144 | + | |
141 | 145 | | |
142 | 146 | | |
143 | 147 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
56 | | - | |
| 56 | + | |
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
| 82 | + | |
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
| 36 | + | |
35 | 37 | | |
36 | 38 | | |
37 | 39 | | |
| |||
44 | 46 | | |
45 | 47 | | |
46 | 48 | | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
52 | 60 | | |
53 | 61 | | |
54 | 62 | | |
55 | 63 | | |
56 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
57 | 69 | | |
58 | 70 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| 24 | + | |
23 | 25 | | |
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
28 | 30 | | |
| 31 | + | |
| 32 | + | |
29 | 33 | | |
30 | 34 | | |
31 | 35 | | |
| |||
62 | 66 | | |
63 | 67 | | |
64 | 68 | | |
| 69 | + | |
65 | 70 | | |
66 | 71 | | |
67 | 72 | | |
| |||
0 commit comments