atlas-iac/services/hermes/networkpolicy.yaml
jenkins 4ccf2066ca hermes(chat): allow tenant egress to the apiserver for cluster_read
The read-only cluster_read tool (and the HUX-12 producer) reach the
Kubernetes API through the kubernetes Service, which kube-proxy DNATs
from the 10.43.0.1 ClusterIP to a control-plane node on 192.168.22.11-13
:6443 - addresses the tenant egress except-block was dropping, so calls
failed with connection-refused. Egress now allows the ClusterIP and
those three apiserver endpoints on 443/6443. RBAC still bounds what is
readable (no Secrets); nothing else about the isolation changes.

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

717 lines
18 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}
# Read-only Kubernetes API for the cluster_read tool and the HUX-12
# producer: the ClusterIP (some CNIs match pre-DNAT) and the real
# control-plane apiserver endpoints on 6443 (post-DNAT target; the
# 192.168/16 except-block below would otherwise drop these), plus the
# ingress edge for Jenkins/Harbor/health receipts.
- to:
- ipBlock:
cidr: 10.43.0.1/32
- ipBlock:
cidr: 192.168.22.11/32
- ipBlock:
cidr: 192.168.22.12/32
- ipBlock:
cidr: 192.168.22.13/32
ports:
- {protocol: TCP, port: 443}
- {protocol: TCP, port: 6443}
- 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}