Initial commit: Elydora Open Source — self-hosted audit platform for AI agents

Full self-hosted port of the Elydora tamper-evident audit protocol:
- Hono API server with PostgreSQL, Redis, MinIO adapters
- Ed25519 signed operations, chain hashing, Merkle epoch rollups
- PBKDF2 password hashing, HMAC-SHA256 JWT, 5-role RBAC
- Next.js management console
- Node.js, Python, and Go SDKs
- Docker Compose for local deployment
- Helm chart for Kubernetes
- Comprehensive security hardening and audit fixes applied

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 4.6 committed 2026-03-02 13:41:42 -05:00
1 parent 15547a8c35
commit e390e68594
207 files changed
+32790 -63

No files matched your search

+74
View File
@@ -0,0 +1,74 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "elydora.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "elydora.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 }}
{{/*
Chart label.
*/}}
{{- define "elydora.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels.
*/}}
{{- define "elydora.labels" -}}
helm.sh/chart: {{ include "elydora.chart" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Selector labels.
*/}}
{{- define "elydora.selectorLabels" -}}
app.kubernetes.io/name: {{ include "elydora.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Namespace.
*/}}
{{- define "elydora.namespace" -}}
{{- .Values.namespace | default "elydora" }}
{{- end }}
{{/*
Database URL.
*/}}
{{- define "elydora.databaseUrl" -}}
postgresql://{{ .Values.postgres.user }}:{{ .Values.postgres.password }}@{{ .Values.postgres.host }}:{{ .Values.postgres.port }}/{{ .Values.postgres.database }}
{{- end }}
{{/*
Redis URL.
*/}}
{{- define "elydora.redisUrl" -}}
redis://{{ .Values.redis.host }}:{{ .Values.redis.port }}
{{- end }}
{{/*
MinIO endpoint.
*/}}
{{- define "elydora.minioEndpoint" -}}
http://{{ .Values.minio.host }}:{{ .Values.minio.port }}
{{- end }}
@@ -0,0 +1,43 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: api
spec:
replicas: {{ .Values.replicaCount.api }}
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: "{{ .Values.image.api.repository }}:{{ .Values.image.api.tag }}"
imagePullPolicy: {{ .Values.image.api.pullPolicy }}
ports:
- containerPort: 8787
envFrom:
- configMapRef:
name: elydora-config
- secretRef:
name: elydora-secret
resources:
{{- toYaml .Values.resources.api | nindent 12 }}
readinessProbe:
httpGet:
path: /health
port: 8787
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8787
initialDelaySeconds: 20
periodSeconds: 20
+14
View File
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: api
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: api
spec:
ports:
- port: 8787
targetPort: 8787
selector:
app: api
+17
View File
@@ -0,0 +1,17 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: elydora-config
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
data:
PORT: {{ .Values.api.port | quote }}
ENVIRONMENT: {{ .Values.api.environment | quote }}
REDIS_URL: {{ include "elydora.redisUrl" . | quote }}
MINIO_ENDPOINT: {{ include "elydora.minioEndpoint" . | quote }}
MINIO_BUCKET: {{ .Values.minio.bucket | quote }}
MINIO_ACCESS_KEY: {{ .Values.minio.rootUser | quote }}
ALLOWED_ORIGINS: {{ .Values.api.allowedOrigins | quote }}
TSA_URL: {{ .Values.api.tsaUrl | quote }}
NEXT_PUBLIC_API_BASE_URL: {{ .Values.console.apiBaseUrl | quote }}
@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: console
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: console
spec:
replicas: {{ .Values.replicaCount.console }}
selector:
matchLabels:
app: console
template:
metadata:
labels:
app: console
spec:
containers:
- name: console
image: "{{ .Values.image.console.repository }}:{{ .Values.image.console.tag }}"
imagePullPolicy: {{ .Values.image.console.pullPolicy }}
ports:
- containerPort: 3000
env:
- name: NEXT_PUBLIC_API_BASE_URL
valueFrom:
configMapKeyRef:
name: elydora-config
key: NEXT_PUBLIC_API_BASE_URL
resources:
{{- toYaml .Values.resources.console | nindent 12 }}
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 20
periodSeconds: 20
@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: console
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: console
spec:
ports:
- port: 3000
targetPort: 3000
selector:
app: console
+51
View File
@@ -0,0 +1,51 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: elydora-ingress
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
- host: {{ .Values.ingress.api.host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api
port:
number: 8787
- host: {{ .Values.ingress.console.host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: console
port:
number: 3000
{{- if or .Values.ingress.api.tls .Values.ingress.console.tls }}
tls:
{{- if .Values.ingress.api.tls }}
- hosts:
- {{ .Values.ingress.api.host }}
secretName: {{ .Values.ingress.api.tlsSecret }}
{{- end }}
{{- if .Values.ingress.console.tls }}
- hosts:
- {{ .Values.ingress.console.host }}
secretName: {{ .Values.ingress.console.tlsSecret }}
{{- end }}
{{- end }}
{{- end }}
+25
View File
@@ -0,0 +1,25 @@
apiVersion: batch/v1
kind: Job
metadata:
name: db-migrate
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: db-migrate
image: "{{ .Values.image.api.repository }}:{{ .Values.image.api.tag }}"
imagePullPolicy: {{ .Values.image.api.pullPolicy }}
command: ["node", "dist/migrate.js"]
envFrom:
- configMapRef:
name: elydora-config
- secretRef:
name: elydora-secret
+18
View File
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: minio
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: minio
spec:
ports:
- port: 9000
targetPort: 9000
name: api
- port: 9001
targetPort: 9001
name: console
selector:
app: minio
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: minio
spec:
serviceName: minio
replicas: 1
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: minio/minio:latest
command: ["server", "/data", "--console-address", ":9001"]
ports:
- containerPort: 9000
name: api
- containerPort: 9001
name: console
env:
- name: MINIO_ROOT_USER
value: {{ .Values.minio.rootUser | quote }}
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: elydora-secret
key: MINIO_ROOT_PASSWORD
volumeMounts:
- name: minio-data
mountPath: /data
readinessProbe:
httpGet:
path: /minio/health/ready
port: 9000
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /minio/health/live
port: 9000
initialDelaySeconds: 20
periodSeconds: 20
volumeClaimTemplates:
- metadata:
name: minio-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: {{ .Values.minio.storage }}
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: postgres
spec:
ports:
- port: 5432
targetPort: 5432
selector:
app: postgres
clusterIP: None
@@ -0,0 +1,65 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: postgres
spec:
serviceName: postgres
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
value: {{ .Values.postgres.user | quote }}
- name: POSTGRES_DB
value: {{ .Values.postgres.database | quote }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: elydora-secret
key: POSTGRES_PASSWORD
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
readinessProbe:
exec:
command:
- pg_isready
- -U
- {{ .Values.postgres.user }}
- -d
- {{ .Values.postgres.database }}
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
exec:
command:
- pg_isready
- -U
- {{ .Values.postgres.user }}
- -d
- {{ .Values.postgres.database }}
initialDelaySeconds: 15
periodSeconds: 10
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: {{ .Values.postgres.storage }}
+15
View File
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: redis
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
clusterIP: None
@@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: redis
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
ports:
- containerPort: 6379
volumeMounts:
- name: redis-data
mountPath: /data
readinessProbe:
exec:
command: ["redis-cli", "ping"]
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
exec:
command: ["redis-cli", "ping"]
initialDelaySeconds: 15
periodSeconds: 10
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: {{ .Values.redis.storage }}
@@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: scheduler
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: scheduler
spec:
replicas: {{ .Values.replicaCount.scheduler }}
selector:
matchLabels:
app: scheduler
template:
metadata:
labels:
app: scheduler
spec:
containers:
- name: scheduler
image: "{{ .Values.image.api.repository }}:{{ .Values.image.api.tag }}"
imagePullPolicy: {{ .Values.image.api.pullPolicy }}
command: ["node", "dist/scheduler.js"]
envFrom:
- configMapRef:
name: elydora-config
- secretRef:
name: elydora-secret
resources:
{{- toYaml .Values.resources.scheduler | nindent 12 }}
+15
View File
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
name: elydora-secret
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
type: Opaque
stringData:
DATABASE_URL: {{ include "elydora.databaseUrl" . | quote }}
JWT_SECRET: {{ .Values.api.jwtSecret | quote }}
ELYDORA_SIGNING_KEY: {{ .Values.api.signingKey | quote }}
POSTGRES_PASSWORD: {{ .Values.postgres.password | quote }}
MINIO_SECRET_KEY: {{ .Values.minio.rootPassword | quote }}
MINIO_ROOT_PASSWORD: {{ .Values.minio.rootPassword | quote }}
@@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker
namespace: {{ include "elydora.namespace" . }}
labels:
{{- include "elydora.labels" . | nindent 4 }}
app: worker
spec:
replicas: {{ .Values.replicaCount.worker }}
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
spec:
containers:
- name: worker
image: "{{ .Values.image.api.repository }}:{{ .Values.image.api.tag }}"
imagePullPolicy: {{ .Values.image.api.pullPolicy }}
command: ["node", "dist/worker.js"]
envFrom:
- configMapRef:
name: elydora-config
- secretRef:
name: elydora-secret
resources:
{{- toYaml .Values.resources.worker | nindent 12 }}