Cut the Deployment over to the Infisical-synced Secret and switch to Recreate
(SQLite/WAL on a RWO PVC must not have two writers during a roll). Applied via
kubectl (not ArgoCD-managed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Out-of-band Secret -> Infisical homelab/prod /vaultwarden. Parallel-name
target vaultwarden-secret-infisical (Owner), passthrough. Old vaultwarden-secret
stays live until decommission. Applied via kubectl (not ArgoCD-managed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Old out-of-band umami-secrets deleted (kubectl); the /data ignoreDifferences
stanza referencing it is now dead. Removed from both the registered app
manifest and the in-dir duplicate. umami-secrets-infisical is Owner-managed
by the operator, not a git-tracked Secret, so no ignore rule is needed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DATABASE_URL + APP_SECRET now reference umami-secrets-infisical. Postgres
(3b-i) already healthy on the same secret; umami's wait-for-postgres
initContainer enforces ordering. Old umami-secrets stays live until 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
POSTGRES_PASSWORD now references umami-secrets-infisical. Adds strategy:
Recreate (single-replica RWO PVC — avoids two postmasters racing PGDATA
during a roll), permanent. Data dir already initialized, so the
byte-identical POSTGRES_PASSWORD is never re-applied on restart (benign).
umami still on old umami-secrets (both live in parallel = zero gap).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3a of the umami-secrets centralization. Adds umami-secrets-infisical synced
from homelab/prod /umami (3 lowercase-hyphenated keys, passthrough).
Parallel name — old out-of-band umami-secrets stays live until 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3b of the centralization. All 5 secretKeyRefs now reference
researchowl-secrets-infisical (synced from /researchowl). Also adds
strategy: Recreate (single-replica RWO SQLite/WAL — avoids two pods
briefly sharing /data/researchowl.db during a roll), permanent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3a of the researchowl-secrets centralization. Adds researchowl-secrets-infisical
synced from homelab/prod /researchowl (5 lowercase-hyphenated keys, passthrough).
Parallel name — old out-of-band researchowl-secrets stays live until 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Old out-of-band zona-exclusion-secrets deleted (kubectl); SMTP now sourced from
Infisical-backed zona-exclusion-secrets-infisical. Remove the obsolete /data
ignoreDifferences stanza from both app manifests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
InfisicalStaticSecret syncs shared /smtp-gmail -> zona-exclusion-secrets-infisical,
template-remapping UPPER_SNAKE -> hyphenated lowercase smtp-user/smtp-pass to match
the deployment secretKeyRef. Old secret stays live until 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Old out-of-band ghost-en-smtp secret deleted (kubectl); SMTP now sourced from
Infisical-backed ghost-en-smtp-infisical. Remove the now-obsolete /data
ignoreDifferences stanza from both app manifests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mail__options__auth__user/pass secretKeyRef
ghost-en-smtp -> ghost-en-smtp-infisical
Recreate roll picks up the Infisical-synced credentials.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
InfisicalStaticSecret syncs shared /smtp-gmail -> ghost-en-smtp-infisical
(parallel name, passthrough SMTP_USER/SMTP_PASS). Old secret stays live until 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
InfisicalStaticSecret syncs /gitea-runner -> gitea-runner-secret-infisical
(parallel name). Out-of-band: created via kubectl apply; commit is for record.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7th and final copy of the Telegram bot token leaving git. monitoring is
out-of-band (not ArgoCD-managed), so the live secret is pruned manually with
kubectl. Grafana already reads grafana-telegram-infisical (from /telegram).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Last plaintext secret leaving git; the 6th/last copy of the Telegram token.
ArgoCD prunes the live bot-secrets Secret (and its cleartext
last-applied-configuration annotation). Consumers already on bot-secrets-infisical.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3c of migration #2: drop the Secret stanza from auth.yaml; the Middleware
stays and references filebrowser-auth-infisical (synced from homelab/prod
/filebrowser). ArgoCD prunes the old plaintext filebrowser-auth secret — the
bcrypt htpasswd leaves git. Completes migration #2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3b of migration #2: Middleware.spec.basicAuth.secret now references the
Infisical-managed secret. Secret stanza in auth.yaml left in place as fallback
until 3b is verified (401 w/o creds, 200 w/ creds), then removed in 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3a of migration #2: syncs FILEBROWSER_USERS from homelab/prod /filebrowser
via read-only infisical-operator/infisical-auth, template-remapped to the
lowercase 'users' key Traefik basic-auth requires, into parallel-name
filebrowser-auth-infisical. Old plaintext filebrowser-auth secret + the Traefik
Middleware untouched (repoint=3b, removal of the Secret stanza=3c).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3c: hooks now read telegram-notify-infisical (synced from homelab/prod
/telegram). Deleting these 4 manifests prunes the old plaintext secrets — the
bot token leaves git for the remaining 4 namespaces. Completes migration #1.
NOTE: polymarket-bot/bot-secrets still embeds the same token (migration #3).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3b: all 4 hooks' secretKeyRefs now read the Infisical-managed secret.
Old plaintext telegram-notify secrets stay as fallback until 3c.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3a of telegram-notify migration: each syncs TELEGRAM_BOT_TOKEN/
TELEGRAM_CHAT_ID from shared homelab/prod /telegram via read-only
infisical-operator/infisical-auth, into parallel-name telegram-notify-infisical.
Old plaintext secrets + hooks untouched (repoint=3b, removal=3c).
polymarket-bot: standalone secret only; bot-secrets copy is migration #3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The PostSync hook now reads telegram-notify-infisical (synced from
homelab/prod /telegram). Deleting this manifest prunes the old plaintext
secret — the bot token leaves git for researchowl. Security win.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both secretKeyRefs (TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID) now read the
Infisical-managed secret instead of the plaintext-in-git telegram-notify.
Old secret stays as fallback until 3c removes its manifest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Syncs TELEGRAM_BOT_TOKEN/TELEGRAM_CHAT_ID from shared homelab/prod /telegram
via the read-only infisical-operator/infisical-auth. Targets parallel-name
telegram-notify-infisical; old plaintext telegram-notify stays live until the
hook is repointed (3b) and the old manifest removed (3c).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
api/bot: imagePullSecrets gitea-registry -> gitea-registry-infisical.
dashboard: add gitea-registry-infisical (previously had NO pull secret
despite pulling a private image — fixes latent ErrImagePull-on-reschedule
bug). Old gitea-registry stays as rollback net until decommission.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reconstructs the dockerconfigjson pull secret from the shared /registry v3
fields (GITEA_REGISTRY_USERNAME/GITEA_REGISTRY_TOKEN) via the shared
infisical-operator/infisical-auth. Targets parallel-name
gitea-registry-infisical; old gitea-registry stays live until cutover.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
imagePullSecrets: gitea-registry -> gitea-registry-infisical (the
InfisicalStaticSecret-managed dockerconfigjson). Old gitea-registry stays
as rollback net until decommission.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reconstructs the dockerconfigjson pull secret from the discrete
GITEA_REGISTRY_USERNAME/GITEA_REGISTRY_TOKEN fields at homelab/prod /registry,
via the shared infisical-operator/infisical-auth. Targets parallel-name
gitea-registry-infisical; old gitea-registry stays live until cutover.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 2: GitOps-managed shared auth layer in infisical-operator ns —
InfisicalConnection (https://infisical.chemavx.xyz) + InfisicalAuth
(kubernetes method, operator SA via TokenReview) + identity-ID Secret
(non-secret UUID; auth is via SA token, so safe in git). To be referenced
cross-namespace by per-app InfisicalStaticSecret CRs later. No real secret yet.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 2 Step 2: dedicated SA infisical-token-reviewer bound to
system:auth-delegator (TokenReview), explicit long-lived SA token Secret
(k8s 1.34 doesn't auto-create). ArgoCD ignores /data so selfHeal won't
strip the controller-populated token. Token value never committed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The multi-source variant ($values git ref) caused the infisical app to
prune its own Application object on first sync (controller pruned
Application/argocd/infisical, orphaning the workloads). Switch to a
single-source Helm app with inline valuesObject (same chart 1.9.0, same
DB/Redis passwords) and drop the hand-written tracking-id annotation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deploy infisical-standalone 1.9.0 (Infisical v0.158.0) in a dedicated
'infisical' namespace via a multi-source ArgoCD app (chart + values).
Bundled Postgres (dedicated local-path PVC, 8Gi) + Redis. Ingress via
Traefik + cert-manager (letsencrypt-prod) at infisical.chemavx.xyz.
Crown-jewel secrets (ENCRYPTION_KEY, AUTH_SECRET, SITE_URL) are injected
out-of-band via the 'infisical-secrets' Secret (kubectl, IgnoreExtraneous),
NOT in git. Postgres/Redis passwords guard ClusterIP-only in-cluster
services holding ciphertext; acceptable in values per design review.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The dockerconfigjson held the old account password (now rotated/revoked)
in plaintext. Manage this image-pull secret out-of-band via kubectl
(like researchowl), so no registry credential lives in git going forward.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A ConfigMap volume is read-only at the FS level, so the Ghost entrypoint's
chown -R on content/ failed ("Read-only file system") and crash-looped.
Copy redirects.yaml onto the writable PVC with an initContainer instead;
still GitOps-sourced and refreshed on every pod start.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Recover ~454 GSC impressions stranded on a 404. Adds a ghost-en-redirects
ConfigMap (content/data/redirects.yaml) 301-redirecting the old slug
/pentagon-second-uap-declassification-may-2026-apollo-12-sandia/ to the
live /pentagon-uap-second-release-may-2026/. Mounted read-only via subPath
so it survives content PVC recreation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Same protection already given to polymarket-bot postgres and n8n: without
it, removing a PVC manifest from git (rename, multi-doc refactor) would
make ArgoCD destroy the volume and its data.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The real manifest is researchowl/argocd-app.yaml, self-managed inside the
app's own synced path; edits to this copy get silently reverted by selfHeal.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
researchowl/argocd-app.yaml lives inside the app's own synced path, so it is
the source of truth: annotations applied only to the live object (or to the
argocd/ dump copy) get reverted by selfHeal.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Notifications via generic webhook to the Telegram Bot API: the engine's
native telegram service only supports channels and negative group IDs,
so a positive private chat_id never worked ("chat not found").
- Only on-sync-failed and on-health-degraded triggers; on-sync-succeeded
dropped (CI already reports successful deploys).
- Subscribe annotations on polymarket-bot, researchowl and n8n.
- prune: true on polymarket-bot, guarded by Prune=false on the postgres
PVC so removing the manifest from git can never destroy the data.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Brings the existing manually-applied ghost-en (theexclusionzone.com)
into the GitOps repo. Adds redirect-to-www-https middleware to fix the
Google Search Console redirect issue: non-www now 301s to https://www
instead of serving duplicate content.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Extract readyReplicas OR availableReplicas (k8s omits readyReplicas when 0)
- Also accept MinimumReplicasAvailable condition as ready signal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Create telegram-notify secret in n8n, portfolio, polymarket-bot, researchowl, openclaw
namespaces (values mirrored from monitoring/grafana-telegram)
- Update existing smoke tests (n8n, portfolio, polymarket-bot) to send [OK]/[FAIL]
Telegram notifications on success/failure
- Add postsync-smoke-test for openclaw (curl GET / on port 18789)
- Add postsync-smoke-test for researchowl (no HTTP port; checks readyReplicas via
k8s API using a smoke-test-reader ServiceAccount + Role + RoleBinding)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ze-manual-html ConfigMap serving ze-manual.html at /ze/index.html
- Mount ze-manual-html in nginx at /usr/share/nginx/html/ze
- Add Projects section in portfolio index with ze card linking to /ze
ArgoCD sobreescribía zona-exclusion-secrets con REPLACE_ME.
El secret se gestiona manualmente con annotation Prune=false.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Añade ignoreDifferences para /data del Secret y
RespectIgnoreDifferences=true para que el sync no aplique
el recurso cuando la única diferencia es en los datos del secret.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add ANTHROPIC_API_KEY from secret for Claude Haiku relevance scoring
- Fix OLLAMA_URL to internal k8s DNS (ollama.ollama.svc.cluster.local)
- Remove Secret resource (was causing ArgoCD to overwrite with REPLACE_ME)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>