CreaRack-SL

Mapa crítico · Credenciales, dependencias y rotación entre plataformas

Para qué sirve esta página

Mapa único y vivo de todas las credenciales, tokens, claves API, deploy keys SSH, GitHub Apps y Service Tokens que conectan las plataformas del proyecto, junto con el grafo de dependencias entre ellas y los procedimientos de rotación/auditoría.

Complementa al [[entity—ops—catalogo-servicios-externos]] (que cubre qué pagamos y a quién) respondiendo a una pregunta distinta: qué credenciales tenemos en circulación, dónde viven, qué depende de cada una, cómo regenerarlas, cómo auditarlas.

Grado: 🔴 Crítico. La pérdida o expiración descontrolada de cualquier item de este mapa rompe partes del pipeline. La última crisis (migración GitHub User→Org · sesiones 74-76, 19/20-05-2026) reveló que sin un mapa unificado tardamos horas en detectar qué dejó de funcionar.

Mantenimiento: lifecycle: refresh-30d — el Bibliotecario marca esta página como pendiente de verificación cada 30 días. Owner: Edu.

✅ Inventario RE-VERIFICADO el 24-07-2026 (s235) contra las fuentes vivas: GitHub API (deploy keys, secrets, apps, toggle Org) + SSH a OPS (100.96.245.233) y STAGE (100.96.254.204). Cambios estructurales desde la versión de mayo, ya incorporados abajo: Tailscale → NetBird (s85) · crons migrados de STAGE a OPS (s174-s201, deploy keys viejas 152056708/152056710 revocadas → 1 key crearack-ops por repo) · firewalls solo-NetBird (s222) · rotaciones CF Access (s222-s223, playbook §9) y MCP_TOKENS (s216) · el deploy del workspace es un cron de OPS (el workflow “CF Pages Deploy” está disabled_manually). El secret huérfano CLAUDE_METHOD_DEPLOY_KEY detectado en la verificación quedó RESUELTO el mismo día (decisión de Edu, opción a: secret borrado + workflow eliminado — ver §1.2).

Cuándo consultar este doc

  • Auditoría rutinaria (mensual) — recorrer las secciones y validar que cada credencial sigue activa, dentro de su expiración y con scope correcto.
  • Tras incidente de plataforma (transferencia de cuentas, cambios de Org, rotación masiva, leak sospechoso) — usar la matriz de dependencias para detectar qué se ha podido romper en cascada.
  • Onboarding de nuevo dev — explicarle dónde vive cada credencial y por qué.
  • Antes de regenerar una credencial — ver en la matriz qué se va a ver afectado y avisar a Dani/Txell si aplica.
  • Cuando el Help Widget, Pulse, widget CI Pipeline, MCP handlers o cualquier integración externa empiece a dar 401/403/404 desde un día concreto — es casi siempre un token caducado o desactivado por cambio de cuenta upstream.

Cómo usarlo

  1. Buscar qué credencial usa una funcionalidad → tabla “Matriz de dependencias plataforma → credencial” abajo.
  2. Ver scope y dónde está almacenada una credencial → tabla “Inventario” en su categoría (PATs, Deploy Keys, OAuth, API Keys, Service Tokens, GitHub Apps).
  3. Regenerarla → sección “Procedimientos de rotación” con el paso a paso de cada tipo.
  4. Validar el sistema entero post-cambio → script de auditoría al final de la página.

Mapa visual de plataformas raíz

Las 11 plataformas raíz de las que dependen las 3 plataformas del proyecto (CreaRack Pro, Workspace, claude-method):

flowchart LR
    GH[GitHub Org<br/>CreaRackSL]
    CF[Cloudflare<br/>Workers + Pages + DNS + Access]
    HET[Hetzner<br/>PROD + STAGE + OPS + Object Storage]
    DOK[Dokploy<br/>en PROD + STAGE]
    AI_G[Google AI Studio<br/>Gemma 4]
    AI_A[Anthropic API<br/>Claude Haiku]
    RES[Resend<br/>email transaccional]
    ZOH[Zoho<br/>Calendar + Mail]
    HOL[Holded<br/>facturación]
    NB[NetBird<br/>VPN mesh solo-NetBird]
    UR[UptimeRobot<br/>monitoring externo]

    GH -->|deploy| CF
    GH -->|deploy keys SSH| HET
    GH -->|App| DOK
    CF -->|D1 + R2 + Vectorize + AI binding| CF
    CF -->|CF Access JWT| HET
    HET -->|crons OPS| GH
    HET -->|VictoriaMetrics scrape| HET
    DOK -->|deploy| HET
    CreaRackPro[CreaRack Pro<br/>SaaS Django] --> HET
    CreaRackPro --> AI_G
    CreaRackPro --> AI_A
    CreaRackPro --> RES
    Workspace[Workspace<br/>Astro + Pages Functions] --> CF
    Workspace --> GH
    Workspace --> AI_G
    Workspace --> AI_A
    Workspace --> ZOH
    Workspace --> HOL
    Workspace --> RES
    UR -.->|check| CreaRackPro

1 · Inventario de credenciales por categoría

1.1 GitHub Personal Access Tokens (PATs)

Tokens fine-grained emitidos por Esquembri (cuenta personal Owner del Org CreaRackSL) con resource owner = CreaRackSL Org.

TokenAlmacenado enRepos accedidosScopesExpiraÚltima regeneraciónUsado por
GH_PATCF Pages workspace env var (crearacksl-workspace, environment production)CreaRack-Pro, CreaRackSL-workspace, claude-methodContents:Read+Write (workspace) · Contents:Read (Pro+method) · Actions:Read (Pro) · Issues:Read+Write · Pull requests:Read · Metadata:Read2027-05-202026-05-20 (s76)Widget CI Pipeline (/api/health), Pulse hot-cache.ts fetchRecentCommits, /api/wiki/translate, /api/wiki/content, MCP handlers wiki.ts/github.ts/docs.ts, /api/biblioteca/wiki-titles
WORKSPACE_REPO_TOKEN (⚠️ el secret se llama así, NO WORKSPACE_REPO_PAT — verificado 24-07)GitHub Actions secret en repo CreaRack-Pro (creado 28-05-2026)CreaRackSL-workspace (read-only)Contents:Read · Metadata:Read~2027-052026-05-28Workflow audit-docs-drift.yml (lee estructura de wikis para auditoría)
routine-maintenance-weeklyclaude.ai routine (cuenta Edu)3 repos (read-only)read-only~2027-05-132026-05Routine Maintenance-Weekly (memoria reference_github_pat_routine_maintenance)
ghcr-pull-crearack-base/root/.docker/config.json en STAGE+PROD (+ env GHCR_PULL_TOKEN PC de Edu)GHCR (classic read:packages)pull de ghcr.io/crearacksl/crearack-baseclassic (revisar)2026-07-17 (s224/s227)Deploys Dokploy: FROM crearack-base (playbook §10; si un deploy falla en el FROM con unauthorized → re-login)
ATLAS_CHECK_PATGitHub Actions secret workspace (01-07-2026)CreaRack-Pro (read)contents readsin fecha registrada2026-07-01Cron atlas-check (lunes 07:00 UTC)

Regla operativa: cualquier PAT nuevo del proyecto debe crearse con resource owner = Org CreaRackSL, NUNCA bajo cuenta personal de un dev. El motivo está documentado en el footgun gh_cli_token_owner_removal (s75): si un PAT está atado al usuario y ese usuario deja el Org, el PAT pierde scope silenciosamente.

1.2 Deploy keys SSH (read-only) · ✅ VERIFICADO 24-07-2026

Estado real post-migración a OPS (las 2 keys de la era STAGE — staging-bib-reindex 152056708 y Bibliotecario Reindex (Oraculo Fase 2) 152056710 — fueron revocadas en s201):

Deploy key (GitHub)RepoIDEstadoPrivkey (en OPS /root/.ssh/)Host aliasUsada por
crearack-ops (read-only)CreaRack-Pro156242312enabled · RO · alta 03-07-2026github_crearackgithub-crearackCron bib-reindex de OPS (git pull del Pro cada 10 min)
crearack-ops (read-only)CreaRackSL-workspace156242314enabled · RO · alta 03-07-2026github_workspacegithub-workspaceCrons bib-reindex-ws + cf-pages-deploy de OPS
crearack-ops (read-only)claude-method156242315enabled · RO · alta 03-07-2026github_claude_methodgithub-claude-methodCron bib-reindex-ws claude-method de OPS (lun/jue 00:30)

✅ Resuelto 24-07-2026 (decisión de Edu, opción a): el secret CLAUDE_METHOD_DEPLOY_KEY (huérfano — su pubkey 152056710 fue revocada en s201) se borró del workspace, y el workflow bib-reindex-claude-method.yml (sin runs desde 16-06, dispatch manual roto) se eliminó del repo. El reindex de claude-method lo cubre el cron bib-reindex-ws de OPS. Reversible: el .yml sigue en el historial de git y una deploy key nueva se emite en 1 min si algún día se quiere el fallback en Actions.

Toggle Org obligatorio (verificado true 24-07): la Org CreaRackSL tiene deploy_keys_enabled_for_repositories: true. Si vuelve a false (default al crear Org Free), TODAS las deploy keys quedan en enabled: false silenciosamente. Toggle a nivel Org → https://github.com/organizations/CreaRackSL/settings/security_analysis (o via API gh api -X PATCH orgs/CreaRackSL -F deploy_keys_enabled_for_repositories=true).

Footgun documentado en s76: tras transferir un repo desde User a Org, las deploy keys que tenía el User quedan asociadas con added_by: <user-bridge> y aunque el toggle Org esté activo, GitHub puede devolver enabled: false hasta re-añadirlas. Procedimiento de recuperación abajo.

1.2bis Crons por servidor · ✅ VERIFICADO por SSH 24-07-2026

Inventario canónico completo: AUTOMATISMOS.md del workspace. Foto verificada:

OPS (crearack-ops · 100.96.245.233) — TODOS los crons de mantenimiento:

Cron (/etc/cron.d/)HorarioQué hace
bib-reindexcada 10 min (+extras :30 · communities 04:00)Reindex AST del Pro al grafo
bib-reindex-wssupercontext 00:45 · ts+claude-method lun/jue 00:15-00:30 · chunks 01:30 · wiki 01:00 (full dom 02:00)Reindex corpus workspace/método
biblioteca-cronslint 04:30 · lint-cons dom 03:00 · curator lun/jue 05:00 · utility L-X-V 06:00 · drift 06:00 · escriba 04:15 · enrich 04:50Mantenimiento del Bibliotecario
cf-pages-deploycada 10 minDeploy real del workspace (pushes a main desplegados en ≤10 min)
gh-actions-watchdogcada 5 minVigila workflows de Actions
cron-heartbeatcada 30 minTelemetría de que los crons viven
docker-prunedom 05:30Limpieza runners CI

STAGE (crearack-staging · 100.96.254.204) — limpio tras la F3 (s201), solo DR:

CronHorarioQué hace
cron-dr-backup.shdiario 00:00Export D1 del workspace a /opt/dr-backups/
cron-gdrive-sync.shdom 03:00Sync offsite
cron-stale-check.shdiario 08:00Vigila frescura de los backups
dr-backups-purgesáb 04:30Retención

(+ /opt/workspace-mirror = mirror DR estático :8090.)

Workflows de GitHub Actions: siguen activos Ingest (post-merge), Catalog, Curator*, Lint*, Utility*, Drift-Check*, Weekly-Report, Reindex-TS/Supercontext*, D1 Cleanup, atlas-check, CI, Rotate-MCP-Tokens (*varios con schedule comentado — la ejecución real es el cron OPS; queda workflow_dispatch). CF Pages Deploy y Escriba drift cron están disabled_manually (migrados a OPS) y bib-reindex-claude-method.yml fue eliminado (24-07, opción a).

1.3 OAuth tokens (Zoho per-user)

3 tokens OAuth almacenados en D1 tabla zoho_oauth del workspace (multi-user desde migración s68 0027). Cada miembro del staff autoriza su propia cuenta Zoho.

Usuariorefresh_tokenaccess_tokenScopes
Eduguardado en D1 (singleton legacy migrado fila Edu)refrescado on-demand, ~1h vidaZohoCalendar.event.ALL · ZohoCalendar.calendar.READ · ZohoMail.tasks.READ · ZohoMail.accounts.READ · ZohoMail.messages.READ+CREATE
Daniguardado en D1idemidem
Txellguardado en D1idemidem

App OAuth Zoho (Server-based) registrada en api-console.zoho.com cuenta esfericlabs.com. client_id + client_secret viven en CF Pages env vars ZOHO_CLIENT_ID + ZOHO_CLIENT_SECRET. Detalle en [[runbook—zoho-integration-end-to-end]].

Procedimiento re-autorización (cuando un refresh_token deja de funcionar tras revoke manual desde Zoho UI o tras cambio de scopes): cada usuario va a https://workspace.crearack.com/settings/integrations/zoho y pulsa “Autorizar mi cuenta”. El admin puede actuar por delegación con ?as=Edu|Dani|Txell (requiere ADMIN_EMAILS env var del workspace que incluya al actor). IMPORTANTE: en flujos admin, hacer logout en mail.zoho.eu entre cada ?as= para no contaminar el token con cuenta cruzada (footgun s68 feedback_zoho_logout_between_admin_oauth).

1.4 API keys de proveedores externos

Claves de proveedores third-party. No son PATs ni OAuth; son tokens estáticos con scope total sobre la cuenta. Política: NUNCA commitearlas, NUNCA en plain text en docs, SIEMPRE en secrets de plataforma.

ServicioVariableAlmacenada enUsado porOwner billing
Anthropic APIANTHROPIC_API_KEYCF Pages workspace + GitHub Actions secret workspace + Pro + Dokploy env var PROD + STAGEWorkspace MCP handlers Tutor/CNS · Bibliotecario Curator/Lint Haiku 4.5 · CreaRack Pro alternativa CNS/Tutor/ExplainEdu (pay-as-you-go)
Google AI Studio (Gemma 4)GOOGLE_AI_API_KEYCF Pages workspace + GitHub Actions secret workspace + Dokploy env var CreaRack-Pro PROD + STAGEWorkspace Oráculo/Tutor/Help · Wiki-Translate cron · CreaRack Pro Auto-Plan + Help Widget (via google-genai SDK)Edu (pay-per-use)
ResendRESEND_API_KEYDokploy env var CreaRack-Pro PROD + STAGE + CF Pages workspaceDjango Anymail (transaccional outbound) · workspace /api/mcp send_maintenance_emailEdu (free tier)
HoldedHOLDED_API_KEYCF Pages workspace env varMCP handlers holded_* del workspace (lista contactos, invoices, leads, products, expenses, treasury)Txell (Esferic Labs SL)
Cloudflare APICLOUDFLARE_API_TOKEN (scope Pages) + CLOUDFLARE_D1_TOKEN (scope D1) + CLOUDFLARE_ACCOUNT_IDGitHub Actions secrets workspaceWorkflow D1 Cleanup · scripts wrangler manuales (el deploy del workspace ya NO va por Actions — cron OPS)Edu
CF_CLAUDE_TOKENCF_CLAUDE_TOKENenv var User del perfil de EduHuecos del MCP de Cloudflare (Security Center, Rulesets — el MCP no cubre Access)Edu
MCP_TOKENS workspaceMCP_TOKENS (formato nombre:token,... · rotados s216: 3 personales + CI)CF Pages workspace + GitHub Actions secret MCP_TOKEN en ambos repos (rotado 10-07) + env var User de cada perfil (BIB_MCP_TOKEN)Bearer auth de los endpoints /api/mcp/* desde Claude Code MCP connector + crons BibliotecarioEdu
MAINTENANCE_AGENT_TOKENMAINTENANCE_AGENT_TOKENCF Pages workspace env varBearer estático adicional para routines claude.ai headless que no pueden completar OAuth interactivo (s69)Edu
Hetzner APIHETZNER_API_TOKENCF Pages workspace env varMCP get_servers_status (resto de gestión = panel manual)Edu
NetBird(no usada programáticamente · panel app.netbird.io)n/agestión manual de la VPN: peers, grupos, setup keysEdu
UptimeRobot(no usada programáticamente · solo panel)n/amonitoring externo de PRODEdu

Secrets por repo verificados 24-07-2026 — Pro: ANTHROPIC_API_KEY · CF_ACCESS_CLIENT_ID/SECRET (secret 14-07 ✓ rotación s222) · MCP_TOKEN (10-07 ✓ rotación s216) · WORKSPACE_REPO_TOKEN. Workspace (9 tras borrar el huérfano CLAUDE_METHOD_DEPLOY_KEY): los anteriores + ATLAS_CHECK_PAT · CLOUDFLARE_ACCOUNT_ID/API_TOKEN/D1_TOKEN · GOOGLE_AI_API_KEY. claude-method: vacío ✓.

1.5 Cloudflare Access Service Tokens

⚠️ Rotado en s222-s223 (14-07-2026): el secret vigente y el inventario de las 6 copias a sincronizar en cada rotación viven en el playbook canónico [[crearack-tech—guides—secret-rotation-playbook]] §9. La policy de /api/mcp es Service Auth (un token en policy Bypass NO autentica — footgun s223).

Tokens emitidos desde el panel CF Zero Trust → Service Auth → Service Tokens. Cada uno autoriza llamadas headless a un endpoint protegido por CF Access sin pasar por OAuth de Google/GitHub.

Service TokenApp CF AccessScope (path)Almacenado enUsado por
Workspace API - Bibliotecario crons + MCP (Client ID c0cfca1ac691...access)CreaRackSL Workspace (policy “Service Tokens (crons)”) + Workspace MCP API + API Bibliotecaworkspace.crearack.com (todo) + /api/mcp + /api/biblioteca/Ver inventario de 6 copias en playbook §9 (GH secrets ×2 repos · OPS · /opt/dr-backups/.cf-access STAGE · Dokploy PROD+STAGE · env vars User)Backend Django /help widget proxy · pre-commit hook bib_report_check.py · cron DR backup (STAGE) · crons bib-reindex (OPS)
Maintenance Weekly AgentCreaRackSL Workspace (policy “Service Tokens (crons)”) + Workspace MCP API (extendida con MAINTENANCE_AGENT_TOKEN Bearer)workspace.crearack.com + /api/mcpclaude.ai routine “Maintenance Weekly” en cuenta Edu (panel routines)Bypass OAuth headless de routine claude.ai (s69). Se combina con MAINTENANCE_AGENT_TOKEN Bearer estático

Toggle bypass-everyone: el endpoint /.well-known/cloudflare-access-protected-resource/* y /.well-known/version.json tienen política “Bypass Everyone” (público) para que el banner detector versión y OAuth discovery funcionen sin auth. Cualquier otro endpoint del workspace está detrás de CF Access standard.

Arquitectura policies a nivel cuenta (s78 · 21-05-2026): la UI actual de CF Zero Trust trata las policies como objetos a nivel cuenta reutilizables. La policy Service Tokens (crons) (acción Service Auth) se asocia simultáneamente a varias apps. Eliminada en s78 la app específica DR Backup Service (workspace.crearack.com/api/maintenance/*) tras causar bucle de redirect 302 para usuarios staff: la app más específica tumbaba el SSO de CreaRackSL Workspace. Path /api/maintenance/* ahora cubierto por la app principal (policy “Team only” para users + “Service Tokens (crons)” para tokens). Footguns relacionados: [[footguns_cf_access_app_path_specificity]] · [[footguns_cf_access_service_token_requires_service_auth_action]] · [[footguns_cf_access_account_policies_need_app_link]] (memorias locales staff).

1.6 GitHub Apps instaladas en Org · ✅ VERIFICADO 24-07-2026

AppReposPor qué
Cloudflare Workers and Pages (cloudflare-workers-and-pages)allStatus checks PR + eventos push para CF Pages dashboard. NO es la vía de deploy del workspace — el deploy real es el cron cf-pages-deploy de OPS (cada 10 min).
Dokploy PROD (dokploy-2026-05-25-xsayav)selectedWebhooks de auto-deploy del panel Dokploy de PROD (alta 25-05-2026).
Dokploy STAGE (dokploy-2026-05-25-9dn7kh)selectedIdem para STAGE.

Webhooks salientes clásicos en repos: 0 (esperado — las Apps los reemplazan).

1.5.bis Cloudflare Access · policy de usuarios (login del staff)

Además de los Service Tokens (1.5), la app CreaRackSL Workspace tiene una policy de usuarios humanos que define quién puede entrar a workspace.crearack.com con su login Google/GitHub. Es lo que valida el acceso de Edu, Dani y Txell al workspace.

PolicyApp CF AccessTipoEmails autorizados (estado esperado)
Email staff (o “Team only”)CreaRackSL WorkspaceInclude → Emailseesquembri@esfericlabs.com · dfuentes@esfericlabs.com · tfuentes@esfericlabs.com

Caso Dani (verificar en panel): existió un desajuste histórico por el cual el login de Dani usaba el email legacy dfuentes@edomo.net mientras la policy exigía dfuentes@esfericlabs.com. Acción de verificación (no hay forma de comprobarlo desde docs): en CF Zero Trust → Access → Policies → policy “Email staff” de la app “CreaRackSL Workspace”, confirmar que (a) la lista incluye dfuentes@esfericlabs.com y NO dfuentes@edomo.net, y (b) el email con el que Dani autentica realmente vía Google/GitHub OAuth coincide con el de la policy. Si Dani entra y recibe 403, casi siempre es este desajuste email-policy. (Nota: Dani verificado operativo al 100% el 15-07, task #199 — el riesgo residual es solo si se recrea la policy.)

Regla: cualquier alta/baja de miembro del staff toca esta policy. Mantener los 3 emails @esfericlabs.com alineados con la allowlist Resend (1.7 / email-routing) y con los onboardings.

1.7 Otros secretos críticos del workspace

SecretTipoAlmacenado enUso
CSRF cookies + session secrets Djangoenv varDokploy CreaRack-Pro PROD + STAGESesiones cookies del SaaS
PostgreSQL credentialsenv varDokploy CreaRack-Pro PROD + STAGEConexión pgbouncer → db (app conecta como crearack_app NOSUPERUSER desde s215 — RLS activo)
Valkey passwordenv varDokploy CreaRack-Pro PROD + STAGEConexión cache + broker Huey
CF_ACCESS_AUDenv varCF Pages workspace + CreaRack-Pro PROD/STAGEValidación JWT CF Access (audience tag)
R2 bucket task-attachmentsbinding wrangler.tomlwrangler.toml del workspace + secret CF PagesAlmacenamiento adjuntos tasks workspace
Vectorize index bib-chunksbinding wrangler.tomlwrangler.toml del workspaceEmbeddings BGE-M3 del corpus Bibliotecario (1644 vectors backfilled s73)

2 · Matriz de dependencias plataforma → credencial

Permite responder rápido: “si rompo X, ¿qué deja de funcionar?”.

Plataforma raízCredenciales que la conectan al sistemaSi la credencial cae…
GitHub Org CreaRackSLGH_PAT (workspace) · WORKSPACE_REPO_TOKEN (Pro) · 3 deploy keys crearack-ops · Apps CF + Dokploy ×2Widget CI Pipeline DIM · Pulse sin commits · wiki translate/edit roto · crons de reindex de OPS no pulean · audit-docs-drift falla · auto-deploys Dokploy no reciben push events
CloudflareCLOUDFLARE_API_TOKEN + CLOUDFLARE_D1_TOKEN + CLOUDFLARE_ACCOUNT_ID · Service Tokens (Help Widget + Maintenance Agent) · App CF Workers and PagesCron D1 Cleanup falla · Help Widget Django sin acceso a MCP workspace · routine Maintenance Weekly sin acceso a MCP
Hetzner PRODSSH key Edu vía NetBird (100.96.156.31 — SSH público cerrado desde s222)Pérdida acceso shell · gestión solo via panel Dokploy (también tras NetBird)
Hetzner STAGESSH key Edu vía NetBird (100.96.254.204)Dokploy panel STAGE inaccesible · DR backups (00:00) + gdrive-sync + stale-check paran · mirror DR nginx:8090 inaccesible
Hetzner OPSSSH key Edu vía NetBird (100.96.245.233) · 3 privkeys deploy /root/.ssh/github_*Runners CI parados (CI vuelve a minutos de Actions) · TODOS los crons de mantenimiento parados · deploy del workspace parado (cron cf-pages-deploy)
Anthropic APIANTHROPIC_API_KEYTutor MCP roto · Bibliotecario Curator/Lint roto (Haiku 4.5) · CreaRack Pro CNS/Tutor/Explain (alternativo) sin fallback Claude · routines claude.ai siguen porque usan plan Max, no API
Google AI StudioGOOGLE_AI_API_KEYOráculo de EL roto · Wiki-Translate roto · CreaRack Pro Auto-Plan + Help Widget rotos · Tutor sin chain de fallback
ResendRESEND_API_KEYEmail transaccional CreaRack Pro roto (verificación cuenta + reset password + alertas) · workspace send_maintenance_email roto · routine Maintenance Weekly no manda informe
ZohoOAuth refresh_tokens (3 usuarios) + ZOHO_CLIENT_ID + ZOHO_CLIENT_SECRETAuto-events de ciclo de vida task (crear/cerrar/reabrir/borrar) no sincronizan a Calendar · widget agenda+tasks home workspace vacío · acciones ”+ Crear evento” / ”+ Vincular email” desde TaskModal rotas
HoldedHOLDED_API_KEYMCP handlers holded_* rotos (financial summary, listar invoices/leads/expenses, etc.) · Edu/Txell pierden vista financiera desde workspace · facturación manual desde panel Holded sigue funcionando
NetBirdgrupo servers + dispositivos staff (SSO)Pérdida de TODO el acceso de gestión a los servidores (firewalls solo-NetBird desde s222: SSH, Dokploy, proxies VM/PG) · las apps públicas siguen vivas tras CF
UptimeRobot(cuenta Edu)Sin alertas externas si PROD cae. No es bloqueante porque hay redundancia con health checks Dokploy.

3 · Procedimientos de rotación / regeneración

3.1 Regenerar GH_PAT workspace (caso s76)

Cuándo: cuando alguna funcionalidad del workspace que llama a GitHub API empieza a dar 401/403/404. Caso típico: cambio de membresía Org, token expirado, scope insuficiente.

Pasos:

  1. Ir a https://github.com/settings/personal-access-tokens/new (cuenta Esquembri, Owner del Org).
  2. Configurar:
    • Token name: GH_PAT workspace (CF Pages)
    • Resource owner: CreaRackSL (Org, no User personal — crítico)
    • Expiration: 1 año
    • Repository access: Only select repositories → marcar los 3: CreaRack-Pro, CreaRackSL-workspace, claude-method
    • Repository permissions:
      • Metadata: Read
      • Contents: Read and write
      • Actions: Read
      • Issues: Read and write
      • Pull requests: Read
  3. Si la Org requiere aprobación: aprobar en https://github.com/organizations/CreaRackSL/settings/personal-access-tokens-requests (auto-aprueba si eres Owner).
  4. Subir a CF Pages env vars: pnpm wrangler pages secret put GH_PAT --project-name=crearacksl-workspace. Pegar el token cuando pida valor.
  5. Disparar redeploy: push cualquier commit a main del workspace — el cron cf-pages-deploy de OPS lo despliega en ≤10 min. (El workflow “CF Pages Deploy” de Actions está disabled_manually — NO usarlo.)
  6. Validar widget CI Pipeline del dashboard salud — debe mostrar 5/5 con color verde y “última: success”.

3.2 Regenerar WORKSPACE_REPO_TOKEN

Mismo procedimiento que 3.1 con scopes mínimos: solo Contents:Read + Metadata:Read sobre el repo CreaRackSL-workspace. Subir a gh secret set WORKSPACE_REPO_TOKEN --repo CreaRackSL/CreaRack-Pro y validar con gh workflow run audit-docs-drift.yml --repo CreaRackSL/CreaRack-Pro.

3.3 Re-añadir deploy key (caso s76)

Cuándo: cuando un cron de OPS falla con Repository not found o un workflow falla con ERROR: Repository not found / fatal: Could not read from remote repository. Causa típica: transferencia Org → deploy keys quedan enabled: false.

Pre-requisito: verificar que la Org tiene el toggle global activo:

gh api orgs/CreaRackSL | python -c "import sys,json; print('deploy_keys_enabled_for_repositories =', json.load(sys.stdin).get('deploy_keys_enabled_for_repositories'))"

Si devuelve False: gh api -X PATCH orgs/CreaRackSL -F deploy_keys_enabled_for_repositories=true.

Pasos para re-añadir la key (sin tocar la privkey que ya está en OPS /root/.ssh/github_*):

# 1. Listar keys actuales para obtener id y pubkey
gh api repos/CreaRackSL/<repo>/keys

# 2. Borrar la entry rota
gh api -X DELETE repos/CreaRackSL/<repo>/keys/<id>

# 3. Re-añadir con misma pubkey
gh api -X POST repos/CreaRackSL/<repo>/keys \
  -f title="crearack-ops (read-only)" \
  -f key="ssh-ed25519 AAAA... <comment>" \
  -F read_only=true

Validación (vía NetBird): ssh root@100.96.245.233 "cd /opt/<repo> && git pull" debe devolver “Already up to date” sin warnings (host aliases: github-crearack · github-workspace · github-claude-method).

3.4 Re-autorizar Zoho (per-user)

Ver runbook dedicado: [[runbook—zoho-integration-end-to-end]] sección “Autorizar mi cuenta Zoho”.

3.5 Rotar API key Anthropic / Google AI / Resend / Holded

Patrón común:

  1. Crear nueva key en panel del proveedor (sin borrar la vieja todavía).
  2. Subir a TODOS los almacenes donde se usa (mirar tabla 1.4 — varios servicios viven en 3+ sitios distintos: CF Pages env vars + GitHub Actions secrets + Dokploy env vars PROD + STAGE).
  3. Disparar redeploys de cada plataforma (CF Pages: push a main → cron OPS · Dokploy: redeploy del servicio en panel).
  4. Validar end-to-end con un caso real (mandar email test, generar 1 respuesta IA, listar 1 invoice, etc.).
  5. Borrar la key vieja del panel del proveedor.

Footgun común: olvidar subir la key nueva a Dokploy STAGE o a uno de los entornos secundarios → funciona en uno y rompe en otro silenciosamente. Por eso el inventario por plataforma debe estar siempre completo.

3.6 Rotar Service Tokens CF Access

Fuente canónica: [[crearack-tech—guides—secret-rotation-playbook]] §9 — inventario de las 6 copias del secret a sincronizar (GH secrets ×2 repos · OPS · /opt/dr-backups/.cf-access STAGE · Dokploy PROD+STAGE · env vars User ×3) + registro de rotaciones. CF Zero Trust → Service Auth → Service Tokens → /rotate (mantiene el client-id). El token nuevo aparece UNA VEZ. Validar con curl explícito al endpoint protegido + redeploy del CreaRack-Pro. Recordar: la policy debe ser Service Auth, nunca Bypass (footgun s223).


4 · Auditoría rutinaria · script de verificación

Ejecutar mensualmente o tras incidente de plataforma. Cada comando debe devolver verde / lo esperado. (Última ejecución completa: 24-07-2026 ✅.)

# A) GitHub secrets de los 3 repos
gh secret list --repo CreaRackSL/CreaRackSL-workspace   # esperado: 9 (ver §1.4)
gh secret list --repo CreaRackSL/CreaRack-Pro           # esperado: 5 (ANTHROPIC, CF_ACCESS ×2, MCP_TOKEN, WORKSPACE_REPO_TOKEN)
gh secret list --repo CreaRackSL/claude-method          # esperado: vacío

# B) Deploy keys vivas (esperado: 1 por repo, "crearack-ops (read-only)", enabled)
gh api repos/CreaRackSL/CreaRack-Pro/keys | python -c "import sys,json; [print(k['title'], '·', 'enabled' if k['enabled'] else 'DISABLED') for k in json.load(sys.stdin)]"
gh api repos/CreaRackSL/CreaRackSL-workspace/keys | python -c "import sys,json; [print(k['title'], '·', 'enabled' if k['enabled'] else 'DISABLED') for k in json.load(sys.stdin)]"
gh api repos/CreaRackSL/claude-method/keys | python -c "import sys,json; [print(k['title'], '·', 'enabled' if k['enabled'] else 'DISABLED') for k in json.load(sys.stdin)]"

# C) Org toggle deploy keys (esperado: True)
gh api orgs/CreaRackSL | python -c "import sys,json; d=json.load(sys.stdin); print('deploy_keys_enabled =', d['deploy_keys_enabled_for_repositories'])"

# D) Apps instaladas en Org (esperado: cloudflare-workers-and-pages + dokploy ×2)
gh api orgs/CreaRackSL/installations | python -c "import sys,json; [print(i['app_slug'], '·', i['repository_selection']) for i in json.load(sys.stdin)['installations']]"

# E) Crons scheduled todos verdes (workspace · los migrados a OPS no aparecen aquí, ver F)
gh run list --repo CreaRackSL/CreaRackSL-workspace --limit 30 --json conclusion,event,workflowName,createdAt | python -c "
import sys, json
runs = json.load(sys.stdin)
scheduled = [r for r in runs if r['event'] == 'schedule']
by_wf = {}
for r in scheduled: by_wf.setdefault(r['workflowName'], r)
for wf, r in by_wf.items():
    flag = 'OK' if r['conclusion'] == 'success' else 'FAIL'
    print(f\"  [{flag}] {wf}: {r['conclusion']} at {r['createdAt']}\")
"

# F) OPS · crons y runners funcionando (vía NetBird; esperado: 7 crons de §1.2bis + logs frescos)
ssh root@100.96.245.233 "ls /etc/cron.d/ && tail -2 /opt/cron-heartbeat/cron-driver.log"

# G) STAGE · DR backups frescos (vía NetBird)
ssh root@100.96.254.204 "ls -lt /opt/dr-backups/ | head -5"

# H) PROD containers up (vía NetBird)
ssh root@100.96.156.31 "docker ps --format '{{.Names}}: {{.Status}}'"

# I) Smoke test endpoints públicos
curl -s -o /dev/null -w "PROD = %{http_code}\n" https://crearack.com/health
curl -s -o /dev/null -w "Workspace = %{http_code}\n" https://workspace.crearack.com    # esperado 302 (CF Access)
curl -s -o /dev/null -w "Esferic Labs = %{http_code}\n" https://esfericlabs.com         # esperado 200 (landing en vivo desde 10-07-2026)

Resultado esperado: todos los [OK] en E, crons presentes y heartbeat fresco en F, backups de hoy en G, contenedores Up X · healthy en H, HTTP esperados en I. Cualquier desviación = abrir incidente y volver a este doc para identificar la credencial afectada.


5 · Histórico · footguns conocidos y migraciones

FechaIncidenteCausa raízMitigación implementada
2026-05-19 (s74)Migración GitHub User → Org CreaRackSLTransferencia consciente. Pro User cuenta renombrada a CreaRackSL-bridge.Auditoría exhaustiva s76 + este doc.
2026-05-19 (s74)WORKSPACE_REPO_PAT inválido post-OrgPAT atado a User antiguo, scope perdido al transferir reposRegenerado fine-grained s75 desde Esquembri (resource owner=Org). Memoria footguns_gh_cli_token_owner_removal. Hoy el secret se llama WORKSPACE_REPO_TOKEN (28-05).
2026-05-19 (s74)Branch protections perdidas en los 3 reposDowngrade Pro User → Free Org temporalActivado plan Team Org ($144/año, s75) + protections re-aplicadas.
2026-05-20 09:59 UTC (s75)Bibliotecario-Catalog scheduled failrequired_status_checks blockea bots con GITHUB_TOKEN defaultQuitado required_status_checks del workspace (workspace tiene bots autónomos que pushean a main). CreaRack-Pro mantiene status checks (no tiene bots autónomos). Memoria footguns_branch_protection_blocks_bots.
2026-05-20 (s76)Widget CI Pipeline DIM · MCP wiki/github handlers rotos · cron STAGE bib-reindex falla git pull · workflow Bibliotecario-Reindex-ClaudeMethod falla git cloneTriple cascada: GH_PAT workspace ligado a User antiguo + 2 deploy keys enabled: false por toggle Org deploy_keys_enabled_for_repositories: falseRegenerado GH_PAT (resource owner=Org) + toggle Org activado + 2 deploy keys re-añadidas. Este documento creado como mapa unificado para futuras auditorías.
2026-05-21 (s78)Página /maintenance UI: TypeError: Failed to fetch + auth_status: NONE redirect a CF Access loginApp DR Backup Service (path /api/maintenance/*) tumbaba SSO de la app principal CreaRackSL Workspace por specificidad de path. Su policy primaria era Service Token Bypass (modo service-auth-first) → users staff con OAuth válida quedaban fuera.App DR Backup Service eliminada. Path queda bajo CreaRackSL Workspace. Policy nueva Service Tokens (crons) (acción Service Auth) creada a nivel cuenta y vinculada a la app principal — incluye Service Tokens Workspace API - Bibliotecario crons + MCP + Maintenance Weekly Agent. Cron DR backup nocturno + routine Maintenance Weekly siguen funcionando. 3 footguns nuevos documentados en memorias staff.
2026-05-25 (s85)—Migración VPNTailscale → NetBird Cloud Free (tailnets borrados, Tailscale purgado de servidores). Peers y setup: memoria infra_servers + runbook--infra--hetzner-firewall-solo-netbird.
2026-07-03 → 05 (s174-s201)—Migración crons STAGE → OPSServidor OPS (CX33) con 3 deploy keys nuevas crearack-ops (03-07) + revocación de las 4 keys viejas de STAGE (s201) + F3 limpieza de STAGE (solo queda DR).
2026-07-10 (s216)Auditoría workspace P1aToken MCP compartido en ficheros locales ×3MCP_TOKENS rotados (3 personales + CI) · .mcp.json → ${ENV_VARS} · workflow rotate-mcp-tokens.yml.
2026-07-14/15 (s222-s223)Rotación CF Access + firewallsEndurecimiento superficie externa F2Secret CF Access rotado (6 copias sincronizadas, playbook §9) · firewalls solo-NetBird · policy /api/mcp a Service Auth.
2026-07-24 (s235)Re-verificación completa de este mapaSecret CLAUDE_METHOD_DEPLOY_KEY huérfano detectado (pubkey revocada en s201; workflow sin schedule desde 16-06, dispatch manual roto)Opción a ejecutada (decisión Edu): secret borrado + workflow bib-reindex-claude-method.yml eliminado. El cron bib-reindex-ws de OPS cubre el reindex de claude-method.

6 · Quién debe leer este documento

  • Edu — owner principal. Lo mantiene actualizado, lo consulta antes de cualquier rotación y al cierre del refresh-30d del Bibliotecario.
  • Dani — lo lee para entender qué credenciales puede tocar sin riesgo (la mayoría requieren acción Edu, pero algunas — Zoho per-user, redeploys — son auto-servicio).
  • Txell — solo las secciones relacionadas con billing (1.4 columna “Owner billing”) y el cross-link con [[entity—ops—catalogo-servicios-externos]]. Si una credencial caduca y bloquea facturación (Holded, Resend), Txell sabrá a qué panel ir.
  • Cualquier sustituto temporal de los 3 (Regla 24 igualdad de accesos del staff) — este doc es punto de entrada al sistema de credenciales del proyecto. Junto al onboarding wiki, debe permitir tomar el relevo sin acceso previo a la memoria del equipo.

7 · Mantenimiento de este documento

  • Lifecycle: refresh-30d. El Bibliotecario marca como pendiente de verificación cada 30 días. Edu valida sección por sección.
  • Cuándo actualizar:
    • Cualquier rotación de credencial (anotar en sección 5 si el incidente fue significativo).
    • Nueva integración con proveedor externo (añadir a tablas 1.4, 2 y procedimientos 3).
    • Cambio de plan Org GitHub o Cloudflare que afecte permisos/toggles.
    • Tras cualquier auditoría exhaustiva ejecutar comandos sección 4 y confirmar estado.
  • Cross-links a mantener vivos: [[entity—ops—catalogo-servicios-externos]] · [[runbook—zoho-integration-end-to-end]] · [[crearack-tech—admin—email-routing-architecture]] · [[crearack-tech—guides—secret-rotation-playbook]].

Véase también

  • [[entity—ops—catalogo-servicios-externos]]
  • [[runbook—zoho-integration-end-to-end]]
  • [[crearack-tech—admin—email-routing-architecture]]
  • [[crearack-tech—guides—secret-rotation-playbook]]
  • [[decision—20260516—auditoria-simplificacion-servicios-auxiliares]]