security: remove all REDACTED secrets from repo, add pre-commit guard

- Delete 26 secret manifests containing REDACTED placeholder values
  (15 cert-manager TLS + 11 app secrets across 8 namespaces)
- REDACTED is valid base64 that decodes to non-UTF-8 bytes — ArgoCD
  applying these manifests corrupts live secrets in the cluster
- Add .githooks/pre-commit that rejects any .yaml with REDACTED
- Add README.md documenting secret management policy and manual
  creation commands for each service
- n8n secret manifests already fixed in previous commits (618b1e8, db04fd2)
This commit is contained in:
2026-04-14 20:02:51 +00:00
parent db04fd2cbc
commit f42cdee585
28 changed files with 81 additions and 481 deletions
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Reject commits that contain REDACTED in YAML files.
# "REDACTED" is valid base64 — if ArgoCD applies it, it corrupts secrets.
REDACTED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.ya\?ml$' | xargs grep -l 'REDACTED' 2>/dev/null)
if [ -n "$REDACTED_FILES" ]; then
echo ""
echo "ERROR: los siguientes archivos contienen 'REDACTED':"
echo "$REDACTED_FILES" | sed 's/^/ /'
echo ""
echo "Los secrets con datos sensibles NO deben ir en este repo."
echo "Elimina el campo 'data:' del manifest o borra el archivo."
echo "Ver README.md para instrucciones de gestión de secrets."
echo ""
exit 1
fi
+64
View File
@@ -0,0 +1,64 @@
# k8s-manifests
Manifests de Kubernetes gestionados por ArgoCD para el cluster chemavx.
## Regla crítica: secrets en git
**Los secrets con datos sensibles NO se guardan en este repo.**
Los archivos de secret en este repo sólo contienen metadata (name, namespace, labels, annotations). Los campos `data` / `stringData` se gestionan manualmente fuera de git.
### Por qué
Un valor placeholder como `REDACTED` es base64 válido que decodifica a bytes no-UTF-8. Si ArgoCD aplica ese manifest, corrompe el secret en el cluster, lo que puede:
- Romper certificados TLS (ERR_CERT_AUTHORITY_INVALID)
- Impedir que pods arranquen (`grpc: error while marshaling: string field contains invalid UTF-8`)
- Cifrar credenciales con una clave incorrecta
### Secrets TLS (cert-manager)
Los secrets TLS los gestiona **cert-manager** automáticamente a partir del recurso `Certificate`. **No crear archivos secret-*-tls.yaml con datos**.
### Secrets de aplicación — crear manualmente antes del primer deploy
| Namespace | Secret | Comando |
|---|---|---|
| `n8n` | `n8n-secret` | `kubectl create secret generic n8n-secret --from-literal=encryption-key='<valor-en-vaultwarden>' -n n8n` |
| `authentik` | `authentik-secret` | Ver Vaultwarden → "authentik" |
| `cloudflare-ddns` | `cloudflare-ddns-secret` | Ver Vaultwarden → "cloudflare-ddns" |
| `vaultwarden` | `vaultwarden-secret` | Ver Vaultwarden → "vaultwarden" |
| `openclaw` | `openclaw-token` | Ver Vaultwarden → "openclaw" |
| `argocd` | `argocd-secret` | Gestionado por ArgoCD bootstrap |
| `argocd` | `argocd-redis` | Gestionado por ArgoCD bootstrap |
| `monitoring` | `kube-prometheus-stack-grafana` | Ver Vaultwarden → "grafana" |
| `monitoring` | `kube-prometheus-stack-admission` | Generado por helm (webhook TLS) |
### ArgoCD ignoreDifferences para secrets
Toda ArgoCD Application que gestione un namespace con secrets debe incluir `ignoreDifferences` para el campo `/data`:
```yaml
spec:
ignoreDifferences:
- group: ""
kind: Secret
name: <nombre-del-secret>
namespace: <namespace>
jsonPointers:
- /data
syncPolicy:
syncOptions:
- RespectIgnoreDifferences=true
```
Ver `n8n` ArgoCD Application como referencia.
## Pre-commit hook
Este repo incluye un pre-commit hook que rechaza commits con `REDACTED` en archivos `.yaml`.
Instalar con:
```bash
cp .githooks/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```
-9
View File
@@ -1,9 +0,0 @@
apiVersion: v1
data:
auth: REDACTED
kind: Secret
metadata:
name: argocd-redis
namespace: argocd
type: Opaque
-20
View File
@@ -1,20 +0,0 @@
apiVersion: v1
data:
admin.password: REDACTED
admin.passwordMtime: REDACTED
server.secretkey: REDACTED
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"labels":{"app.kubernetes.io/name":"argocd-secret","app.kubernetes.io/part-of":"argocd"},"name":"argocd-secret","namespace":"argocd"},"type":"Opaque"}
'
labels:
app.kubernetes.io/name: argocd-secret
app.kubernetes.io/part-of: argocd
name: argocd-secret
namespace: argocd
type: Opaque
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: argocd.chemavx.xyz
cert-manager.io/certificate-name: argocd-tls
cert-manager.io/common-name: argocd.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: argocd-tls
namespace: argocd
type: kubernetes.io/tls
-19
View File
@@ -1,19 +0,0 @@
apiVersion: v1
data:
insecure: REDACTED
password: REDACTED
type: REDACTED
url: REDACTED
username: REDACTED
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"labels":{"argocd.argoproj.io/secret-type":"repository"},"name":"gitea-k8s-manifests","namespace":"argocd"},"stringData":{"insecure":"true","password":"GitAdmin2026x","type":"git","url":"https://git.chemavx.xyz/chemavx/k8s-manifests","username":"chemavx"},"type":"Opaque"}
'
labels:
argocd.argoproj.io/secret-type: repository
name: gitea-k8s-manifests
namespace: argocd
type: Opaque
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: auth.chemavx.xyz
cert-manager.io/certificate-name: auth-tls
cert-manager.io/common-name: auth.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: auth-tls
namespace: authentik
type: kubernetes.io/tls
-15
View File
@@ -1,15 +0,0 @@
apiVersion: v1
data:
AUTHENTIK_POSTGRESQL__PASSWORD: REDACTED
AUTHENTIK_SECRET_KEY: REDACTED
POSTGRES_PASSWORD: REDACTED
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"authentik-secrets","namespace":"authentik"},"stringData":{"AUTHENTIK_POSTGRESQL__PASSWORD":"authentik","AUTHENTIK_SECRET_KEY":"PLACEHOLDER_WILL_UPDATE","POSTGRES_PASSWORD":"authentik"},"type":"Opaque"}
'
name: authentik-secrets
namespace: authentik
type: Opaque
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: authentik.chemavx.xyz
cert-manager.io/certificate-name: authentik-tls
cert-manager.io/common-name: authentik.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: authentik-tls
namespace: authentik
type: kubernetes.io/tls
@@ -1,13 +0,0 @@
apiVersion: v1
data:
CF_API_TOKEN: REDACTED
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"cloudflare-ddns-secret","namespace":"cloudflare-ddns"},"stringData":{"CF_API_TOKEN":"SMDp7QpoGiM_5JVeq4IXCGCv5oKAWQK5MfsBt3n_"},"type":"Opaque"}
'
name: cloudflare-ddns-secret
namespace: cloudflare-ddns
type: Opaque
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: '*.chemavx.xyz,chemavx.xyz'
cert-manager.io/certificate-name: wildcard-chemavx-xyz
cert-manager.io/common-name: chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: ''
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: wildcard-chemavx-xyz-tls
namespace: default
type: kubernetes.io/tls
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: git.chemavx.xyz
cert-manager.io/certificate-name: gitea-tls
cert-manager.io/common-name: git.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: gitea-tls
namespace: gitea
type: kubernetes.io/tls
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: homarr.chemavx.xyz
cert-manager.io/certificate-name: homarr-tls
cert-manager.io/common-name: homarr.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: homarr-tls
namespace: homarr
type: kubernetes.io/tls
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: home.chemavx.xyz
cert-manager.io/certificate-name: home-tls
cert-manager.io/common-name: home.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: home-tls
namespace: homarr
type: kubernetes.io/tls
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: grafana.chemavx.xyz
cert-manager.io/certificate-name: grafana-tls
cert-manager.io/common-name: grafana.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: grafana-tls
namespace: monitoring
type: kubernetes.io/tls
@@ -1,11 +0,0 @@
apiVersion: v1
data:
ca: REDACTED
cert: REDACTED
key: REDACTED
kind: Secret
metadata:
name: kube-prometheus-stack-admission
namespace: monitoring
type: Opaque
@@ -1,21 +0,0 @@
apiVersion: v1
data:
admin-password: REDACTED
admin-user: REDACTED
ldap-toml: REDACTED
kind: Secret
metadata:
annotations:
meta.helm.sh/release-name: kube-prometheus-stack
meta.helm.sh/release-namespace: monitoring
labels:
app.kubernetes.io/component: admin-secret
app.kubernetes.io/instance: kube-prometheus-stack
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: grafana
app.kubernetes.io/version: 12.4.2
helm.sh/chart: grafana-11.5.0
name: kube-prometheus-stack-grafana
namespace: monitoring
type: Opaque
@@ -1,19 +0,0 @@
apiVersion: v1
data:
prometheus.http-client-file.yaml: REDACTED
kind: Secret
metadata:
labels:
app.kubernetes.io/managed-by: prometheus-operator
managed-by: prometheus-operator
name: prometheus-kube-prometheus-stack-prometheus-thanos-prometheus-http-client-file
namespace: monitoring
ownerReferences:
- apiVersion: monitoring.coreos.com/v1
blockOwnerDeletion: true
controller: true
kind: Prometheus
name: kube-prometheus-stack-prometheus
uid: f0355616-4bfa-4409-8b5f-c1c815ee7a2a
type: Opaque
@@ -1,19 +0,0 @@
apiVersion: v1
data:
0_monitoring_kube-prometheus-stack-admission_ca: REDACTED
kind: Secret
metadata:
labels:
app.kubernetes.io/managed-by: prometheus-operator
managed-by: prometheus-operator
name: prometheus-kube-prometheus-stack-prometheus-tls-assets-0
namespace: monitoring
ownerReferences:
- apiVersion: monitoring.coreos.com/v1
blockOwnerDeletion: true
controller: true
kind: Prometheus
name: kube-prometheus-stack-prometheus
uid: f0355616-4bfa-4409-8b5f-c1c815ee7a2a
type: Opaque
@@ -1,19 +0,0 @@
apiVersion: v1
data:
web-config.yaml: REDACTED
kind: Secret
metadata:
labels:
app.kubernetes.io/managed-by: prometheus-operator
managed-by: prometheus-operator
name: prometheus-kube-prometheus-stack-prometheus-web-config
namespace: monitoring
ownerReferences:
- apiVersion: monitoring.coreos.com/v1
blockOwnerDeletion: true
controller: true
kind: Prometheus
name: kube-prometheus-stack-prometheus
uid: f0355616-4bfa-4409-8b5f-c1c815ee7a2a
type: Opaque
@@ -1,19 +0,0 @@
apiVersion: v1
data:
prometheus.yaml.gz: REDACTED
kind: Secret
metadata:
labels:
app.kubernetes.io/managed-by: prometheus-operator
managed-by: prometheus-operator
name: prometheus-kube-prometheus-stack-prometheus
namespace: monitoring
ownerReferences:
- apiVersion: monitoring.coreos.com/v1
blockOwnerDeletion: true
controller: true
kind: Prometheus
name: kube-prometheus-stack-prometheus
uid: f0355616-4bfa-4409-8b5f-c1c815ee7a2a
type: Opaque
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: prometheus.chemavx.xyz
cert-manager.io/certificate-name: prometheus-tls
cert-manager.io/common-name: prometheus.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: prometheus-tls
namespace: monitoring
type: kubernetes.io/tls
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: uptime.chemavx.xyz
cert-manager.io/certificate-name: uptime-kuma-redirect-tls
cert-manager.io/common-name: uptime.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: uptime-kuma-redirect-tls
namespace: monitoring
type: kubernetes.io/tls
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: home.chemavx.xyz,status.chemavx.xyz
cert-manager.io/certificate-name: uptime-kuma-tls
cert-manager.io/common-name: status.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: uptime-kuma-tls
namespace: monitoring
type: kubernetes.io/tls
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: openclaw.chemavx.xyz
cert-manager.io/certificate-name: openclaw-tls
cert-manager.io/common-name: openclaw.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: openclaw-tls
namespace: openclaw
type: kubernetes.io/tls
-9
View File
@@ -1,9 +0,0 @@
apiVersion: v1
data:
OPENCLAW_TOKEN: REDACTED
kind: Secret
metadata:
name: openclaw-token
namespace: openclaw
type: Opaque
@@ -1,15 +0,0 @@
apiVersion: v1
data:
ADMIN_TOKEN: REDACTED
DOMAIN: REDACTED
SIGNUPS_ALLOWED: REDACTED
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"vaultwarden-secret","namespace":"vaultwarden"},"stringData":{"DOMAIN":"https://vaultwarden.chemavx.xyz","SIGNUPS_ALLOWED":"false"},"type":"Opaque"}
'
name: vaultwarden-secret
namespace: vaultwarden
type: Opaque
-21
View File
@@ -1,21 +0,0 @@
apiVersion: v1
data:
tls.crt: REDACTED
tls.key: REDACTED
kind: Secret
metadata:
annotations:
cert-manager.io/alt-names: vaultwarden.chemavx.xyz
cert-manager.io/certificate-name: vaultwarden-tls
cert-manager.io/common-name: vaultwarden.chemavx.xyz
cert-manager.io/ip-sans: ''
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
cert-manager.io/uri-sans: ''
labels:
controller.cert-manager.io/fao: 'true'
name: vaultwarden-tls
namespace: vaultwarden
type: kubernetes.io/tls