Skip to content

Kubernetes — алерт когда secret не ротировался дольше N дней

Compliance требует rotation k8s-secrets (DB-passwords, API-tokens) каждые 90 дней. Никто не делает auto-rotate, secrets живут с момента создания cluster-а. Аудитор найдёт первый.

Рецепт

bash
#!/usr/bin/env bash
# /etc/cron.d/k8s-secret-age
# 0 7 * * * root /opt/k8s-secret-age.sh

CONTEXT=${KUBE_CONTEXT:-prod}
NS=${NS:-prod}
MAX_DAYS=${MAX_DAYS:-90}
EXCLUDE_TYPE='kubernetes.io/service-account-token|helm.sh/release.v1'

NOW=$(date -u +%s)
STALE=$(kubectl --context "$CONTEXT" -n "$NS" get secrets -o json \
  | jq --argjson now "$NOW" --argjson max "$MAX_DAYS" --arg ex "$EXCLUDE_TYPE" '
      [.items[] |
       select(.type | test($ex) | not) |
       {name: .metadata.name,
        days: (($now - (.metadata.creationTimestamp | fromdateiso8601)) / 86400 | floor)} |
       select(.days > $max)]')

COUNT=$(echo "$STALE" | jq 'length')

if [ "${COUNT:-0}" -gt 0 ]; then
  EXAMPLES=$(echo "$STALE" | jq -r '.[] | "\(.name)=\(.days)d"' | head -5 | tr '\n' ',')
  curl -fsS "$HEARTBEAT_URL" --data-urlencode "stale_secrets=$COUNT,examples=$EXAMPLES"
  exit 2
fi
echo "OK (no Secrets older than ${MAX_DAYS}d)"

То же самое в Enterno.io

Подключите Enterno heartbeat с retention 365 — будет история «что и когда мы ротировали» для compliance-audit-а.

Настроить HTTP monitor → ← Все рецепты

Похожие рецепты

Readiness-probe внутри пода есть, но никто не видит, что LB отказался роутить трафик на новый deploy.