Merge pull request #124 from sirius0xdev/fix/osint-dashboard-manifest-audit

Audit: OSINT Dashboard Helm chart - security, resilience and reliability fixes
This commit is contained in:
sirius0xdev 2026-05-23 01:57:45 -04:00 committed by GitHub
commit d68eb72833
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 82 additions and 56 deletions

View file

@ -11,12 +11,12 @@ data:
DB_HOST: "{{ .Values.postgresql.clusterName }}-rw.{{ .Values.namespace }}.svc.cluster.local"
DB_PORT: "{{ .Values.postgresql.port | default \"5432\" }}"
DB_NAME: "{{ .Values.postgresql.database | default \"osint_data\" }}"
NATS_URLS: "nats://{{ include \"osint-dashboard.fullname\" . }}-nats.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.nats.ports.client }}"
REDIS_URL: "redis://{{ include \"osint-dashboard.fullname\" . }}-redis.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.redis.ports.redis }}/0"
MINIO_ENDPOINT: "{{ include \"osint-dashboard.fullname\" . }}-minio.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.minio.ports.api }}"
MINIO_BUCKET_VIDEO: "{{ .Values.minio.buckets._0.name | default \"osint-video-clips\" }}"
MINIO_BUCKET_SATELLITE: "{{ .Values.minio.buckets._1.name | default \"osint-satellite-tiles\" }}"
MINIO_BUCKET_DATA: "{{ .Values.minio.buckets._2.name | default \"osint-data-dumps\" }}"
NATS_URLS: "nats://nats.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.nats.ports.client }}"
REDIS_URL: "redis://redis-master.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.redis.ports.redis }}/0"
MINIO_ENDPOINT: "minio.{{ .Values.namespace }}.svc.cluster.local:{{ .Values.minio.ports.api }}"
MINIO_BUCKET_VIDEO: "{{ .Values.minio.buckets.0.name | default \"osint-video-clips\" }}"
MINIO_BUCKET_SATELLITE: "{{ .Values.minio.buckets.1.name | default \"osint-satellite-tiles\" }}"
MINIO_BUCKET_DATA: "{{ .Values.minio.buckets.2.name | default \"osint-data-dumps\" }}"
PYTHONPATH: "/app/app"
PYTHONUNBUFFERED: "1"
PYTHONDONTWRITEBYTECODE: "1"

View file

@ -10,6 +10,7 @@ metadata:
spec:
schedule: "*/5 * * * *"
concurrencyPolicy: Forbid
activeDeadlineSeconds: 3600
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
@ -62,6 +63,7 @@ metadata:
spec:
schedule: "*/15 * * * *"
concurrencyPolicy: Forbid
activeDeadlineSeconds: 3600
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
@ -114,6 +116,7 @@ metadata:
spec:
schedule: "0 * * * *"
concurrencyPolicy: Forbid
activeDeadlineSeconds: 3600
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
@ -166,6 +169,7 @@ metadata:
spec:
schedule: "*/2 * * * *"
concurrencyPolicy: Forbid
activeDeadlineSeconds: 3600
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:

View file

@ -53,6 +53,11 @@ spec:
secretKeyRef:
name: {{ .Values.postgresql.credentialsSecret }}
key: password
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
startupProbe:
httpGet:
path: /api/health

View file

@ -19,8 +19,19 @@ spec:
type: PathPrefix
value: {{ $rule.path }}
backendRefs:
{{- if eq $host.host "dashboard.siriusdevops.com" }}
- name: dashboard-web
port: 3000
{{- else if eq $host.host "api.siriusdevops.com" }}
- name: {{ include "osint-dashboard.fullname" $ }}-api
port: 8000
{{- else if eq $host.host "ws.siriusdevops.com" }}
- name: {{ include "osint-dashboard.fullname" $ }}-api
port: 8000
{{- else }}
- name: dashboard-web
port: 3000
{{- end }}
weight: 100
{{- end }}
---

View file

@ -69,7 +69,7 @@ spec:
periodSeconds: 10
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeClaimTemplates:

View file

@ -0,0 +1,44 @@
{{- if .Values.nats.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: nats-config
namespace: {{ .Values.namespace }}
labels:
{{- include "osint-dashboard.labels" . | nindent 4 }}
data:
nats-server.conf: |
port: {{ .Values.nats.ports.client }}
server_name: "osint-nats-${HOSTNAME}"
# Cluster
cluster {
port: {{ .Values.nats.ports.cluster }}
routes: [
nats-route://nats-0.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }},
nats-route://nats-1.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }},
nats-route://nats-2.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }}
]
cluster_advertise: "nats-${HOSTNAME}.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }}"
}
# JetStream
jetstream {
store_dir: "{{ .Values.nats.jetstream.fileStore }}"
max_mem_store: {{ .Values.nats.jetstream.maxMemory }}
max_file_store: {{ .Values.nats.storage.size }}
}
# Monitoring
monitor: {{ .Values.nats.ports.monitor }}
# WebSocket
websocket {
port: {{ .Values.nats.ports.websocket }}
no_tls: true
}
# Logging
logtime: true
log_file: /var/log/nats/nats.log
{{- end }}

View file

@ -1,47 +1,4 @@
{{- if .Values.nats.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: nats-config
namespace: {{ .Values.namespace }}
labels:
{{- include "osint-dashboard.labels" . | nindent 4 }}
data:
nats-server.conf: |
port: {{ .Values.nats.ports.client }}
server_name: "osint-nats-${HOSTNAME}"
# Cluster
cluster {
port: {{ .Values.nats.ports.cluster }}
routes: [
nats-route://nats-0.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }},
nats-route://nats-1.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }},
nats-route://nats-2.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }}
]
cluster_advertise: "nats-${HOSTNAME}.nats-cluster.{{ .Values.namespace }}.svc:{{ .Values.nats.ports.cluster }}"
}
# JetStream
jetstream {
store_dir: "{{ .Values.nats.jetstream.fileStore }}"
max_mem_store: {{ .Values.nats.jetstream.maxMemory }}
max_file_store: {{ .Values.nats.storage.size }}
}
# Monitoring
monitor: {{ .Values.nats.ports.monitor }}
# WebSocket
websocket {
port: {{ .Values.nats.ports.websocket }}
no_tls: true
}
# Logging
logtime: true
log_file: /var/log/nats/nats.log
---
apiVersion: apps/v1
kind: StatefulSet
metadata:

View file

@ -144,7 +144,7 @@ spec:
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
postgresql operator: {{ .Values.postgresql.clusterName }}
postgresql.cnpg.io/cluster: {{ .Values.postgresql.clusterName }}
nodesAutoRemediationChecks:
livenessProbe:
initialDelaySeconds: 10

View file

@ -44,7 +44,7 @@ spec:
app.kubernetes.io/component: api
ports:
- protocol: TCP
port: 4000
port: 8000
# Allow to external APIs (GDelt, satellite providers)
- to:
- ipBlock:
@ -78,7 +78,7 @@ spec:
app.kubernetes.io/component: web
ports:
- protocol: TCP
port: 4000
port: 8000
# Allow from ingress controller / Gateway API
- from:
- namespaceSelector:
@ -86,7 +86,7 @@ spec:
kubernetes.io/metadata.name: ingress-nginx
ports:
- protocol: TCP
port: 4000
port: 8000
egress:
# Allow DNS
- to:

View file

@ -16,8 +16,11 @@ spec:
- Ingress
- Egress
ingress:
# Allow Grafana web access
- from: []
# Allow Grafana web access from monitoring namespace
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
ports:
- protocol: TCP
port: {{ .Values.monitoring.grafana.port }}

View file

@ -31,6 +31,8 @@ postgresql:
imageName: ghcr.io/cloudnative-pg/postgresql:16
# Custom image with PostGIS + TimescaleDB
# Use CNPG bootstrap to create extensions
port: 5432
database: osint
storage:
size: 200Gi
storageClass: premium-rwo