security: encrypt ConfigMap with SOPS, remove plaintext secrets
- ConfigMap values encrypted with age/SOPS (YubiKey-gated) - Removed secrets.env, secret.yaml, poimen-application.yaml (plaintext) - Worker needs no secrets — uses local LLM via ClusterIP, JWT from activity input - Decrypt: sops-unlock && sops --decrypt k8s/configmap.enc.yaml
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
creation_rules:
|
||||
- path_regex: k8s/.*\.enc\.ya?ml
|
||||
age: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
|
||||
@@ -0,0 +1,27 @@
|
||||
apiVersion: ENC[AES256_GCM,data:IxE=,iv:nh5IQck87AsRYnvxMLxn2rZFBUTHcc9obvsYoHnvC6g=,tag:ink4m5kv1NqX2TeRrpCaqg==,type:str]
|
||||
kind: ENC[AES256_GCM,data:2U5oBCqywkR0,iv:EVBlp6G1SlznoP7Zx9Y0mQOnxbzcosP28+UbJUWFjHM=,tag:v1lot4q06QBqU2M5q2RJ/g==,type:str]
|
||||
metadata:
|
||||
name: ENC[AES256_GCM,data:pFOLyxGAW7/KqUqijkPM1mGYaKo=,iv:jttNW2Ef0itpuWupOQkGEiFaanpcd/HuvfLg9l2tSEg=,tag:6ijOdYdjnUaCOf29z8vkxg==,type:str]
|
||||
namespace: ENC[AES256_GCM,data:FSZFmVEp,iv:liL0yGuEbjZjf6egh8KS9zi6H3AEF9MvynGBO+49GW0=,tag:4iJNECe8vsXqzQBV/Q7c0g==,type:str]
|
||||
data:
|
||||
#ENC[AES256_GCM,data:d+Z/w/n69JI5,iv:/w2xIrmNXg53kz+tfebT0P6rD3TC909YTDFXXUc/yHo=,tag:ao4yA2lW2a1/ELT8ZIBOgw==,type:comment]
|
||||
TEMPORAL_NAMESPACE: ENC[AES256_GCM,data:X0D/DVfVgzhFh+oB8nU=,iv:biiLtXRALsUMNIW4qGj8JOc9C1RJK93pOw74ZmymM/g=,tag:tW5+AwUGj8jzvxPSZAf41A==,type:str]
|
||||
TEMPORAL_HOSTPORT: ENC[AES256_GCM,data:OK8Cu7nA2fKhXmBko8MORoD6hvJBMFfE/dTBZ99ac420xjPBWjhrz2XR3WRiWhUIIQ==,iv:HKDNRT/30HNzN3pX91e63i/ZeIUUYkycknjjKTFlVwo=,tag:OjPle4p+nV4ZQYN/yuUFEw==,type:str]
|
||||
#ENC[AES256_GCM,data:1jnEt80ScfSqnCv9Rf/XLAlYTfuZVxoRdV7Sx9EgIGmzvAM=,iv:3NKsB9ZytMxuMipSLApKX7hj2jQG+2e2Hp8+ofFin9k=,tag:s4eRatHTQJa37xBO5UYI5Q==,type:comment]
|
||||
LOCAL_LLM_BASE_URL: ENC[AES256_GCM,data:rTWBhNovjp5WdFI2jMaMRRg41uhh1dOFqVnplmMADiubu/FGXCvUPD2d9IuU,iv:1RdS5UfD6aOXnaEfddRd4PxJ1+K7AwKlMUYxzUQxVJ4=,tag:K0g2KDCFLOtxDFkHxoRbMw==,type:str]
|
||||
MEMORY_SERVICE_URL: ENC[AES256_GCM,data:CarE5ENFtDvBWVzB7qTZQqoL0OsN2uAO9aoPXu1LPWtdoSQ2rQsVs2scTA08jaWLD+o=,iv:e7M/aibmYdSk4NbY6fYw0UPjd/VQvWJ1tC8n0r2y6r0=,tag:bWuCTBRfKkaB2fauPR51Fg==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBV0RJU2wzN1Bib0lZRlFl
|
||||
K2UzSVBNUjNHUVVFeUFEWTJBUHNZT0l3RWprCmp2cE1HM2xOWnVjVGlqdWI0SndG
|
||||
Q1VOaklVdlg4eGp6V29uVDVJRUtmKzgKLS0tIGp3MWJMdmdyZmRnWmxOWEhVZUhm
|
||||
Rm5DNzBhUWt0SVBDK09mSWw2SHVRTWMKLS6Cz2nhz1RSoV+VUvFw9EsjlWbE2nEk
|
||||
4P1FdNgr+v1MTNczKZGzh9HbTAmYxCRgVBszXR5ov2JfukaZAWb9mg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
|
||||
lastmodified: "2026-09-06T12:56:33Z"
|
||||
mac: ENC[AES256_GCM,data:Ra89XdYHoJV+uFBlUMdw+I36UQfhM+r0Q4WjI3V/A7jBY2t00I0xSP+KRKPXlAA18HXpLCc5VkWklPMU4gfyYied1bPuFw6yLvvuup/ev4UAg/LofThKjtuRfXPy82Ltvro6R+ilWzJ8pRtgtk+jC4xkkMsUOACJMVwgn979D7M=,iv:UWR+CqXAreW/fx3tt1kJsOKYZkrAkxLXlU5QVy5p3gE=,tag:3t9c6631D4XrDmkR6Iv/4Q==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.13.2
|
||||
@@ -1,10 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: poimen-config
|
||||
namespace: poimen
|
||||
data:
|
||||
TEMPORAL_NAMESPACE: "poimen-harness"
|
||||
TEMPORAL_HOSTPORT: "temporal-frontend.temporal:7233"
|
||||
LOCAL_LLM_BASE_URL: "http://api-gateway.api:8080"
|
||||
POIMEN_MEMORY_URL: "http://poimen-memory.poimen.svc.cluster.local:8080"
|
||||
@@ -1,283 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: poimen
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: poimen-registry
|
||||
namespace: poimen
|
||||
type: kubernetes.io/dockercfg
|
||||
data:
|
||||
.dockercfg: eyJmb3JnZWpvLnJpb3RwaWFvLmNvbSI6eyJhdXRoIjoiYmFzZTY0LWVuY29kZWQtY3JlZGVudGlhbHMifX0=
|
||||
---
|
||||
# Poimen Memory Service
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: poimen-memory
|
||||
namespace: poimen
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: poimen-memory
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: poimen-memory
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: poimen-registry
|
||||
containers:
|
||||
- name: memory
|
||||
image: forgejo.riotpiao.com/rock/poimen-memory:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-db-credentials
|
||||
key: memory-url
|
||||
- name: REDIS_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: redis-url
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-secrets
|
||||
key: jwt-secret
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 8000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: poimen-memory
|
||||
namespace: poimen
|
||||
spec:
|
||||
selector:
|
||||
app: poimen-memory
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
type: ClusterIP
|
||||
---
|
||||
# Poimen Workflows Service
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: poimen-workflows
|
||||
namespace: poimen
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: poimen-workflows
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: poimen-workflows
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: poimen-registry
|
||||
containers:
|
||||
- name: workflows-server
|
||||
image: forgejo.riotpiao.com/rock/poimen-workflows:latest
|
||||
imagePullPolicy: Always
|
||||
command: ["/app/workflows", "server"]
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-db-credentials
|
||||
key: workflows-url
|
||||
- name: TEMPORAL_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: temporal-host
|
||||
- name: MEMORY_SERVICE_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: memory-service-url
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-secrets
|
||||
key: jwt-secret
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
- name: workflows-worker
|
||||
image: forgejo.riotpiao.com/rock/poimen-workflows:latest
|
||||
imagePullPolicy: Always
|
||||
command: ["/app/workflows", "worker"]
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-db-credentials
|
||||
key: workflows-url
|
||||
- name: TEMPORAL_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: temporal-host
|
||||
- name: MEMORY_SERVICE_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: memory-service-url
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: poimen-workflows
|
||||
namespace: poimen
|
||||
spec:
|
||||
selector:
|
||||
app: poimen-workflows
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
type: ClusterIP
|
||||
---
|
||||
# Poimen Frontend Service
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: poimen-frontend
|
||||
namespace: poimen
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: poimen-frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: poimen-frontend
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: poimen-registry
|
||||
containers:
|
||||
- name: frontend
|
||||
image: forgejo.riotpiao.com/rock/poimen-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: NEXT_PUBLIC_WORKFLOWS_API
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: workflows-api-url
|
||||
- name: NEXT_PUBLIC_MEMORY_API
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: memory-api-url
|
||||
- name: NEXT_PUBLIC_AUTH_URL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: poimen-config
|
||||
key: auth-url
|
||||
- name: OAUTH_CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-secrets
|
||||
key: oauth-client-id
|
||||
- name: OAUTH_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: poimen-secrets
|
||||
key: oauth-client-secret
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 3000
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: poimen-frontend
|
||||
namespace: poimen
|
||||
spec:
|
||||
selector:
|
||||
app: poimen-frontend
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 3000
|
||||
type: LoadBalancer
|
||||
---
|
||||
# ConfigMap for shared configuration
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: poimen-config
|
||||
namespace: poimen
|
||||
data:
|
||||
temporal-host: "temporal:7233"
|
||||
redis-url: "redis://redis:6379"
|
||||
workflows-api-url: "http://poimen-workflows:8080"
|
||||
memory-api-url: "http://poimen-memory:8000"
|
||||
auth-url: "https://auth.riotpiao.com"
|
||||
memory-service-url: "http://poimen-memory:8000"
|
||||
---
|
||||
# Secrets placeholder - should be created separately
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: poimen-db-credentials
|
||||
namespace: poimen
|
||||
type: Opaque
|
||||
stringData:
|
||||
memory-url: "postgresql://user:pass@postgres:5432/poimen_memory"
|
||||
workflows-url: "postgresql://user:pass@postgres:5432/poimen_workflows"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: poimen-secrets
|
||||
namespace: poimen
|
||||
type: Opaque
|
||||
stringData:
|
||||
jwt-secret: "your-jwt-secret-here"
|
||||
oauth-client-id: "your-oauth-client-id"
|
||||
oauth-client-secret: "your-oauth-client-secret"
|
||||
@@ -1,12 +0,0 @@
|
||||
# NOTE: This file is for reference only.
|
||||
# Kustomize will auto-generate secrets from secrets.env
|
||||
# See kustomization.yaml for details
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: poimen-secrets
|
||||
namespace: poimen
|
||||
type: Opaque
|
||||
stringData:
|
||||
ANTHROPIC_API_KEY: "" # Generated from secrets.env by Kustomize
|
||||
@@ -1 +0,0 @@
|
||||
ANTHROPIC_API_KEY=YOUR_ANTHROPIC_API_KEY_HERE
|
||||
Reference in New Issue
Block a user