atlas-iac/services/hermes/networkpolicy.yaml
jenkins e40fc5ec5d hermes(chat): stage the HUX-12 evidence producer sidecar
Activation-layer staging, fail-closed until enablement: a per-tenant
hux-evidence-producer sidecar on the exact reviewed WebUI image runs
hux_producer.run_once on a 60s loop, inert until the Vault-staged
evidence key (tolerant init, tmpfs, 0400, staged only for the hux
service and producer containers - never hermes or webui), the policy
ConfigMap, and the scope ConfigMap exist. Adds least-privilege
read-only RBAC (pods+statefulset in hermes, the single named Flux
Kustomization), tenant egress to the Kubernetes API ClusterIP and the
traefik edge, the policy allowlist, hux_producer packaging in the WebUI
image, and a third expected WebUI consumer in the Flux release
renderer. Delivery and image-automation gates enforce the boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
2026-08-24 04:39:45 -03:00

707 lines
17 KiB
YAML

# services/hermes/networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-local-image-ingress
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-local-image
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchExpressions:
- key: app
operator: In
values: [hermes-agent, hermes-model-gate]
ports:
- {protocol: TCP, port: 9004}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-model-gate-ingress
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-model-gate
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchExpressions:
- key: app
operator: In
values: [hermes, hermes-agent, hermes-chat-tenant, hermes-switchyard]
ports:
- {protocol: TCP, port: 8080}
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: maintenance
podSelector:
matchLabels:
app: ariadne
ports:
- {protocol: TCP, port: 8081}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-triage-ingress
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
app: oauth2-proxy-hermes-triage
ports:
- {protocol: TCP, port: 8787}
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: maintenance
podSelector:
matchLabels:
app: ariadne
ports:
- {protocol: TCP, port: 8642}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-agent-isolation
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-agent
policyTypes: [Ingress, Egress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- {protocol: TCP, port: 4180}
- from:
- podSelector:
matchLabels:
app: hermes-chat-tenant
ports:
- {protocol: TCP, port: 9002}
- {protocol: TCP, port: 9003}
- from:
- podSelector:
matchLabels:
app: hermes-switchyard
ports:
- {protocol: TCP, port: 9003}
- {protocol: TCP, port: 9006}
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app: server
ports:
- {protocol: TCP, port: 9010}
- {protocol: TCP, port: 9011}
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
- to:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values: [gitea, hermes-scm]
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: hermes-scm
podSelector:
matchLabels:
app: hermes-scm-broker
ports:
- {protocol: TCP, port: 9081}
- to:
- ipBlock:
cidr: 10.43.0.1/32
ports:
- {protocol: TCP, port: 443}
- to:
- ipBlock:
cidr: 192.168.0.0/16
except:
- 192.168.22.9/32
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 100.64.0.0/10
- 127.0.0.0/8
- 169.254.0.0/16
- 172.16.0.0/12
- 192.168.0.0/16
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-node-ssh-access-isolation
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-node-ssh-access
policyTypes: [Ingress, Egress]
ingress: []
egress: []
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-deny
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
policyTypes: [Ingress, Egress]
ingress: []
egress: []
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-0
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "0"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-0
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-1
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "1"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-1
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-2
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "2"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-2
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-3
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "3"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-3
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-4
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "4"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-4
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-5
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "5"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-5
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-6
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "6"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-6
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-sandbox-tenant-7
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-sandbox
ai.bstein.dev/tenant-ordinal: "7"
policyTypes: [Ingress]
ingress:
- from:
- podSelector:
matchLabels:
statefulset.kubernetes.io/pod-name: hermes-chat-tenant-7
ports:
- {protocol: TCP, port: 9080}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-tenant-isolation
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-tenant
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels:
app: hermes-chat-router
ports:
- {protocol: TCP, port: 8787}
- {protocol: TCP, port: 8642}
- {protocol: TCP, port: 8788}
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: vault
podSelector:
matchLabels:
app: vault
ports:
- {protocol: TCP, port: 8200}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ai
podSelector:
matchLabels:
app: ollama
ports:
- {protocol: TCP, port: 11434}
- to:
- podSelector:
matchLabels:
app: hermes-model-gate
ports:
- {protocol: TCP, port: 8080}
- to:
- podSelector:
matchLabels:
app: hermes-switchyard
ports:
- {protocol: TCP, port: 9005}
- {protocol: TCP, port: 9009}
# HUX-12 evidence producer: the Kubernetes API (ClusterIP) for pod and
# Flux facts, and the ingress edge for Jenkins/Harbor/health receipts.
- to:
- ipBlock:
cidr: 10.43.0.1/32
ports:
- {protocol: TCP, port: 443}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
ports:
- {protocol: TCP, port: 443}
- to:
- podSelector:
matchLabels:
app: hermes-agent
ports:
- {protocol: TCP, port: 9002}
- {protocol: TCP, port: 9003}
- to:
- podSelector:
matchLabels:
app: hermes-chat-sandbox
ports:
- {protocol: TCP, port: 9080}
- to:
- podSelector:
matchExpressions:
- key: app
operator: In
values: [hermes-stt, hermes-tts]
ports:
- {protocol: TCP, port: 9000}
- {protocol: TCP, port: 9001}
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 100.64.0.0/10
- 127.0.0.0/8
- 169.254.0.0/16
- 172.16.0.0/12
- 192.168.0.0/16
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-switchyard-isolation
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-switchyard
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchExpressions:
- key: app
operator: In
values: [hermes, hermes-agent, hermes-chat-tenant]
ports:
- {protocol: TCP, port: 9005}
- from:
- podSelector:
matchLabels:
app: hermes-chat-tenant
ports:
- {protocol: TCP, port: 9009}
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app: server
ports:
- {protocol: TCP, port: 9005}
- {protocol: TCP, port: 9009}
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: vault
podSelector:
matchLabels:
app: vault
ports:
- {protocol: TCP, port: 8200}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ai
podSelector:
matchLabels:
app: ollama
ports:
- {protocol: TCP, port: 11434}
- to:
- podSelector:
matchLabels:
app: hermes-model-gate
ports:
- {protocol: TCP, port: 8080}
- to:
- podSelector:
matchLabels:
app: hermes-agent
ports:
- {protocol: TCP, port: 9003}
- {protocol: TCP, port: 9006}
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 100.64.0.0/10
- 127.0.0.0/8
- 169.254.0.0/16
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- {protocol: TCP, port: 443}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-chat-router-isolation
namespace: hermes
spec:
podSelector:
matchLabels:
app: hermes-chat-router
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels:
app: oauth2-proxy-hermes-chat
ports:
- {protocol: TCP, port: 8080}
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
- to:
- podSelector:
matchLabels:
app: hermes-chat-tenant
ports:
- {protocol: TCP, port: 8787}
- {protocol: TCP, port: 8642}
- {protocol: TCP, port: 8788}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: vault
podSelector:
matchLabels:
app: vault
ports:
- {protocol: TCP, port: 8200}
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 100.64.0.0/10
- 127.0.0.0/8
- 169.254.0.0/16
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- {protocol: TCP, port: 443}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-oauth2-proxies
namespace: hermes
spec:
podSelector:
matchExpressions:
- key: app
operator: In
values:
- oauth2-proxy-hermes-chat
- oauth2-proxy-hermes-triage
policyTypes: [Ingress, Egress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
podSelector:
matchLabels:
app: traefik
ports:
- {protocol: TCP, port: 4180}
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: vault
podSelector:
matchLabels:
app: vault
ports:
- {protocol: TCP, port: 8200}
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
podSelector:
matchLabels:
app: traefik
ports:
- {protocol: TCP, port: 443}
- to:
- podSelector:
matchExpressions:
- key: app
operator: In
values: [hermes, hermes-agent, hermes-chat-router]
ports:
- {protocol: TCP, port: 7681}
- {protocol: TCP, port: 8787}
- {protocol: TCP, port: 8080}
- to:
- podSelector:
matchLabels:
app: hermes-oauth-sessions
ports:
- {protocol: TCP, port: 6379}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: hermes-private-voice
namespace: hermes
spec:
podSelector:
matchExpressions:
- key: app
operator: In
values: [hermes-stt, hermes-tts]
policyTypes: [Ingress, Egress]
ingress:
- from:
- podSelector:
matchLabels:
app: hermes-chat-tenant
ports:
- {protocol: TCP, port: 9000}
- {protocol: TCP, port: 9001}
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- {protocol: UDP, port: 53}
- {protocol: TCP, port: 53}