Fix Woodpecker agent secret duplication — single source of truth #179
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-platform#179
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Bug
Lineage
standalone — discovered during Mac build agent setup (#174)
Repo
forgejo_admin/pal-e-platformWhat Broke
Woodpecker API tokens become "User not authorized" after pod restarts. The Woodpecker MCP, CLI, and external agent auth all break intermittently. Root cause: TWO tfvars files define
woodpecker_agent_secretwith DIFFERENT values:k3s.tfvars:3e053a...(currently deployed to server)secrets.auto.tfvars:597ea9...(would override on nexttofu apply)This secret is the JWT signing key for ALL Woodpecker auth. When it flips between values, every existing token invalidates. The stored API token in
~/secrets/woodpecker/credentials.envwas signed with the wrong value. The Mac agent was given the wrong secret. This has caused debugging pain across multiple sessions.Repro Steps
helm get values woodpecker -n woodpecker --all | grep AGENT_SECRET→ returns3e053a...secrets.auto.tfvars: contains597ea9...(different value)curl -H "Authorization: Bearer $WOODPECKER_TOKEN" https://woodpecker.tail5b443a.ts.net/api/userwith the token fromcredentials.env→ "User not authorized"Expected Behavior
woodpecker_agent_secretvalue across all configtofu planshows zero changes to the Woodpecker secretEnvironment
woodpeckerAcceptance Criteria
woodpecker_agent_secrettofu plan -lock=falseshows NO changes to Woodpecker secretcurl -H "Authorization: Bearer $TOKEN" .../api/userreturns user info~/secrets/woodpecker/credentials.envupdated with working tokenRelated
project-pal-e-platform— platform infrastructurefeedback_ci_pipeline_lessons— add as lesson learnedIssue #179 Ticket Scope Review
TEMPLATE COMPLIANCE (template-issue-bug)
All 9 required sections present and correctly structured:
### Type### Lineage### Repoforgejo_admin/pal-e-platform-- correct### What Brokewoodpecker_agent_secretvalues, JWT signing key mismatch. Includes actual hash prefixes.### Repro Steps### Expected Behavior### Environment### Acceptance Criteria### RelatedTRACEABILITY CHECK
story:superuser-deploytraces to documented user storyproject-pal-e-platformUser Stories table: "I can deploy infrastructure changes viatofu plan/applyand see them succeed in Woodpecker CI without manual intervention." Secret duplication directly threatens this story.arch:ci-pipelinetraces to documented architecture componentconvention-architecture-idsDeployment Components table:arch:ci-pipeline= "Woodpecker CI". Correct mapping.type:bugmatches ticket content[]. The three labels (story:superuser-deploy,arch:ci-pipeline,type:bug) are stated in the review request but not actually applied to the Forgejo issue. Labels must be set for board sync and traceability.ROOT CAUSE ANALYSIS
Root cause is clearly identified and well-articulated: two tfvars files (
k3s.tfvarsandsecrets.auto.tfvars) define the same variablewoodpecker_agent_secretwith different values. Terraform's variable precedence means.auto.tfvarswins, causing the deployed value to flip on apply. This invalidates all existing JWT-signed tokens.This is a textbook config drift bug. The root cause explanation is specific, verifiable, and points directly to the fix (consolidate to one source of truth).
ACCEPTANCE CRITERIA ASSESSMENT
All 7 criteria are testable:
woodpecker_agent_secret" -- grep-verifiabletofu plan -lock=falseshows NO changes to Woodpecker secret" -- CLI-verifiable (note: correctly includes-lock=falseper platform convention)~/secrets/woodpecker/credentials.envupdated" -- file-verifiableCriteria 5-6 may constitute scope creep: creating the Mac agent and updating Salt pillar are arguably part of #174 (Mac build agent), not the secret duplication fix itself. However, since the secret fix is a prerequisite and the agent creation validates the fix, this is borderline acceptable. Flag for awareness.
REPRO STEPS ASSESSMENT
Steps are specific and actionable. They include:
helm get valuescommand with expected outputsecrets.auto.tfvars)curlcommand with expected error responseThese are sufficient to verify both the bug and its fix.
FINDINGS
Must fix before moving to next_up:
story:superuser-deploy,arch:ci-pipeline,type:bug) must be applied to the issue for board sync and traceability triangle compliance. Without labels, the board item cannot be traced to architecture or user story.Observations (non-blocking):
### Relatedsection referencesfeedback_ci_pipeline_lessonsas a note to update. Good practice -- ensures lessons learned are captured.VERDICT: NEEDS WORK
Action required: Apply the three Forgejo labels (
story:superuser-deploy,arch:ci-pipeline,type:bug) to issue #179. Once labels are set, this ticket is ready fornext_up. The issue body itself is exemplary -- clear root cause, specific repro steps, testable acceptance criteria, correct template usage.Resolved (2026-03-26)
Root cause confirmed and fixed
woodpecker_agent_secretfromsecrets.auto.tfvars(line 12)woodpecker_api_token(line 13) — tokens should not be in tfvarsk3s.tfvars(3e053a...) matching deployed Helm valuetf_var_woodpecker_agent_secretto correct valueWorking API token recovered
/proc/PID/environon the running MCP process~/secrets/woodpecker/credentials.envwith the working token3e053a...secretMac agent registered (Woodpecker v3 per-agent tokens)
POST /api/agentswith namelucass-macbook-air-1darwin/arm64, backendlocal,platform=darwinlabelVerification
curl /api/agentsshows both agents connected (linux + darwin)curl /api/userreturns admin user (API token works)Key lesson
Woodpecker v3 uses TWO auth mechanisms:
The shared secret signs JWTs. The per-agent token authenticates individual agents. Don't conflate them.