feat: add marketplace metrics, privacy features, and service registry endpoints

- Add Prometheus metrics for marketplace API throughput and error rates with new dashboard panels
- Implement confidential transaction models with encryption support and access control
- Add key management system with registration, rotation, and audit logging
- Create services and registry routers for service discovery and management
- Integrate ZK proof generation for privacy-preserving receipts
- Add metrics instru
This commit is contained in:
oib
2025-12-22 10:33:23 +01:00
parent d98b2c7772
commit c8be9d7414
260 changed files with 59033 additions and 351 deletions

View File

@ -0,0 +1,64 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "aitbc-blockchain-node.fullname" . }}
labels:
{{- include "aitbc-blockchain-node.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "aitbc-blockchain-node.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
# Custom metrics for blockchain-specific scaling
- type: External
external:
metric:
name: blockchain_transaction_queue_depth
target:
type: AverageValue
averageValue: "100"
- type: External
external:
metric:
name: blockchain_pending_transactions
target:
type: AverageValue
averageValue: "500"
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # Longer stabilization for blockchain
policies:
- type: Percent
value: 5
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 50
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Max
{{- end }}

View File

@ -0,0 +1,11 @@
apiVersion: v2
name: aitbc-coordinator
description: AITBC Coordinator API Helm Chart
type: application
version: 0.1.0
appVersion: "0.1.0"
dependencies:
- name: postgresql
version: 12.x.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled

View File

@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "aitbc-coordinator.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "aitbc-coordinator.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "aitbc-coordinator.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "aitbc-coordinator.labels" -}}
helm.sh/chart: {{ include "aitbc-coordinator.chart" . }}
{{ include "aitbc-coordinator.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "aitbc-coordinator.selectorLabels" -}}
app.kubernetes.io/name: {{ include "aitbc-coordinator.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "aitbc-coordinator.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "aitbc-coordinator.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,90 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "aitbc-coordinator.fullname" . }}
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "aitbc-coordinator.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "aitbc-coordinator.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "aitbc-coordinator.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
livenessProbe:
{{- toYaml .Values.livenessProbe | nindent 12 }}
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
env:
- name: APP_ENV
value: {{ .Values.config.appEnv }}
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ include "aitbc-coordinator.fullname" . }}
key: database-url
- name: ALLOW_ORIGINS
value: {{ .Values.config.allowOrigins | quote }}
{{- if .Values.config.receiptSigningKeyHex }}
- name: RECEIPT_SIGNING_KEY_HEX
valueFrom:
secretKeyRef:
name: {{ include "aitbc-coordinator.fullname" . }}
key: receipt-signing-key
{{- end }}
{{- if .Values.config.receiptAttestationKeyHex }}
- name: RECEIPT_ATTESTATION_KEY_HEX
valueFrom:
secretKeyRef:
name: {{ include "aitbc-coordinator.fullname" . }}
key: receipt-attestation-key
{{- end }}
volumeMounts:
- name: config
mountPath: /app/.env
subPath: .env
volumes:
- name: config
configMap:
name: {{ include "aitbc-coordinator.fullname" . }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,60 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "aitbc-coordinator.fullname" . }}
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "aitbc-coordinator.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.customMetrics }}
{{- range .Values.autoscaling.customMetrics }}
- type: External
external:
metric:
name: {{ .name }}
target:
type: AverageValue
averageValue: {{ .targetValue }}
{{- end }}
{{- end }}
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
{{- end }}

View File

@ -0,0 +1,70 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "aitbc-coordinator.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class")) }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else -}}
apiVersion: networking.k8s.io/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
annotations:
# Security annotations (always applied)
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.3"
nginx.ingress.kubernetes.io/ssl-ciphers: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "X-Frame-Options: DENY";
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Referrer-Policy: strict-origin-when-cross-origin";
more_set_headers "Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'";
more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload";
cert-manager.io/cluster-issuer: {{ .Values.ingress.certManager.issuer | default "letsencrypt-prod" }}
# User-provided annotations
{{- with .Values.ingress.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,73 @@
{{- if .Values.networkPolicy.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ include "aitbc-coordinator.fullname" . }}
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
{{- include "aitbc-coordinator.selectorLabels" . | nindent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
# Allow traffic from ingress controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
ports:
- protocol: TCP
port: http
# Allow traffic from monitoring
- from:
- namespaceSelector:
matchLabels:
name: monitoring
- podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
ports:
- protocol: TCP
port: http
# Allow traffic from wallet-daemon
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: wallet-daemon
ports:
- protocol: TCP
port: http
# Allow traffic from same namespace for internal communication
- from:
- podSelector: {}
ports:
- protocol: TCP
port: http
egress:
# Allow DNS resolution
- to: []
ports:
- protocol: UDP
port: 53
# Allow PostgreSQL access
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: postgresql
ports:
- protocol: TCP
port: 5432
# Allow external API calls (if needed)
- to: []
ports:
- protocol: TCP
port: 443
- protocol: TCP
port: 80
{{- end }}

View File

@ -0,0 +1,59 @@
{{- if .Values.podSecurityPolicy.enabled }}
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: {{ include "aitbc-coordinator.fullname" . }}
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "aitbc-coordinator.fullname" }}-psp
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- {{ include "aitbc-coordinator.fullname" . }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "aitbc-coordinator.fullname" }}-psp
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
roleRef:
kind: Role
name: {{ include "aitbc-coordinator.fullname" }}-psp
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: {{ include "aitbc-coordinator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@ -0,0 +1,21 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "aitbc-coordinator.fullname" . }}
labels:
{{- include "aitbc-coordinator.labels" . | nindent 4 }}
{{- if .Values.monitoring.enabled }}
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "{{ .Values.service.port }}"
prometheus.io/path: "{{ .Values.monitoring.serviceMonitor.path }}"
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
protocol: TCP
name: http
selector:
{{- include "aitbc-coordinator.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,162 @@
# Default values for aitbc-coordinator.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: aitbc/coordinator-api
pullPolicy: IfNotPresent
tag: "0.1.0"
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
fsGroup: 1000
securityContext:
allowPrivilegeEscalation: false
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
service:
type: ClusterIP
port: 8011
targetPort: 8011
ingress:
enabled: false
className: nginx
annotations: {}
# cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: coordinator.local
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: coordinator-tls
# hosts:
# - coordinator.local
# Pod Security Policy
podSecurityPolicy:
enabled: true
# Network policies
networkPolicy:
enabled: true
security:
auth:
enabled: true
requireApiKey: true
apiKeyHeader: "X-API-Key"
tls:
version: "TLSv1.3"
ciphers: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
headers:
frameOptions: "DENY"
contentTypeOptions: "nosniff"
xssProtection: "1; mode=block"
referrerPolicy: "strict-origin-when-cross-origin"
hsts:
enabled: true
maxAge: 31536000
includeSubDomains: true
preload: true
rateLimit:
enabled: true
requestsPerMinute: 60
burst: 10
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
# Configuration
config:
appEnv: production
databaseUrl: "postgresql://aitbc:password@postgresql:5432/aitbc"
receiptSigningKeyHex: ""
receiptAttestationKeyHex: ""
allowOrigins: "*"
# PostgreSQL sub-chart configuration
postgresql:
enabled: true
auth:
postgresPassword: "password"
username: aitbc
database: aitbc
primary:
persistence:
enabled: true
size: 20Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# Monitoring
monitoring:
enabled: true
serviceMonitor:
enabled: true
interval: 30s
path: /metrics
port: http
# Health checks
livenessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /v1/health
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3

View File

@ -0,0 +1,19 @@
apiVersion: v2
name: aitbc-monitoring
description: AITBC Monitoring Stack (Prometheus, Grafana, AlertManager)
type: application
version: 0.1.0
appVersion: "0.1.0"
dependencies:
- name: prometheus
version: 23.1.0
repository: https://prometheus-community.github.io/helm-charts
condition: prometheus.enabled
- name: grafana
version: 6.58.9
repository: https://grafana.github.io/helm-charts
condition: grafana.enabled
- name: alertmanager
version: 1.6.1
repository: https://prometheus-community.github.io/helm-charts
condition: alertmanager.enabled

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "aitbc-monitoring.fullname" . }}-dashboards
labels:
{{- include "aitbc-monitoring.labels" . | nindent 4 }}
annotations:
grafana.io/dashboard: "1"
data:
blockchain-node-overview.json: |
{{ .Files.Get "dashboards/blockchain-node-overview.json" | indent 4 }}
coordinator-overview.json: |
{{ .Files.Get "dashboards/coordinator-overview.json" | indent 4 }}

View File

@ -0,0 +1,124 @@
# Default values for aitbc-monitoring.
# Prometheus configuration
prometheus:
enabled: true
server:
enabled: true
global:
scrape_interval: 15s
evaluation_interval: 15s
retention: 30d
persistentVolume:
enabled: true
size: 100Gi
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
service:
type: ClusterIP
port: 9090
serviceMonitors:
enabled: true
selector:
release: monitoring
alertmanager:
enabled: false
config:
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/'
# Grafana configuration
grafana:
enabled: true
adminPassword: admin
persistence:
enabled: true
size: 20Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
service:
type: ClusterIP
port: 3000
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus-server:9090
access: proxy
isDefault: true
dashboardProviders:
dashboardproviders.yaml:
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards/default
# Service monitors for AITBC services
serviceMonitors:
coordinator:
enabled: true
interval: 30s
path: /metrics
port: http
blockchainNode:
enabled: true
interval: 30s
path: /metrics
port: http
walletDaemon:
enabled: true
interval: 30s
path: /metrics
port: http
# Alert rules
alertRules:
enabled: true
groups:
- name: aitbc.rules
rules:
- alert: HighErrorRate
expr: rate(marketplace_errors_total[5m]) / rate(marketplace_requests_total[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate detected"
description: "Error rate is above 10% for 5 minutes"
- alert: CoordinatorDown
expr: up{job="coordinator"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Coordinator is down"
description: "Coordinator API has been down for more than 1 minute"