# Excubitor network policy controller (excubitor.netpolicy). # # Keeps one network policy per agent matching its containment: normally the # agent's pods may reach only their allowed destinations; once Excubitor contains # the agent, only DNS and the console. Below the agent's process, so a # subprocess or another library cannot go around it. # # Before applying: # 1. Label each agent's pods: excubitor.aurakore.com/agent: # 2. Edit agents.json below: the namespace, the flavor (cilium for host names, # kubernetes for address ranges only), the console, and each agent's # destinations. A plain-Kubernetes config needs console_cidrs. # 3. kubectl -n agents create secret generic excubitor-netpolicy \ # --from-literal=EXCUBITOR_CONSOLE_URL=https://... \ # --from-literal=EXCUBITOR_TOKEN= # (self-hosted: EXCUBITOR_DATABASE_URL instead, the console's own database) # # ⛔ The first sync applies the allow-lists. An agent pod reaching a destination # that is not on its list loses it then. Run `excubitor-netpolicy render` for # each agent and read the output before applying this. apiVersion: v1 kind: ServiceAccount metadata: name: excubitor-netpolicy namespace: agents --- # Network policies in the agents' namespace and nothing else. apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: excubitor-netpolicy namespace: agents rules: - apiGroups: ["cilium.io"] resources: ["ciliumnetworkpolicies"] verbs: ["get", "create", "patch"] - apiGroups: ["networking.k8s.io"] resources: ["networkpolicies"] verbs: ["get", "create", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: excubitor-netpolicy namespace: agents roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: excubitor-netpolicy} subjects: - {kind: ServiceAccount, name: excubitor-netpolicy, namespace: agents} --- apiVersion: v1 kind: ConfigMap metadata: name: excubitor-netpolicy namespace: agents data: agents.json: | {"namespace": "agents", "flavor": "cilium", "console_host": "excubitor.aurakore.com", "agents": { "invoice-copilot": {"allow_hosts": ["api.stripe.com", "*.corp.internal"]} }} --- apiVersion: apps/v1 kind: Deployment metadata: name: excubitor-netpolicy namespace: agents spec: replicas: 1 # one writer of the policies selector: {matchLabels: {app: excubitor-netpolicy}} template: metadata: labels: {app: excubitor-netpolicy} spec: serviceAccountName: excubitor-netpolicy containers: - name: controller image: python:3.12-slim command: ["sh", "-c", "pip install --quiet excubitor-sdk && exec excubitor-netpolicy sync --config /config/agents.json"] envFrom: - secretRef: {name: excubitor-netpolicy} volumeMounts: - {name: config, mountPath: /config, readOnly: true} resources: requests: {cpu: 10m, memory: 64Mi} limits: {cpu: 200m, memory: 128Mi} securityContext: allowPrivilegeEscalation: false capabilities: {drop: ["ALL"]} volumes: - name: config configMap: {name: excubitor-netpolicy}