| 2026-07-30 23:30 UTC | NO ROTATION — cross-repo credential, unresolved — GitHub OAuth token (gho_…, 40 chars) hardcoded in n8n node digest-get-needs-review et al., workflow Brand__Weekly_Review_Digest_blZAM1unSMwysA38.json, calling api.github.com/repos/radieu/radekkonarski-personal-brand/issues | exposure (#4693, category B) — confirmed via GitHub PR timeline events (gh api repos/radieu/p24-infra/issues/4643/events) that the raw literal was the HEAD of PR #4643’s automation branch (commit 140e11f8, fetchable) from 09:59:42 UTC to 18:30:14 UTC today (~8.5h) before a second force-push overwrote it with the scrub-gate-redacted version merged at 18:42 UTC. Extracted the literal from 140e11f8 via raw-byte git-blob read (git cat-file -p, never printed) — confirmed clean ASCII, 40 chars, SHA-256 fingerprint (first 8 hex) a42320e3. Compared by fingerprint against every GH-token-shaped key reachable from p24-infra: N8N_BMS4_GH_TOKEN (n8n-bms4.env.sops / n8n-bms4-gh.env.sops), GH_TOKEN, GITHUB_PAT_ALL_WRITES, GITHUB_PAT_P24_INFRA (n8n-bms4-gh.env.sops), and all 4 role-scoped ROLE_*_GITHUB_PAT keys — no match (different length and/or fingerprint on every candidate). Target repo (radekkonarski-personal-brand) is owned by a different SOPS file (secrets/radekkonarski-brand.env.sops) that lives in that repo, not p24-infra — out of this session’s access scope by design (role/repo boundary). Decision: cannot confirm live/dead without cross-repo access — escalated as a new targeted issue rather than left unresolved inside #4693. No rotation performed (nothing to rotate against). | claude (secret-manager, Windows desktop session) | Not applicable — credential not identified within p24-infra scope. Follow-up issue filed for radekkonarski-personal-brand secret-manager to identify + rotate if live. |
| 2026-07-30 23:30 UTC | NO ROTATION — already superseded — P24_AUTOMATION_KEY (secrets/pinbox24-w4-auth.env.sops), pre-shared bypass secret for the p24-auth CF Worker /token endpoint | exposure, Step 0b "SOPS already ahead" (#4693, category B) — same PR #4643 force-push window (140e11f8, 09:59:42–18:30:14 UTC) exposed a Bearer 767… literal in the newly-added ecotrans_..._4d7RkkIKsmNNa4lY.json (nodes p24-auth/p24-auth1/p24-auth2). Identified the target key by reading infra-src/p24-auth-worker/src/index.ts (env.P24_AUTOMATION_KEY — “When the Bearer token exactly matches this value, Google OAuth validation is skipped”). Extracted the exposed literal from commit 140e11f8 via raw-byte git-blob read (never printed): clean ASCII, 40 chars (pure token, Bearer prefix stripped), fingerprint d88a5e6e. Compared against the current live SOPS value via Get-SopsKeyFingerprint: 64 chars, fingerprint 8b376d8c — does not match (different length, different hash). Cross-checked against this same log’s 2026-07-11 entry (#3915): that incident rotated this exact key for this exact same anti-pattern (hardcoded literal in a duplicated n8n node — the other copy of this workflow, vuZ1bgFHeiLr6JXp) and explicitly predicted “the same anti-pattern will re-expose the new key on the next workflow view/export” — confirming today’s exposed 40-char value is the pre-2026-07-11-rotation, already-dead key, not the live one. Per static-api-key-incident-rotation.md Step 0b: SOPS is already ahead of the exposed value → no rotation needed. | claude (secret-manager, Windows desktop session) | SOPS unchanged (verified already ahead, no write) · fingerprint comparison only, no value printed · #3915’s 2026-07-11 rotation remains the last real rotation of this key |
| 2026-07-30 23:30 UTC | NO ROTATION — exposed literal confirmed corrupted/non-functional — Supabase Bearer sb_… literal shared across 4 workflows: atrax-daily-stats-collector_Wi3ZJcPw0YbxLXwa.json, wa-group-sync_idCyQWUM4qkeAzFw.json, IMAP_Inbox_Sync__AI_Classifier_82xi1IcZPf0Efj5z.json, compliance-gaps-to-incidents_PKmRXSY3pxBct4r1.json | exposure — reassessed (#4693, category A) — contradicts the issue’s premise that these are long-standing/pre-existing: git log --follow on all 4 files shows the sb_ literal is absent from every commit before today; it first appears in 092a43b1 (“chore: n8n workflow backup 2026-07-30”, merged to main via PR #4643 at 18:42 UTC) and is still on main right now, unredacted by the #4695 scrub gate (verified: no REDACTED marker on this specific field in any of the 4 files — a real gate-coverage gap, filed separately as a bug). Extracted the literal via raw-byte git-blob read (two independent methods: .NET Process+MemoryStream in PowerShell, and Python reading the same blob file — cross-checked, identical result) rather than the text pipeline, because the naive text read silently truncated/garbled the value. Both methods agree: of ~93–100 raw bytes following sb_, 78 are non-ASCII, and the value contains 26 occurrences of the UTF-8 encoding of U+FFFD (the lossy Unicode replacement character) — 93 total bytes − 26×2 excess bytes from the 3-byte U+FFFD encoding = 48, matching the original investigator’s reported “48 chars” exactly. This is conclusive: ≈26 of the original ~48 characters are irreversibly lost, replaced by a lossy placeholder somewhere in the n8n-backup export pipeline (likely a Windows-runner encoding mismatch — the same class of bug this repo already tracks for SOPS files). A value missing more than half its bytes to U+FFFD cannot function as an HTTP Bearer credential (HTTP headers require ASCII) — SHA-256 fingerprint matching against any live SOPS Supabase key is therefore not meaningful (any 1-byte difference already produces a non-matching hash; this has dozens). Per static-api-key-incident-rotation.md’s “confirmed non-functional” logic (same practical-risk class as the documented “confirmed expired token” exception): no emergency rotation of SUPABASE_SERVICE_KEY is warranted from this specific artifact. The underlying live n8n node parameter (in n8n’s own database, not this git export) almost certainly still holds a working, uncorrupted copy of this key — that is a separate, ongoing exposure surface (n8n access, not git) already tracked under #4694 (migrate to credential references); flagged there that #4694 must cover these 4 workflows too (not only the ones in its original scope). | claude (secret-manager, Windows desktop session) | SOPS unchanged (fingerprint match not meaningful against corrupted data — no write attempted) · scrub-gate coverage gap filed as a follow-up bug · #4694 scope note added |
| 2026-07-30 00:00 UTC | PLACEMENT DECISION, no value changed — SUPABASE_ACCESS_TOKEN mirror into secrets/monitoring.env.sops (PR #4700) | secret-placement — delegated call per CLAUDE.md §Role Enforcement (“this is exactly the kind of SOPS-scope decision that’s secret-manager’s, not sys-admin’s, to make”). PR #4700 mirrored the value already held as ROLE_SECRET_MANAGER_SUPABASE_ACCESS_TOKEN (secrets/role-secret-manager.env.sops) into monitoring.env.sops under the canonical name, for #4585’s stated “discoverability” goal. An automated review (AI-Dev-IO1) had already flagged and closed the PR (REQUEST_CHANGES) before this decision was made — this entry is the secret-manager sign-off confirming that closure, made independently rather than rubber-stamped. Verified: (1) docs/secrets-rotation-log.md (this file, 2026-07-05 entry) confirms commit 560fb17e (security #2075) moved this exact key out of monitoring.env.sops because 4 containers (alertmanager, caddy, loki, mezmo-exporter) consume that file wholesale via env_file: .env with no Supabase Management API business — reversing it would have reopened that exposure surface with no new capability. (2) secrets/administration.env.sops already holds SUPABASE_ACCESS_TOKEN under the canonical name (key-presence confirmed, value never read) and is excluded from secrets-sync.yml — the PR’s stated benefit already existed at zero deployment exposure. (3) #4626 (Supabase-side data-plane bug — even a dashboard-minted key 401s, support ticket filed) is the actual blocker on #4583’s rotation, unrelated to which file holds the token — mirroring would not have unblocked anything. Decision: closure endorsed, no re-attempt. Posted sign-off on PR #4700 and closed #4585 (not planned — its premise was superseded by PR #4701’s documentation fix, already reflected in this repo’s CLAUDE.md SOPS file map). Side effect identified, not yet resolved: PR #4700 step 2 had already overwritten the GH Secret SUPABASE_ACCESS_TOKEN on radieu/p24-infra out-of-band (0 workflow consumers — weekly-supabase-advisor-audit.yml reads only the distinct ROLE_SECRET_MANAGER_SUPABASE_ACCESS_TOKEN). Recommended deletion (duplicate copy, no consumer, contradicts least-privilege principle behind 560fb17e); deletion attempt was blocked by this session’s own safety guardrails as an irreversible action requiring explicit human confirmation — flagged on #4585 for radieu to action directly. | claude (secret-manager, delegated placement-decision call) | No SOPS file written — decision-only entry. PR #4700 comment ✅ · #4585 comment + close ✅ · GH Secret SUPABASE_ACCESS_TOKEN deletion: pending human confirmation, not yet actioned |
| 2026-07-30 00:00 UTC | GRAFANA_RADIEU_PASSWORD (secrets/monitoring.env.sops) — password for Grafana user radieu (Org Admin + Server Admin / isGrafanaAdmin: true), created earlier the same day directly via the Grafana Admin API on https://grafana.vps-i1.infra.zintegrowana.online | bootstrap — pure record-keeping, not a rotation and not a new credential value. The password already existed as plaintext in .env.local (grafana_reader_password, lowercase) — an emergency-fallback store per the credential lookup order — and is moved into the canonical SOPS store under the new key name so .env.local is no longer the source of truth. Value copied verbatim via the safe extraction pattern (Select-String → $env:NEW_VALUE, never printed) into sops-set.ps1. No provider-side change made, no distribution/redeploy required: Grafana stores this user’s password in its own internal DB (set at user-creation time via the Admin API, not a GF_SECURITY_ADMIN_PASSWORD-style bootstrap env var), so it is already live and secrets-sync.yml does not touch it. | claude (secret-manager, Windows desktop session) | SOPS secrets/monitoring.env.sops ✅ canary OK, key presence verified via Test-SopsKeyExists (boolean only) · PR #4702 → main, branch chore/add-grafana-radieu-password-sops · GH Secret: N/A (not CI-consumed) · Deployment/restart: N/A (see reason column) |
| 2026-07-30 — ATTEMPTED, ROLLED BACK, STILL PENDING | SUPABASE_SERVICE_ROLE_KEY + SUPABASE_SERVICE_KEY (shared value; secrets/monitoring.env.sops, secrets/n8n-bms4.env.sops, secrets/et-operational-platform.env.sops, secrets/brandpilot.env.sops) | incident — #4583, P0 exposure in review-pr-worker stdout during PR #3788 review (malformed ${SUPA_HB_KEY:-<empty>} expansion). Four prior escalations blocked on missing SUPABASE_ACCESS_TOKEN (#4585). Found working management token ROLE_SECRET_MANAGER_SUPABASE_ACCESS_TOKEN in secrets/role-secret-manager.env.sops (missed by prior escalations — role-scoped file, different key name) and attempted the rotation. | claude (secret-manager, Windows desktop session) | Identified live compromised key p24_shared_service_role_20260714_rot4149 (id 6737a5b9-...-c77d) via unambiguous prefix match. Minted replacement (id 9a59003e-...-a460), distributed to all 4 SOPS files (PR #4602, #4607), GH Secrets (p24-infra + et-operational-platform), secrets-sync (vps-i1/bms-4/vps-h1), Vercel (et-op auto-redeploy + brandpilot manual redeploy), n8n credential ZNuDXmNs3nT58L6p, CF Worker p24-meta-dispatcher rebind. Pre-deletion verification gate FAILED: new key returned 401 Invalid API key from Supabase’s REST API, confirmed independently from bms-4 (ruling out a local network issue). A second freshly-minted key (id 3152d6da-...-e639a9) failed identically — systemic, not a fluke. Rolled back all 4 SOPS files + GH Secrets + n8n credential + both Vercel projects + CF Worker to the old key value (recovered from pre-rotation git history via sops decrypt) — verified restored: GET .../rest/v1/dev_r_services → 200 from bms-4, n8n credential sync → “updated and validated OK”. Both non-functional keys deleted at Supabase (cleanup only). Old/compromised key 6737a5b9 is still live and unchanged — the original exposure from #4583 is NOT resolved. New blocker filed: #4626 (ROLE_SECRET_MANAGER_SUPABASE_ACCESS_TOKEN can list but not mint working keys for this project — needs human investigation of token/org linkage). dev_r_rotation_log id 9aec90aa-8111-4234-9704-c7f3c9bba551 left pending (rotation not achieved). #4583 reopened as human-action, blocked on #4626. |