Files
vm-core/docs/VAULTMESH-DEPLOYMENT-MANIFESTS.md
2025-12-27 00:10:32 +00:00

33 KiB

VAULTMESH-DEPLOYMENT-MANIFESTS.md

Production Infrastructure for the Civilization Ledger

A system that cannot be deployed is a system that cannot exist.

This document provides complete Kubernetes, Docker, and infrastructure-as-code configurations for deploying VaultMesh in production environments.


1. Deployment Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                           KUBERNETES CLUSTER                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                      INGRESS LAYER                               │   │
│  │  • Traefik / NGINX Ingress                                       │   │
│  │  • TLS termination (cert-manager)                                │   │
│  │  • Rate limiting                                                 │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                    │                                    │
│          ┌─────────────────────────┼─────────────────────────┐         │
│          │                         │                         │         │
│          ▼                         ▼                         ▼         │
│  ┌───────────────┐       ┌───────────────┐       ┌───────────────┐    │
│  │    PORTAL     │       │   GUARDIAN    │       │    ORACLE     │    │
│  │   (Rust)      │       │   (Rust)      │       │   (Python)    │    │
│  │               │       │               │       │               │    │
│  │ • HTTP API    │       │ • Anchor      │       │ • MCP Server  │    │
│  │ • WebSocket   │       │ • ProofChain  │       │ • LLM Client  │    │
│  │ • Auth        │       │ • Sentinel    │       │ • Corpus      │    │
│  └───────┬───────┘       └───────┬───────┘       └───────┬───────┘    │
│          │                       │                       │             │
│          └───────────────────────┼───────────────────────┘             │
│                                  │                                      │
│                                  ▼                                      │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                      DATA LAYER                                  │   │
│  │                                                                  │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │   │
│  │  │ PostgreSQL  │  │    Redis    │  │   MinIO     │              │   │
│  │  │ (receipts)  │  │  (cache)    │  │ (artifacts) │              │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘              │   │
│  │                                                                  │   │
│  │  ┌─────────────────────────────────────────────────────────┐    │   │
│  │  │              PERSISTENT VOLUMES                          │    │   │
│  │  │  • receipts/    (JSONL files)                           │    │   │
│  │  │  • cases/       (artifacts)                              │    │   │
│  │  │  • corpus/      (Oracle documents)                       │    │   │
│  │  └─────────────────────────────────────────────────────────┘    │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                    OBSERVABILITY LAYER                           │   │
│  │  • Prometheus (metrics)                                          │   │
│  │  • Loki (logs)                                                   │   │
│  │  • Tempo (traces)                                                │   │
│  │  • Grafana (dashboards)                                          │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

2. Namespace and RBAC

2.1 Namespace

# kubernetes/base/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: vaultmesh
  labels:
    app.kubernetes.io/name: vaultmesh
    app.kubernetes.io/part-of: civilization-ledger
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

2.2 Service Accounts

# kubernetes/base/rbac.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vaultmesh-portal
  namespace: vaultmesh
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vaultmesh-guardian
  namespace: vaultmesh
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vaultmesh-oracle
  namespace: vaultmesh
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: vaultmesh-guardian-role
  namespace: vaultmesh
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]
    resourceNames: ["guardian-anchor-keys", "guardian-config"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch", "update"]
    resourceNames: ["vaultmesh-roots", "guardian-state"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: vaultmesh-guardian-binding
  namespace: vaultmesh
subjects:
  - kind: ServiceAccount
    name: vaultmesh-guardian
    namespace: vaultmesh
roleRef:
  kind: Role
  name: vaultmesh-guardian-role
  apiGroup: rbac.authorization.k8s.io

3. Core Services

3.1 Portal Deployment

# kubernetes/base/portal/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vaultmesh-portal
  namespace: vaultmesh
  labels:
    app.kubernetes.io/name: portal
    app.kubernetes.io/component: api
    app.kubernetes.io/part-of: vaultmesh
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: portal
  template:
    metadata:
      labels:
        app.kubernetes.io/name: portal
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: vaultmesh-portal
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: portal
          image: ghcr.io/vaultmesh/portal:v0.1.0
          imagePullPolicy: IfNotPresent
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
            - name: metrics
              containerPort: 9090
              protocol: TCP
          env:
            - name: RUST_LOG
              value: "info,vaultmesh=debug"
            - name: VAULTMESH_CONFIG
              value: "/config/portal.toml"
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: vaultmesh-db-credentials
                  key: portal-url
            - name: REDIS_URL
              valueFrom:
                secretKeyRef:
                  name: vaultmesh-redis-credentials
                  key: url
          volumeMounts:
            - name: config
              mountPath: /config
              readOnly: true
            - name: receipts
              mountPath: /data/receipts
            - name: tmp
              mountPath: /tmp
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 1000m
              memory: 1Gi
          livenessProbe:
            httpGet:
              path: /health/live
              port: http
            initialDelaySeconds: 10
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health/ready
              port: http
            initialDelaySeconds: 5
            periodSeconds: 5
      volumes:
        - name: config
          configMap:
            name: vaultmesh-portal-config
        - name: receipts
          persistentVolumeClaim:
            claimName: vaultmesh-receipts
        - name: tmp
          emptyDir: {}
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchLabels:
                    app.kubernetes.io/name: portal
                topologyKey: kubernetes.io/hostname
---
apiVersion: v1
kind: Service
metadata:
  name: vaultmesh-portal
  namespace: vaultmesh
spec:
  selector:
    app.kubernetes.io/name: portal
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: metrics
      port: 9090
      targetPort: metrics
  type: ClusterIP

3.2 Guardian Deployment

# kubernetes/base/guardian/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vaultmesh-guardian
  namespace: vaultmesh
  labels:
    app.kubernetes.io/name: guardian
    app.kubernetes.io/component: anchor
    app.kubernetes.io/part-of: vaultmesh
spec:
  replicas: 1  # Single instance for anchor coordination
  strategy:
    type: Recreate  # Ensure only one instance runs at a time
  selector:
    matchLabels:
      app.kubernetes.io/name: guardian
  template:
    metadata:
      labels:
        app.kubernetes.io/name: guardian
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
    spec:
      serviceAccountName: vaultmesh-guardian
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: guardian
          image: ghcr.io/vaultmesh/guardian:v0.1.0
          imagePullPolicy: IfNotPresent
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          ports:
            - name: http
              containerPort: 8081
              protocol: TCP
            - name: metrics
              containerPort: 9090
              protocol: TCP
          env:
            - name: RUST_LOG
              value: "info,guardian=debug"
            - name: GUARDIAN_CONFIG
              value: "/config/guardian.toml"
            - name: GUARDIAN_ANCHOR_KEY
              valueFrom:
                secretKeyRef:
                  name: guardian-anchor-keys
                  key: private-key
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: vaultmesh-db-credentials
                  key: guardian-url
          volumeMounts:
            - name: config
              mountPath: /config
              readOnly: true
            - name: receipts
              mountPath: /data/receipts
            - name: guardian-state
              mountPath: /data/guardian
            - name: tmp
              mountPath: /tmp
          resources:
            requests:
              cpu: 200m
              memory: 512Mi
            limits:
              cpu: 2000m
              memory: 2Gi
          livenessProbe:
            httpGet:
              path: /health/live
              port: http
            initialDelaySeconds: 15
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health/ready
              port: http
            initialDelaySeconds: 10
            periodSeconds: 5
      volumes:
        - name: config
          configMap:
            name: vaultmesh-guardian-config
        - name: receipts
          persistentVolumeClaim:
            claimName: vaultmesh-receipts
        - name: guardian-state
          persistentVolumeClaim:
            claimName: vaultmesh-guardian-state
        - name: tmp
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: vaultmesh-guardian
  namespace: vaultmesh
spec:
  selector:
    app.kubernetes.io/name: guardian
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: metrics
      port: 9090
      targetPort: metrics
  type: ClusterIP

3.3 Oracle Deployment

# kubernetes/base/oracle/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vaultmesh-oracle
  namespace: vaultmesh
  labels:
    app.kubernetes.io/name: oracle
    app.kubernetes.io/component: compliance
    app.kubernetes.io/part-of: vaultmesh
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: oracle
  template:
    metadata:
      labels:
        app.kubernetes.io/name: oracle
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9090"
    spec:
      serviceAccountName: vaultmesh-oracle
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: oracle
          image: ghcr.io/vaultmesh/oracle:v0.1.0
          imagePullPolicy: IfNotPresent
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          ports:
            - name: http
              containerPort: 8082
              protocol: TCP
            - name: mcp
              containerPort: 8083
              protocol: TCP
            - name: metrics
              containerPort: 9090
              protocol: TCP
          env:
            - name: ORACLE_CONFIG
              value: "/config/oracle.toml"
            - name: OPENAI_API_KEY
              valueFrom:
                secretKeyRef:
                  name: oracle-llm-credentials
                  key: openai-key
            - name: ANTHROPIC_API_KEY
              valueFrom:
                secretKeyRef:
                  name: oracle-llm-credentials
                  key: anthropic-key
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: vaultmesh-db-credentials
                  key: oracle-url
            - name: VAULTMESH_RECEIPT_ENDPOINT
              value: "http://vaultmesh-portal/api/receipts"
          volumeMounts:
            - name: config
              mountPath: /config
              readOnly: true
            - name: corpus
              mountPath: /data/corpus
              readOnly: true
            - name: cache
              mountPath: /data/cache
            - name: tmp
              mountPath: /tmp
          resources:
            requests:
              cpu: 200m
              memory: 512Mi
            limits:
              cpu: 2000m
              memory: 4Gi
          livenessProbe:
            httpGet:
              path: /health/live
              port: http
            initialDelaySeconds: 20
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /health/ready
              port: http
            initialDelaySeconds: 15
            periodSeconds: 5
      volumes:
        - name: config
          configMap:
            name: vaultmesh-oracle-config
        - name: corpus
          persistentVolumeClaim:
            claimName: vaultmesh-corpus
        - name: cache
          emptyDir:
            sizeLimit: 1Gi
        - name: tmp
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: vaultmesh-oracle
  namespace: vaultmesh
spec:
  selector:
    app.kubernetes.io/name: oracle
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: mcp
      port: 8083
      targetPort: mcp
    - name: metrics
      port: 9090
      targetPort: metrics
  type: ClusterIP

4. Data Layer

4.1 PostgreSQL (via CloudNativePG)

# kubernetes/base/database/postgresql.yaml
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: vaultmesh-db
  namespace: vaultmesh
spec:
  instances: 3

  postgresql:
    parameters:
      max_connections: "200"
      shared_buffers: "256MB"
      effective_cache_size: "768MB"
      maintenance_work_mem: "128MB"
      checkpoint_completion_target: "0.9"
      wal_buffers: "16MB"
      default_statistics_target: "100"
      random_page_cost: "1.1"
      effective_io_concurrency: "200"
      work_mem: "6553kB"
      min_wal_size: "1GB"
      max_wal_size: "4GB"

  storage:
    size: 50Gi
    storageClass: fast-ssd

  backup:
    barmanObjectStore:
      destinationPath: "s3://vaultmesh-backups/postgresql"
      s3Credentials:
        accessKeyId:
          name: vaultmesh-backup-credentials
          key: access-key
        secretAccessKey:
          name: vaultmesh-backup-credentials
          key: secret-key
      wal:
        compression: gzip
        maxParallel: 8
    retentionPolicy: "30d"

  monitoring:
    enablePodMonitor: true

  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2000m
      memory: 4Gi

---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
  name: vaultmesh-db-daily-backup
  namespace: vaultmesh
spec:
  schedule: "0 2 * * *"
  backupOwnerReference: self
  cluster:
    name: vaultmesh-db

4.2 Redis

# kubernetes/base/cache/redis.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: vaultmesh-redis
  namespace: vaultmesh
spec:
  serviceName: vaultmesh-redis
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: redis
  template:
    metadata:
      labels:
        app.kubernetes.io/name: redis
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      containers:
        - name: redis
          image: redis:7-alpine
          ports:
            - containerPort: 6379
          command:
            - redis-server
            - /config/redis.conf
          volumeMounts:
            - name: config
              mountPath: /config
            - name: data
              mountPath: /data
          resources:
            requests:
              cpu: 100m
              memory: 256Mi
            limits:
              cpu: 500m
              memory: 1Gi
      volumes:
        - name: config
          configMap:
            name: vaultmesh-redis-config
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: fast-ssd
        resources:
          requests:
            storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  name: vaultmesh-redis
  namespace: vaultmesh
spec:
  selector:
    app.kubernetes.io/name: redis
  ports:
    - port: 6379
      targetPort: 6379
  type: ClusterIP

4.3 Persistent Volumes

# kubernetes/base/storage/persistent-volumes.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vaultmesh-receipts
  namespace: vaultmesh
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-csi
  resources:
    requests:
      storage: 100Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vaultmesh-guardian-state
  namespace: vaultmesh
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vaultmesh-corpus
  namespace: vaultmesh
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-csi
  resources:
    requests:
      storage: 50Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vaultmesh-cases
  namespace: vaultmesh
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: nfs-csi
  resources:
    requests:
      storage: 200Gi

5. Configuration

5.1 Portal Config

# kubernetes/base/portal/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: vaultmesh-portal-config
  namespace: vaultmesh
data:
  portal.toml: |
    [server]
    bind = "0.0.0.0:8080"
    metrics_bind = "0.0.0.0:9090"

    [database]
    max_connections = 20
    min_connections = 5

    [receipts]
    base_path = "/data/receipts"

    [scrolls]
    enabled = [
      "Drills",
      "Compliance",
      "Guardian",
      "Treasury",
      "Mesh",
      "OffSec",
      "Identity",
      "Observability",
      "Automation",
      "PsiField",
      "Federation",
      "Governance",
    ]

    [auth]
    jwt_issuer = "vaultmesh-portal"
    session_ttl_hours = 24

    [guardian]
    endpoint = "http://vaultmesh-guardian"

    [oracle]
    endpoint = "http://vaultmesh-oracle"

5.2 Guardian Config

# kubernetes/base/guardian/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: vaultmesh-guardian-config
  namespace: vaultmesh
data:
  guardian.toml: |
    [server]
    bind = "0.0.0.0:8081"
    metrics_bind = "0.0.0.0:9090"

    [proofchain]
    receipts_path = "/data/receipts"
    roots_path = "/data/receipts"

    [anchor]
    # Primary anchor backend
    primary = "ethereum"

    # Anchor schedule
    interval_seconds = 3600  # Every hour
    min_receipts_threshold = 10

    # Ethereum configuration
    [anchor.ethereum]
    rpc_url = "https://mainnet.infura.io/v3/${INFURA_PROJECT_ID}"
    contract_address = "0x..."
    chain_id = 1
    gas_limit = 100000

    # OpenTimestamps backup
    [anchor.ots]
    enabled = true
    calendar_urls = [
      "https://a.pool.opentimestamps.org",
      "https://b.pool.opentimestamps.org",
    ]

    # Bitcoin anchor (optional, for high-value anchors)
    [anchor.bitcoin]
    enabled = false
    rpc_url = "http://bitcoin-node:8332"

    [sentinel]
    enabled = true
    alert_webhook = "http://alertmanager:9093/api/v2/alerts"

    [state]
    path = "/data/guardian/state.json"

5.3 Oracle Config

# kubernetes/base/oracle/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: vaultmesh-oracle-config
  namespace: vaultmesh
data:
  oracle.toml: |
    [server]
    http_bind = "0.0.0.0:8082"
    mcp_bind = "0.0.0.0:8083"
    metrics_bind = "0.0.0.0:9090"

    [corpus]
    path = "/data/corpus"
    index_path = "/data/cache/index"
    supported_formats = ["docx", "pdf", "md", "txt"]

    [llm]
    # Primary model
    primary_provider = "anthropic"
    primary_model = "claude-sonnet-4-20250514"

    # Fallback model
    fallback_provider = "openai"
    fallback_model = "gpt-4o"

    # Settings
    temperature = 0.1
    max_tokens = 4096
    timeout_seconds = 60

    [prompts]
    version = "vm_oracle_answer_v1"

    [receipts]
    endpoint = "http://vaultmesh-portal/api/receipts/oracle"

    [cache]
    enabled = true
    path = "/data/cache/answers"
    ttl_hours = 24

6. Ingress and TLS

6.1 Ingress

# kubernetes/base/ingress/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: vaultmesh-ingress
  namespace: vaultmesh
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
    nginx.ingress.kubernetes.io/rate-limit: "100"
    nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - portal.vaultmesh.io
        - guardian.vaultmesh.io
        - oracle.vaultmesh.io
        - federation.vaultmesh.io
      secretName: vaultmesh-tls
  rules:
    - host: portal.vaultmesh.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: vaultmesh-portal
                port:
                  name: http
    - host: guardian.vaultmesh.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: vaultmesh-guardian
                port:
                  name: http
    - host: oracle.vaultmesh.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: vaultmesh-oracle
                port:
                  name: http
    - host: federation.vaultmesh.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: vaultmesh-portal
                port:
                  name: http

6.2 Certificate

# kubernetes/base/ingress/certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: vaultmesh-tls
  namespace: vaultmesh
spec:
  secretName: vaultmesh-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - portal.vaultmesh.io
    - guardian.vaultmesh.io
    - oracle.vaultmesh.io
    - federation.vaultmesh.io

7. Secrets Management

7.1 Sealed Secrets

# kubernetes/base/secrets/sealed-secrets.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: vaultmesh-db-credentials
  namespace: vaultmesh
spec:
  encryptedData:
    portal-url: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
    guardian-url: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
    oracle-url: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
  template:
    metadata:
      name: vaultmesh-db-credentials
      namespace: vaultmesh
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: guardian-anchor-keys
  namespace: vaultmesh
spec:
  encryptedData:
    private-key: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
  template:
    metadata:
      name: guardian-anchor-keys
      namespace: vaultmesh
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: oracle-llm-credentials
  namespace: vaultmesh
spec:
  encryptedData:
    openai-key: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
    anthropic-key: AgBy3i4OJSWK+PiTySYZZA9rO53sFO...
  template:
    metadata:
      name: oracle-llm-credentials
      namespace: vaultmesh

8. Kustomization

8.1 Base Kustomization

# kubernetes/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: vaultmesh

resources:
  - namespace.yaml
  - rbac.yaml
  - portal/deployment.yaml
  - portal/configmap.yaml
  - guardian/deployment.yaml
  - guardian/configmap.yaml
  - oracle/deployment.yaml
  - oracle/configmap.yaml
  - database/postgresql.yaml
  - cache/redis.yaml
  - storage/persistent-volumes.yaml
  - ingress/ingress.yaml
  - ingress/certificate.yaml
  - secrets/sealed-secrets.yaml

commonLabels:
  app.kubernetes.io/part-of: vaultmesh
  app.kubernetes.io/managed-by: kustomize

8.2 Production Overlay

# kubernetes/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: vaultmesh

resources:
  - ../../base

patches:
  - path: portal-resources.yaml
  - path: guardian-resources.yaml
  - path: oracle-resources.yaml

configMapGenerator:
  - name: vaultmesh-portal-config
    behavior: merge
    files:
      - portal.toml=configs/portal-prod.toml
  - name: vaultmesh-guardian-config
    behavior: merge
    files:
      - guardian.toml=configs/guardian-prod.toml

replicas:
  - name: vaultmesh-portal
    count: 3
  - name: vaultmesh-oracle
    count: 3
# kubernetes/overlays/production/portal-resources.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vaultmesh-portal
spec:
  template:
    spec:
      containers:
        - name: portal
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              cpu: 2000m
              memory: 4Gi

9. Docker Compose (Development)

# docker-compose.yaml
version: "3.9"

services:
  portal:
    build:
      context: .
      dockerfile: docker/portal/Dockerfile
    ports:
      - "8080:8080"
      - "9090:9090"
    environment:
      - RUST_LOG=info,vaultmesh=debug
      - VAULTMESH_CONFIG=/config/portal.toml
      - DATABASE_URL=postgresql://vaultmesh:vaultmesh@postgres:5432/vaultmesh
      - REDIS_URL=redis://redis:6379
    volumes:
      - ./config/portal.toml:/config/portal.toml:ro
      - receipts:/data/receipts
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
      interval: 10s
      timeout: 5s
      retries: 5

  guardian:
    build:
      context: .
      dockerfile: docker/guardian/Dockerfile
    ports:
      - "8081:8081"
    environment:
      - RUST_LOG=info,guardian=debug
      - GUARDIAN_CONFIG=/config/guardian.toml
      - DATABASE_URL=postgresql://vaultmesh:vaultmesh@postgres:5432/vaultmesh
    volumes:
      - ./config/guardian.toml:/config/guardian.toml:ro
      - receipts:/data/receipts
      - guardian-state:/data/guardian
    depends_on:
      portal:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8081/health/live"]
      interval: 10s
      timeout: 5s
      retries: 5

  oracle:
    build:
      context: .
      dockerfile: docker/oracle/Dockerfile
    ports:
      - "8082:8082"
      - "8083:8083"
    environment:
      - ORACLE_CONFIG=/config/oracle.toml
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - VAULTMESH_RECEIPT_ENDPOINT=http://portal:8080/api/receipts
    volumes:
      - ./config/oracle.toml:/config/oracle.toml:ro
      - ./corpus:/data/corpus:ro
    depends_on:
      portal:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8082/health/live"]
      interval: 10s
      timeout: 5s
      retries: 5

  postgres:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=vaultmesh
      - POSTGRES_PASSWORD=vaultmesh
      - POSTGRES_DB=vaultmesh
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U vaultmesh"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes

  prometheus:
    image: prom/prometheus:v2.47.0
    ports:
      - "9091:9090"
    volumes:
      - ./config/prometheus.yaml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.enable-lifecycle'

  grafana:
    image: grafana/grafana:10.1.0
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - ./config/grafana/provisioning:/etc/grafana/provisioning:ro
      - grafana-data:/var/lib/grafana
    depends_on:
      - prometheus

volumes:
  receipts:
  guardian-state:
  postgres-data:
  redis-data:
  prometheus-data:
  grafana-data:

networks:
  default:
    name: vaultmesh