fix: redact Semaphore API errors#526
Conversation
|
Codex review: needs changes before merge. Reviewed June 21, 2026, 5:03 AM ET / 09:03 UTC. Summary Reproducibility: yes. source inspection gives a high-confidence path: a 2xx project-list response can provide a token-bearing next Link, and a later non-2xx getWithHeaders call formats that unchanged path through semaphoreAPIError.Error. I did not run tests because this review is read-only. Review metrics: 3 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Redact the configured Semaphore token from both stored API error fields, then add a regression test for a token-bearing pagination Link followed by a failing request. Do we have a high-confidence way to reproduce the issue? Yes, source inspection gives a high-confidence path: a 2xx project-list response can provide a token-bearing next Link, and a later non-2xx getWithHeaders call formats that unchanged path through semaphoreAPIError.Error. I did not run tests because this review is read-only. Is this the best way to solve the issue? No, not yet. The provider-local helper is the right narrow shape, but it needs to redact the stored Path as well as Body before this is a complete fix for response-controlled Semaphore diagnostics. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 15dd1dbb1d95. Label changesLabel changes:
Label justifications:
Evidence reviewedSecurity concerns:
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1e246d5927
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| func (c *apiClient) responseError(path string, statusCode int, body []byte) *semaphoreAPIError { | ||
| return &semaphoreAPIError{ | ||
| Path: path, |
There was a problem hiding this comment.
Redact secrets before storing the error path
When resolving a project, path can come from the API's Link header via nextLinkPath; if a bad or reflective Semaphore response puts the configured token in that next URL and the follow-up request returns non-2xx, semaphoreAPIError.Error() prints this Path verbatim even though the body is redacted. Please run the same redaction over path before storing it so response-controlled pagination diagnostics cannot leak the token.
Useful? React with 👍 / 👎.
|
@clawsweeper re-review Maintainer security review accepts the provider-local helper and coverage of all Semaphore non-2xx constructors; live TLS reflection proof is sufficient. The sole mechanical finding is declined: repository policy requires an Unreleased changelog entry for this maintainer-authored user-facing security fix. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Summary
Fixes #518
Verification
go test -race ./internal/providers/semaphorego test -race ./internal/providers/semaphore -run 'TestAPIClient.*Redact' -count=1 -vgo vet ./...go test -race ./...npm run format:check --prefix workernpm run lint --prefix workernpm run check --prefix workernpm test --prefix worker(646 tests)npm run build --prefix workernode scripts/build-docs-site.mjsLive proof
The focused integration starts a real loopback TLS server, verifies that the production client submitted
Authorization: Token <dummy>, returns that header in a 401 response body, and asserts the resulting error containsToken [redacted]but not the dummy token:The adjacent socket-free table executes every non-2xx construction path independently.