Skip to content

Migrate Forge bridge to @forge/kvs and add /confluence forge reset command#231

Merged
nang2049 merged 6 commits into
masterfrom
forge-reset-command
Jul 1, 2026
Merged

Migrate Forge bridge to @forge/kvs and add /confluence forge reset command#231
nang2049 merged 6 commits into
masterfrom
forge-reset-command

Conversation

@nang2049

@nang2049 nang2049 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Migrates the Confluence Forge bridge from the deprecated @forge/api storage module to @forge/kvs
  • Adds a reset webtrigger to the bridge and a wipeRegistrationFn break-glass function invocable via forge invoke.
  • Adds /confluence forge reset slash command (System Admin only): rotates the bridge shared secret in-place without re-running the install wizard.

QA

  1. Run /confluence install cloud (captures ForgeResetURL + ForgeRegisterURL).
  2. Verify Confluence events flow to Mattermost normally.
  3. Run /confluence forge reset as a System Admin.
  4. Expected: ephemeral reply Forge bridge secret rotated successfully. Queued events cleared: N.
  5. Wait, edit another Confluence page. Expected: notification still arrives (drain URL unchanged, new secret in use).

Non-admin blocked
6. Run /confluence forge reset as a regular user. Expected: commands can only be run by a system administrator.

**HMAC drift **
9. Manually change ForgeSharedSecret in plugin config to a wrong value.
10. Run /confluence forge reset. Expected: error message mentioning forge invoke -f wipeRegistrationFn and install cloud.

Break-glass path
11. From a machine with Forge CLI access: forge invoke -f wipeRegistrationFn -e development.
12. Expected: JSON {"ok":true,"queuedDeleted":N}.
13. Re-run /confluence install cloud to re-register. Verify events flow again.

Change Impact: 🔴 High

Reasoning: This PR changes the Forge bridge’s core persistence layer and runtime queue/secrets handling by migrating from @forge/api storage to @forge/kvs, and adds new shared-secret rotation/reset flows that can wipe queued events. While there are unit tests for the Go HTTP helpers (postForgeReset/postForgeRegister), there is no end-to-end coverage validating the KVS-backed enqueue→drain→ack and reset/wipe behavior within the Forge webtrigger itself.

Regression Risk: High—queue correctness and HMAC/secret coordination across Confluence↔Mattermost depend on KVS secret/key semantics and query/pagination; most critical reset/rotation paths are not directly exercised by unit tests (tests focus on request signing and response parsing rather than full KVS state transitions). The change also expands command routing and inter-service contracts, adding additional runtime failure modes if URLs/secrets drift.

QA Recommendation: Strongly require manual end-to-end QA in staging (do not skip): verify normal enqueue→drain→ack with realistic event volumes; run /confluence forge reset as a System Admin and confirm the bridge returns an ephemeral confirmation with queued-deleted count and that event flow resumes; verify non-admin access denial; simulate shared-secret/HMAC drift and validate the recovery guidance and break-glass forge invoke -f wipeRegistrationFn ... flow; finally re-register and confirm the queue drains/acknowledges correctly after rotation.
Generated by CodeRabbitAI

@nang2049
nang2049 requested a review from a team as a code owner June 23, 2026 14:27
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: beea3d13-52f0-40fe-b1df-ea79e4a20405

📥 Commits

Reviewing files that changed from the base of the PR and between 8286908 and 1f5840c.

📒 Files selected for processing (1)
  • forge/README.md

📝 Walkthrough

Walkthrough

Adds Forge shared-secret reset support, moves bridge storage to @forge/kvs, returns and stores webtrigger URLs during registration, wires a /confluence forge reset command, updates poller guidance, and expands the Forge operational notes.

Changes

Forge reset and bridge registration

Layer / File(s) Summary
Forge bridge reset endpoint and KVS storage
forge/manifest.yml, forge/package.json, forge/src/index.ts
Adds the Forge reset webtrigger and handler mappings, switches queue and registration persistence to @forge/kvs, clears queued keys through KVS pagination, and returns resolved drain, register, and reset URLs from register responses.
Server registration response and config URLs
server/config/main.go, server/flow.go, server/forge_reset_test.go
Adds config fields for Forge reset/register URLs, changes Forge registration to parse and persist optional returned URLs, keeps compatibility with older {"ok":true} responses, and tests URL parsing behavior.
Reset command implementation and wiring
server/forge_reset.go, server/command.go, server/forge_poller.go, server/forge_reset_test.go, forge/README.md
Adds the /confluence forge reset admin command, signs reset requests with HMAC-SHA256 and re-registers a new secret, tests reset request handling and HMAC signing, updates admin help and autocomplete, updates poller remediation text, and documents reset, KVS storage keys, and limit behavior.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ConfluenceCommandHandler
  participant executeForgeReset
  participant ForgeReset
  participant ForgeRegister
  User->>ConfluenceCommandHandler: forge/reset
  ConfluenceCommandHandler->>executeForgeReset: dispatch
  executeForgeReset->>ForgeReset: POST signed reset
  ForgeReset-->>executeForgeReset: queuedDeleted
  executeForgeReset->>ForgeRegister: POST new shared secret
  ForgeRegister-->>executeForgeReset: urls
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • avasconcelos114

Poem

🐇 I twitched my nose, then spun the wheel,
Fresh URLs and secrets now seal.
KVS keeps the burrow neat and light,
Reset, register, hop on right.
A tidy cloudly carrot delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: migrating the Forge bridge to @forge/kvs and adding the /confluence forge reset command.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch forge-reset-command

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 markdownlint-cli2 (0.22.1)
forge/README.md

markdownlint-cli2 wrapper config was not available before execution


Comment @coderabbitai help to get the list of available commands.

@nang2049 nang2049 added 2: Dev Review Requires review by a core committer 3: QA Review Requires review by a QA tester labels Jun 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@forge/src/index.ts`:
- Around line 179-195: In the wipeAllStorage function, the deletion of
REGISTERED_KEY and SECRET_KEY credentials is currently performed before the
queue deletion loop, which can leave stale queue entries if subsequent
kvs.query() or kvs.delete() operations fail. Reorder the operations by moving
the kvs.delete(REGISTERED_KEY) and kvs.deleteSecret(SECRET_KEY) calls to execute
after the do-while loop that processes queue deletion with the QUEUE_PREFIX,
ensuring credentials remain available for the entire cleanup operation.

In `@server/flow.go`:
- Around line 858-868: The URL assignment block in the flow handling code
accepts bridge-returned values for Reset, Drain, and Register without
validation. Update the logic around the urls handling in flow.go to run each
non-empty value through isForgeWebtriggerURL before writing to
cfg.ForgeResetURL, cfg.ForgeDrainURL, and cfg.ForgeRegisterURL, and only persist
the value when it passes validation.

In `@server/forge_reset.go`:
- Around line 139-144: The code at line 143 (json.Unmarshal call) ignores the
error returned when parsing the response body, and line 144 returns success
without validating that the reset response actually indicates success. Capture
the error from json.Unmarshal instead of ignoring it and check if it's non-nil,
returning an error if the JSON is invalid. Additionally, after successful
unmarshaling, validate that the parsed forgeResetResponse object confirms the
reset was successful (check the appropriate success indicator field in the
forgeResetResponse struct) before returning parsed.QueuedDeleted. Only proceed
with returning success if both the JSON parsing succeeds and the response body
explicitly confirms the bridge wipe was successful.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7841b9ae-0e9b-4ad3-b494-28ca18e09e86

📥 Commits

Reviewing files that changed from the base of the PR and between 0d4a33a and 8ee76da.

📒 Files selected for processing (10)
  • forge/README.md
  • forge/manifest.yml
  • forge/package.json
  • forge/src/index.ts
  • server/command.go
  • server/config/main.go
  • server/flow.go
  • server/forge_poller.go
  • server/forge_reset.go
  • server/forge_reset_test.go

Comment thread forge/src/index.ts
Comment thread server/flow.go
Comment thread server/forge_reset.go

@avasconcelos114 avasconcelos114 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Left a couple of comments for non-blocking nitpicks

Comment thread server/forge_reset.go
}
defer resp.Body.Close()

respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This and server/flow.go could benefit from referencing the same constant for the maximum allowed body size

Comment thread server/flow.go
case http.StatusOK, http.StatusNoContent:
return nil
respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
var parsed forgeRegisterResponse

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Might be nice to also do the same check for parsed.OK that is happening in postForgeReset

@nang2049
nang2049 merged commit 43abbda into master Jul 1, 2026
8 checks passed
@nang2049
nang2049 deleted the forge-reset-command branch July 1, 2026 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2: Dev Review Requires review by a core committer 3: QA Review Requires review by a QA tester

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants