Skip to content

Commit 000fe03

Browse files
committed
Merge branch 'LuD1161/pull-analytics-branch' into eng-42/workflow-analytics-dashboards
2 parents 8b3168a + 3646e89 commit 000fe03

7 files changed

Lines changed: 159 additions & 65 deletions

File tree

backend/src/analytics/opensearch-tenant.service.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,18 +172,20 @@ export class OpenSearchTenantService {
172172

173173
/**
174174
* Creates a read-only customer role for the organization.
175-
* Grants read access to security-findings-{orgId}-* indices.
175+
* Grants read-only access to security findings indices, plus the minimum
176+
* Dashboards/Notifications permissions required for tenant-scoped UI usage.
176177
*/
177178
private async createCustomerRole(orgId: string): Promise<void> {
178179
const roleName = `customer_${orgId}_ro`;
179180
const url = `${this.opensearchUrl}/_plugins/_security/api/roles/${roleName}`;
181+
const tenantSavedObjectsPattern = `.kibana_*_${orgId.replace(/[^a-z0-9]/g, '')}*`;
180182

181183
const roleDefinition = {
182184
cluster_permissions: [
183185
'cluster_composite_ops_ro',
184186
// Required for Dashboards saved objects (bulk writes to .kibana_* tenant indices)
185187
'indices:data/write/bulk',
186-
// Alerting: monitor CRUD, execution, alerts, and destinations
188+
// Alerting: monitor CRUD, execution, alerts, and destinations (legacy endpoints)
187189
'cluster:admin/opendistro/alerting/monitor/get',
188190
'cluster:admin/opendistro/alerting/monitor/search',
189191
'cluster:admin/opendistro/alerting/monitor/write',
@@ -193,12 +195,30 @@ export class OpenSearchTenantService {
193195
'cluster:admin/opendistro/alerting/destination/get',
194196
'cluster:admin/opendistro/alerting/destination/write',
195197
'cluster:admin/opendistro/alerting/destination/delete',
198+
// Notifications plugin (OpenSearch 2.x): channel features + config CRUD
199+
'cluster:admin/opensearch/notifications/features',
200+
'cluster:admin/opensearch/notifications/configs/get',
201+
'cluster:admin/opensearch/notifications/configs/create',
202+
'cluster:admin/opensearch/notifications/configs/update',
203+
'cluster:admin/opensearch/notifications/configs/delete',
196204
],
197205
index_permissions: [
198206
{
199207
index_patterns: [`security-findings-${orgId}-*`],
200208
allowed_actions: ['read', 'indices:data/read/*'],
201209
},
210+
{
211+
// Tenant-scoped Dashboards saved objects index alias/index
212+
index_patterns: [tenantSavedObjectsPattern],
213+
allowed_actions: [
214+
'read',
215+
'write',
216+
'create_index',
217+
'indices:data/read/*',
218+
'indices:data/write/*',
219+
'indices:admin/mapping/put',
220+
],
221+
},
202222
],
203223
tenant_permissions: [
204224
{

docker/docker-compose.dev-ports.yml

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,49 @@
11
# Development Ports Overlay
22
#
33
# WARNING: These ports bypass ALL nginx authentication!
4-
# Use ONLY for local development where direct OpenSearch/Dashboards access is needed.
4+
# Use ONLY for local development where direct service access is needed.
55
#
66
# Usage:
77
# docker compose -f docker-compose.infra.yml -f docker-compose.dev-ports.yml up -d
88
#
9-
# This overlay exposes OpenSearch and Dashboards ports on loopback (127.0.0.1) only,
9+
# This overlay exposes all service ports on loopback (127.0.0.1) only,
1010
# preventing external network access while allowing local development tools to connect.
1111

1212
services:
13+
postgres:
14+
ports:
15+
- "127.0.0.1:5433:5432"
16+
17+
temporal:
18+
ports:
19+
- "127.0.0.1:7233:7233"
20+
21+
temporal-ui:
22+
ports:
23+
- "127.0.0.1:8081:8080"
24+
25+
minio:
26+
ports:
27+
- "127.0.0.1:9000:9000"
28+
- "127.0.0.1:9001:9001"
29+
30+
redis:
31+
ports:
32+
- "127.0.0.1:6379:6379"
33+
34+
loki:
35+
ports:
36+
- "127.0.0.1:3100:3100"
37+
38+
redpanda:
39+
ports:
40+
- "127.0.0.1:9092:9092"
41+
- "127.0.0.1:9644:9644"
42+
43+
redpanda-console:
44+
ports:
45+
- "127.0.0.1:8082:8080"
46+
1347
opensearch:
1448
ports:
1549
- "127.0.0.1:9200:9200"

docker/docker-compose.full.yml

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ services:
88
POSTGRES_PASSWORD: shipsec
99
POSTGRES_DB: shipsec
1010
POSTGRES_MULTIPLE_DATABASES: temporal
11-
ports:
12-
- "5433:5432"
11+
# Internal only - no direct port access in production
12+
expose:
13+
- "5432"
1314
volumes:
1415
- postgres_data:/var/lib/postgresql/data
1516
- ./init-db:/docker-entrypoint-initdb.d
@@ -34,8 +35,8 @@ services:
3435
- POSTGRES_PWD=shipsec
3536
- POSTGRES_SEEDS=postgres
3637
- AUTO_SETUP=true
37-
ports:
38-
- "7233:7233"
38+
expose:
39+
- "7233"
3940
volumes:
4041
- temporal_data:/var/lib/temporal
4142
restart: unless-stopped
@@ -51,8 +52,8 @@ services:
5152
environment:
5253
- TEMPORAL_ADDRESS=temporal:7233
5354
- TEMPORAL_NAMESPACE=default
54-
ports:
55-
- "8081:8080"
55+
expose:
56+
- "8080"
5657
depends_on:
5758
- temporal
5859
restart: unless-stopped
@@ -69,9 +70,9 @@ services:
6970
environment:
7071
MINIO_ROOT_USER: minioadmin
7172
MINIO_ROOT_PASSWORD: minioadmin
72-
ports:
73-
- "9000:9000"
74-
- "9001:9001"
73+
expose:
74+
- "9000"
75+
- "9001"
7576
volumes:
7677
- minio_data:/data
7778
restart: unless-stopped
@@ -85,8 +86,8 @@ services:
8586
image: grafana/loki:3.2.1
8687
container_name: shipsec-loki
8788
command: -config.file=/etc/loki/local-config.yaml
88-
ports:
89-
- "3100:3100"
89+
expose:
90+
- "3100"
9091
volumes:
9192
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
9293
- loki_data:/loki
@@ -100,8 +101,8 @@ services:
100101
redis:
101102
image: redis:latest
102103
container_name: shipsec-redis
103-
ports:
104-
- "6379:6379"
104+
expose:
105+
- "6379"
105106
volumes:
106107
- redis_data:/data
107108
restart: unless-stopped
@@ -124,9 +125,9 @@ services:
124125
- --node-id=0
125126
- --check=false
126127
- --advertise-kafka-addr=redpanda:9092
127-
ports:
128-
- "9092:9092"
129-
- "9644:9644"
128+
expose:
129+
- "9092"
130+
- "9644"
130131
volumes:
131132
- redpanda_data:/var/lib/redpanda/data
132133
restart: unless-stopped
@@ -143,8 +144,8 @@ services:
143144
- redpanda
144145
environment:
145146
CONFIG_FILEPATH: /etc/redpanda/console-config.yaml
146-
ports:
147-
- "8082:8080"
147+
expose:
148+
- "8080"
148149
volumes:
149150
- ./redpanda-console-config.yaml:/etc/redpanda/console-config.yaml:ro
150151
restart: unless-stopped
@@ -165,9 +166,9 @@ services:
165166
nofile:
166167
soft: 65536
167168
hard: 65536
168-
ports:
169-
- "9200:9200"
170-
- "9600:9600"
169+
expose:
170+
- "9200"
171+
- "9600"
171172
volumes:
172173
- opensearch_data:/usr/share/opensearch/data
173174
restart: unless-stopped

docker/docker-compose.infra.yml

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ services:
77
POSTGRES_PASSWORD: shipsec
88
POSTGRES_DB: shipsec
99
POSTGRES_MULTIPLE_DATABASES: temporal
10-
ports:
11-
- "5433:5432"
10+
# Internal only - use docker-compose.dev-ports.yml overlay for local dev access
11+
expose:
12+
- "5432"
1213
volumes:
1314
- postgres_data:/var/lib/postgresql/data
1415
- ./init-db:/docker-entrypoint-initdb.d
@@ -33,8 +34,8 @@ services:
3334
- POSTGRES_PWD=shipsec
3435
- POSTGRES_SEEDS=postgres
3536
- AUTO_SETUP=true
36-
ports:
37-
- "7233:7233"
37+
expose:
38+
- "7233"
3839
volumes:
3940
- temporal_data:/var/lib/temporal
4041
restart: unless-stopped
@@ -47,8 +48,8 @@ services:
4748
environment:
4849
- TEMPORAL_ADDRESS=temporal:7233
4950
- TEMPORAL_CORS_ORIGINS=http://localhost:5173
50-
ports:
51-
- "8081:8080"
51+
expose:
52+
- "8080"
5253
restart: unless-stopped
5354

5455
minio:
@@ -58,9 +59,9 @@ services:
5859
environment:
5960
MINIO_ROOT_USER: minioadmin
6061
MINIO_ROOT_PASSWORD: minioadmin
61-
ports:
62-
- "9000:9000"
63-
- "9001:9001"
62+
expose:
63+
- "9000"
64+
- "9001"
6465
volumes:
6566
- minio_data:/data
6667
restart: unless-stopped
@@ -73,8 +74,8 @@ services:
7374
redis:
7475
image: redis:latest
7576
container_name: shipsec-redis
76-
ports:
77-
- "6379:6379"
77+
expose:
78+
- "6379"
7879
volumes:
7980
- redis_data:/data
8081
restart: unless-stopped
@@ -88,8 +89,8 @@ services:
8889
image: grafana/loki:3.2.1
8990
container_name: shipsec-loki
9091
command: -config.file=/etc/loki/local-config.yaml
91-
ports:
92-
- "3100:3100"
92+
expose:
93+
- "3100"
9394
volumes:
9495
- ./loki/loki-config.yaml:/etc/loki/local-config.yaml
9596
- loki_data:/loki
@@ -113,9 +114,9 @@ services:
113114
- --node-id=0
114115
- --check=false
115116
- --advertise-kafka-addr=localhost:9092
116-
ports:
117-
- "9092:9092"
118-
- "9644:9644"
117+
expose:
118+
- "9092"
119+
- "9644"
119120
volumes:
120121
- redpanda_data:/var/lib/redpanda/data
121122
restart: unless-stopped
@@ -132,8 +133,8 @@ services:
132133
- redpanda
133134
environment:
134135
CONFIG_FILEPATH: /etc/redpanda/console-config.yaml
135-
ports:
136-
- "8082:8080"
136+
expose:
137+
- "8080"
137138
volumes:
138139
- ./redpanda-console-config.yaml:/etc/redpanda/console-config.yaml:ro
139140
restart: unless-stopped

docker/opensearch-dashboards.Dockerfile

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
FROM opensearchproject/opensearch-dashboards:2.11.1
1+
# Custom OpenSearch Dashboards image for SaaS tenant lockdown
2+
# Source: https://github.com/ShipSecAI/tools/tree/main/misc/opensearch-dashboards-saas
3+
#
4+
# Removes unwanted plugins from sidebar. Config-level disabling is NOT possible
5+
# because OSD 2.x plugins don't register an "enabled" config key (fatal error).
6+
# See the tools repo README for full documentation.
27

3-
# SaaS Tenant Lockdown - Remove plugins that tenants should not access
4-
# Allowed: Discover, Dashboards, Visualize, Alerting, Dev Tools, Home
5-
# Keeping: alertingDashboards, notificationsDashboards (alerting dependency),
6-
# securityDashboards (proxy auth/multitenancy), ganttChartDashboards (viz type)
8+
FROM opensearchproject/opensearch-dashboards:2.11.1
79

810
RUN /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin remove queryWorkbenchDashboards && \
911
/usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin remove reportsDashboards && \

docker/opensearch-security/roles.yml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ customer_template_rw:
8282
- "indices:data/read/scroll*"
8383
# Required for Dashboards saved objects (bulk writes to .kibana_* tenant indices)
8484
- "indices:data/write/bulk"
85-
# Alerting: monitor CRUD, execution, alerts, and destinations
85+
# Alerting: monitor CRUD, execution, alerts, and destinations (legacy endpoints)
8686
- "cluster:admin/opendistro/alerting/monitor/get"
8787
- "cluster:admin/opendistro/alerting/monitor/search"
8888
- "cluster:admin/opendistro/alerting/monitor/write"
@@ -92,6 +92,12 @@ customer_template_rw:
9292
- "cluster:admin/opendistro/alerting/destination/get"
9393
- "cluster:admin/opendistro/alerting/destination/write"
9494
- "cluster:admin/opendistro/alerting/destination/delete"
95+
# Notifications plugin (OpenSearch 2.x): channel features + config CRUD
96+
- "cluster:admin/opensearch/notifications/features"
97+
- "cluster:admin/opensearch/notifications/configs/get"
98+
- "cluster:admin/opensearch/notifications/configs/create"
99+
- "cluster:admin/opensearch/notifications/configs/update"
100+
- "cluster:admin/opensearch/notifications/configs/delete"
95101
index_permissions:
96102
- index_patterns:
97103
- "CUSTOMER_ID_PLACEHOLDER-*"
@@ -102,6 +108,15 @@ customer_template_rw:
102108
- "indices:data/read/*"
103109
- "indices:data/write/*"
104110
- "indices:admin/mapping/put"
111+
- index_patterns:
112+
- ".kibana*"
113+
allowed_actions:
114+
- "read"
115+
- "write"
116+
- "create_index"
117+
- "indices:data/read/*"
118+
- "indices:data/write/*"
119+
- "indices:admin/mapping/put"
105120
tenant_permissions:
106121
- tenant_patterns:
107122
- "CUSTOMER_ID_PLACEHOLDER"
@@ -118,7 +133,7 @@ customer_template_ro:
118133
- "cluster_composite_ops_ro"
119134
# Required for Dashboards saved objects (bulk writes to .kibana_* tenant indices)
120135
- "indices:data/write/bulk"
121-
# Alerting: monitor CRUD, execution, alerts, and destinations
136+
# Alerting: monitor CRUD, execution, alerts, and destinations (legacy endpoints)
122137
- "cluster:admin/opendistro/alerting/monitor/get"
123138
- "cluster:admin/opendistro/alerting/monitor/search"
124139
- "cluster:admin/opendistro/alerting/monitor/write"
@@ -128,12 +143,27 @@ customer_template_ro:
128143
- "cluster:admin/opendistro/alerting/destination/get"
129144
- "cluster:admin/opendistro/alerting/destination/write"
130145
- "cluster:admin/opendistro/alerting/destination/delete"
146+
# Notifications plugin (OpenSearch 2.x): channel features + config CRUD
147+
- "cluster:admin/opensearch/notifications/features"
148+
- "cluster:admin/opensearch/notifications/configs/get"
149+
- "cluster:admin/opensearch/notifications/configs/create"
150+
- "cluster:admin/opensearch/notifications/configs/update"
151+
- "cluster:admin/opensearch/notifications/configs/delete"
131152
index_permissions:
132153
- index_patterns:
133154
- "CUSTOMER_ID_PLACEHOLDER-*"
134155
allowed_actions:
135156
- "read"
136157
- "indices:data/read/*"
158+
- index_patterns:
159+
- ".kibana*"
160+
allowed_actions:
161+
- "read"
162+
- "write"
163+
- "create_index"
164+
- "indices:data/read/*"
165+
- "indices:data/write/*"
166+
- "indices:admin/mapping/put"
137167
tenant_permissions:
138168
- tenant_patterns:
139169
- "CUSTOMER_ID_PLACEHOLDER"

0 commit comments

Comments
 (0)