Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcf9e24dec |
@@ -5,11 +5,13 @@ When you use a pronoun for someone whose pronouns haven't been stated, use they/
|
||||
# What you can touch
|
||||
|
||||
- `kubectl`: read-only cluster access (the `view` ClusterRole, no Secrets). You cannot change the cluster.
|
||||
- `talosctl`: read-only (`os:reader`) on the Talos nodes; `TALOSCONFIG` is set, the endpoint is `talos.default`. Pass nodes with `-n <InternalIP>` taken from `kubectl get nodes -o wide` at the time (e.g. `talosctl -n <ip> get members`).
|
||||
- `bao`: OpenBao at `BAO_ADDR`, read-only on your own `homelab/apps/hermes/*`. Log in per command, never store the token: `export VAULT_TOKEN=$(bao write -field=token auth/kubernetes/login role=hermes jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token)` then e.g. `bao kv list -mount=homelab apps/hermes`. Never print secret values.
|
||||
- Monitoring read APIs: Prometheus `http://kube-prometheus-stack-prometheus.monitoring.svc:9090`, Alertmanager `http://kube-prometheus-stack-alertmanager.monitoring.svc:9093`, Loki `http://loki.monitoring.svc:3100`.
|
||||
- The homelab wiki through the `homelab-wiki` skill (read, and deposit facts).
|
||||
- The web (HTTPS) and LAN hostnames under `renner.uno` through Traefik.
|
||||
|
||||
- Gitea (`https://gitea.renner.uno`) as `hermes-bot`: `git` over HTTPS authenticates and sets the commit identity on its own. For the API, send `Authorization: token <contents of /var/run/secrets/gitea/api-token>` (read it inside the command, never print it). `tea` is installed but not logged in; use the REST API (`/api/v1`). You write only to repos where `hermes-bot` is a collaborator.
|
||||
- Gitea (`https://gitea.renner.uno`) as `hermes-bot`: `git` over HTTPS authenticates and sets the commit identity on its own. For the API, send `Authorization: token <contents of /var/run/secrets/gitea/api-token>` (read it inside the command, never print it). `tea` is logged in as `hermes-bot` (login `hermes-bot`, the default). You write only to repos where `hermes-bot` is a collaborator.
|
||||
|
||||
All state of record lives in git: infrastructure in the `homelab` repo (Kubernetes/Flux, Ansible, OpenTofu, ESPHome), Home Assistant config in the `homeassistant` repo. Changes land as a feature branch plus a PR for the owner's review (see below).
|
||||
|
||||
|
||||
@@ -95,6 +95,36 @@ spec:
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /opt/data
|
||||
# tea login hermes-bot, written from the mounted token into an
|
||||
# emptyDir at the agent's ~/.config/tea.
|
||||
- name: tea-login
|
||||
image: gitea.renner.uno/konairius/hermes:build.1792397861 # {"$imagepolicy": "flux-system:hermes"}
|
||||
command:
|
||||
- sh
|
||||
- -ec
|
||||
- |
|
||||
umask 077
|
||||
{
|
||||
echo 'logins:'
|
||||
echo ' - name: hermes-bot'
|
||||
echo ' url: https://gitea.renner.uno'
|
||||
echo " token: $(cat /var/run/secrets/gitea/api-token)"
|
||||
echo ' default: true'
|
||||
echo ' user: hermes-bot'
|
||||
} > /tea/config.yml
|
||||
securityContext:
|
||||
runAsUser: 10000
|
||||
runAsGroup: 10000
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
volumeMounts:
|
||||
- name: tea-config
|
||||
mountPath: /tea
|
||||
- name: gitea-token
|
||||
mountPath: /var/run/secrets/gitea
|
||||
readOnly: true
|
||||
containers:
|
||||
- name: hermes
|
||||
image: gitea.renner.uno/konairius/hermes:build.1792397861 # {"$imagepolicy": "flux-system:hermes"}
|
||||
@@ -114,6 +144,14 @@ spec:
|
||||
value: "true"
|
||||
- name: API_SERVER_HOST
|
||||
value: 0.0.0.0
|
||||
# bao: log in with the pod's ServiceAccount token, role hermes
|
||||
# (kubernetes/infrastructure/openbao/policies/hermes.hcl).
|
||||
- name: BAO_ADDR
|
||||
value: http://openbao.openbao.svc.cluster.local:8200
|
||||
# talosctl: os:reader talosconfig from the talos.dev ServiceAccount
|
||||
# hermes-talos (talos-serviceaccount.yaml).
|
||||
- name: TALOSCONFIG
|
||||
value: /var/run/secrets/talos.dev/config
|
||||
# git as hermes-bot: the credential helper reads the mounted token.
|
||||
- name: GIT_CONFIG_COUNT
|
||||
value: "3"
|
||||
@@ -179,6 +217,11 @@ spec:
|
||||
- name: gitea-token
|
||||
mountPath: /var/run/secrets/gitea
|
||||
readOnly: true
|
||||
- name: tea-config
|
||||
mountPath: /opt/data/home/.config/tea
|
||||
- name: talos-config
|
||||
mountPath: /var/run/secrets/talos.dev
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
@@ -201,6 +244,12 @@ spec:
|
||||
- name: gitea-token
|
||||
secret:
|
||||
secretName: hermes-gitea
|
||||
- name: tea-config
|
||||
emptyDir: {}
|
||||
- name: talos-config
|
||||
secret:
|
||||
secretName: hermes-talos
|
||||
optional: true
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
||||
@@ -5,6 +5,7 @@ resources:
|
||||
- api-key.yaml
|
||||
- wiki-externalsecret.yaml
|
||||
- gitea-externalsecret.yaml
|
||||
- talos-serviceaccount.yaml
|
||||
- hermes.yaml
|
||||
- ingress.yaml
|
||||
configMapGenerator:
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# Talos issues an os:reader talosconfig into Secret hermes-talos (key
|
||||
# `config`, endpoint talos.default:50000). Needs
|
||||
# machine.features.kubernetesTalosAPIAccess on the control planes
|
||||
# (kubernetes/talos/patches/cluster.yaml).
|
||||
apiVersion: talos.dev/v1alpha1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: hermes-talos
|
||||
namespace: hermes
|
||||
spec:
|
||||
roles:
|
||||
- os:reader
|
||||
@@ -122,6 +122,24 @@ spec:
|
||||
- ports:
|
||||
- port: "8080"
|
||||
protocol: TCP
|
||||
# OpenBao Kubernetes-auth login and apps/hermes reads; ingress side is
|
||||
# openbao-ns.yaml.
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": openbao
|
||||
app.kubernetes.io/name: openbao
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
# Talos apid (talosctl via Service default/talos, endpoints are the node IPs).
|
||||
- toEntities:
|
||||
- host
|
||||
- remote-node
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "50000"
|
||||
protocol: TCP
|
||||
---
|
||||
# Traefik serves the dashboard (9119) and the OpenAI-compatible API (8642).
|
||||
apiVersion: cilium.io/v2
|
||||
|
||||
@@ -41,6 +41,15 @@ spec:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
# Hermes Agent logs in via auth/kubernetes/role/hermes and reads apps/hermes.
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": hermes
|
||||
app.kubernetes.io/name: hermes
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
# (Secret-rotation CronJobs run in THIS namespace since 2026-07-18, so their
|
||||
# OpenBao access is covered by the intra-namespace ingress rule above — no
|
||||
# per-app rule needed.)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# OpenBao policy: hermes
|
||||
#
|
||||
# Hermes Agent (Deployment hermes, namespace hermes) logs in with its pod
|
||||
# ServiceAccount token and reads its own app secrets.
|
||||
#
|
||||
# NOT applied by Flux. Apply ONCE with an admin token:
|
||||
#
|
||||
# bao policy write hermes kubernetes/infrastructure/openbao/policies/hermes.hcl
|
||||
# bao write auth/kubernetes/role/hermes \
|
||||
# bound_service_account_names=hermes \
|
||||
# bound_service_account_namespaces=hermes \
|
||||
# policies=hermes ttl=1h
|
||||
#
|
||||
# Do NOT set token_no_default_policy=true (kv-v2 preflight needs the default policy).
|
||||
|
||||
path "homelab/data/apps/hermes/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "homelab/metadata/apps/hermes/*" {
|
||||
capabilities = ["read", "list"]
|
||||
}
|
||||
|
||||
path "homelab/metadata/apps/hermes" {
|
||||
capabilities = ["list"]
|
||||
}
|
||||
@@ -38,6 +38,14 @@ machine:
|
||||
hostDNS:
|
||||
enabled: true
|
||||
forwardKubeDNSToHost: true
|
||||
# talos.dev ServiceAccounts: os:reader talosconfigs for Hermes Agent
|
||||
# (apps/hermes/talos-serviceaccount.yaml). Control planes only.
|
||||
kubernetesTalosAPIAccess:
|
||||
enabled: true
|
||||
allowedRoles:
|
||||
- os:reader
|
||||
allowedKubernetesNamespaces:
|
||||
- hermes
|
||||
nodeLabels:
|
||||
node.kubernetes.io/exclude-from-external-load-balancers: ""
|
||||
kubelet:
|
||||
|
||||
Reference in New Issue
Block a user