Files
poimen-memory/k8s/app/opensearch-deployment.yaml
Story Crater Bot 56bee1915e chore: Archive completed task files (M0, M1, M3, M3.5, M4.1-2, M3.6.1)
Deleted 31 completed task files:
- M0.x: 8 tasks (cargo, domain types, recordsource, tokenizer, adapters, gate)
- M1.x: 8 tasks (llm-chat, standing-query, prompt template, parser, loop, log, e2e, gate)
- M3.x: 4 tasks (l2-synthesis, rerank, mem-query, gate)
- M3.5.x: 8 tasks (http-server, ingest, query, federation, skills, projects, rate-limiting, gate)
- M3.6.1: DocCorpusSource (heading-boundary chunking)
- M4.1-2: skill-draft, derived-filter

Updated INDEX.md:
- Removed M0 & M1 phase sections (archived in git history)
- Updated progress table: 65 active tasks (42 + 2🟡 + 21)
- Updated status: M0/M1 complete, M3/M3.5 gates passing, M4.1-2 done
- Noted M3.5.10 JWT auth implementation complete (awaiting image rollout)
- Cleaned up broken links to deleted task files

Total test count: 239 passing, 2 ignored (up from 196 at M3.4)
Ready for M4.3 gate composition, M5 post-training, M7 source connectors.
2026-08-27 20:25:05 -07:00

385 lines
10 KiB
YAML

---
# OpenSearch Security Config
apiVersion: v1
kind: ConfigMap
metadata:
name: opensearch-config
namespace: poimen
labels:
app: opensearch
data:
opensearch.yml: |
cluster.name: poimen-memory
node.name: ${HOSTNAME}
discovery.seed_hosts: "opensearch-0.opensearch,opensearch-1.opensearch"
cluster.initial_master_nodes: "opensearch-0,opensearch-1"
# Security Plugin Configuration
plugins:
security:
ssl:
transport:
pemcert_filepath: certs/node.pem
pemkey_filepath: certs/node-key.pem
pemtrustedcas_filepath: certs/root-ca.pem
enforce_hostname_verification: false
http:
enabled: true
pemcert_filepath: certs/node.pem
pemkey_filepath: certs/node-key.pem
pemtrustedcas_filepath: certs/root-ca.pem
# JWT Authentication Realm
authcz:
admin_dn:
- CN=admin,OU=admin,O=admin,L=admin,ST=admin,C=admin
authc:
realms:
jwt_realm:
type: jwt
order: 1
http_enabled: true
transport_enabled: false
description: "JWT realm for Authentik integration"
# Token location and format
token_name: Authorization
token_extractor: "Bearer " # Extract token after "Bearer "
# JWT signing configuration
jwt_header: "Authorization"
jwt_url_parameter: null
roles_key: "roles"
subject_key: "sub"
# JWKS endpoint from Authentik
jwks_uri: "https://authentik.riotpiao.com/application/o/poimen-memory/jwks/"
jwks_refresh_interval_ms: 3600000 # 1 hour
# Issuer validation
issuer: "https://authentik.riotpiao.com/application/o/poimen-memory/"
audience: null
# Claims mapping
enable_ssl_peer_hostname_verification: false
skip_jwt_verification: false
backends:
internal_authc_backend:
type: intern
# Role-based access control
roles_mapping:
all_access:
- "*"
own_index:
- "?kibana"
- "?opensearch-dashboards"
logstash:
- "logstash"
# Index-level permissions
roles:
all_access:
cluster_permissions:
- "*"
index_permissions:
- index_patterns:
- "*"
allowed_actions:
- "*"
tenant_permissions:
- tenant_patterns:
- "*"
allowed_actions:
- "*"
read_vault:
cluster_permissions:
- cluster:monitor/health
- indices:data/read/search
index_permissions:
- index_patterns:
- "vault-*"
allowed_actions:
- "indices:data/read/search"
- "indices:data/read/get"
tenant_permissions:
- tenant_patterns:
- "global_tenant"
allowed_actions:
- "kibana_all_read"
write_vault:
cluster_permissions:
- cluster:monitor/health
- indices:data/write/index
- indices:data/write/update
index_permissions:
- index_patterns:
- "vault-*"
allowed_actions:
- "indices:data/write/index"
- "indices:data/write/update"
- "indices:data/read/search"
tenant_permissions:
- tenant_patterns:
- "global_tenant"
allowed_actions:
- "kibana_all"
# Map JWT claims to OpenSearch internal users
authc_cache_enable: true
internal_users.yml: |
# Internal admin user (for bootstrapping)
admin:
hash: "$2y$12$K/SpwjtB.wW8u3/52l.f2OPST9/PgBkqquzi.Oi8KfRMfsKkCq3GO" # admin:admin123
reserved: true
backend_roles:
- "admin"
- "all_access"
attributes:
attribute1: "value1"
attribute2: "value2"
attribute3: "value3"
roles_mapping.yml: |
all_access:
reserved: false
users:
- "admin"
backend_roles:
- "*"
hosts:
- "*"
action_groups.yml: |
# Add standard action groups here
---
# OpenSearch StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: opensearch
namespace: poimen
labels:
app: opensearch
spec:
serviceName: opensearch
replicas: 2
selector:
matchLabels:
app: opensearch
template:
metadata:
labels:
app: opensearch
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- opensearch
topologyKey: kubernetes.io/hostname
initContainers:
- name: fix-permissions
image: busybox:1.28
command:
- sysctl
- -w
- vm.max_map_count=262144
securityContext:
privileged: true
containers:
- name: opensearch
image: opensearchproject/opensearch:2.11.0
env:
- name: OPENSEARCH_JAVA_OPTS
value: "-Xms2g -Xmx2g -XX:+AlwaysPreTouch -XX:+UseG1GC -XX:MaxGCPauseMillis=30"
- name: OPENSEARCH_INITIAL_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: opensearch-secrets
key: admin-password
- name: DISABLE_SECURITY_PLUGIN
value: "false"
- name: OPENSEARCH_SECURITY_SSL_HTTP_ENABLED
value: "true"
ports:
- containerPort: 9200
name: http
protocol: TCP
- containerPort: 9300
name: node-comm
protocol: TCP
resources:
requests:
memory: "2Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /_cluster/health
port: 9200
scheme: HTTPS
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /_cluster/health
port: 9200
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 3
volumeMounts:
- name: data
mountPath: /usr/share/opensearch/data
- name: config
mountPath: /usr/share/opensearch/config/opensearch.yml
subPath: opensearch.yml
- name: config
mountPath: /usr/share/opensearch/plugins/opensearch-security/securityconfig/internal_users.yml
subPath: internal_users.yml
- name: config
mountPath: /usr/share/opensearch/plugins/opensearch-security/securityconfig/roles_mapping.yml
subPath: roles_mapping.yml
- name: config
mountPath: /usr/share/opensearch/plugins/opensearch-security/securityconfig/action_groups.yml
subPath: action_groups.yml
volumes:
- name: config
configMap:
name: opensearch-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 30Gi
---
# OpenSearch Service (Headless for StatefulSet)
apiVersion: v1
kind: Service
metadata:
name: opensearch
namespace: poimen
labels:
app: opensearch
spec:
clusterIP: None # Headless service
selector:
app: opensearch
ports:
- port: 9200
targetPort: 9200
protocol: TCP
name: http
- port: 9300
targetPort: 9300
protocol: TCP
name: node-comm
publishNotReadyAddresses: true
---
# OpenSearch Internal Service (for direct access)
apiVersion: v1
kind: Service
metadata:
name: opensearch-internal
namespace: poimen
labels:
app: opensearch
spec:
type: ClusterIP
selector:
app: opensearch
ports:
- port: 9200
targetPort: 9200
protocol: TCP
name: http
---
# Secret for OpenSearch Admin Password
apiVersion: v1
kind: Secret
metadata:
name: opensearch-secrets
namespace: poimen
type: Opaque
stringData:
admin-password: "OpenSearch@Admin123!" # TODO: Change to secure password
---
# NetworkPolicy: Only Memory Service can access OpenSearch
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: opensearch-access
namespace: poimen
spec:
podSelector:
matchLabels:
app: opensearch
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: poimen-memory
ports:
- protocol: TCP
port: 9200
---
# NetworkPolicy: OpenSearch can communicate internally
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: opensearch-internal-comm
namespace: poimen
spec:
podSelector:
matchLabels:
app: opensearch
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: opensearch
ports:
- protocol: TCP
port: 9300