Skip to content

fix(whatsapp): encrypt each workspace's access token with the server key, tied to that workspace - #313

Merged
SirLouen merged 8 commits into
mainfrom
fix/312
Oct 28, 2026
Merged

SirLouen merged 8 commits into
mainfrom
fix/312

Conversation

@SirLouen

@SirLouen SirLouen commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Closes #312.

What

  • WhatsApp now encrypts a workspace's own access token with the encrypter the host gives it. That uses ALPHONE_ENCRYPTION_KEY and ties the token to its workspace. ALPHONE_WHATSAPP_CREDENTIALS_KEY and the plugin's own cipher code are gone.
  • Without the key, storing a workspace's token fails with an error that names ALPHONE_ENCRYPTION_KEY. The number in the environment file still serves the default workspace.
  • A lint rule keeps cipher packages out of plugins.
  • The e2e server gets a fixed encryption key, so a browser test can still save a token.
  • The docs drop the old key and note the upgrade.

Why

The old key belonged to WhatsApp alone, and a token copied into another workspace's row still opened there. One host key for every plugin secret binds each value to its workspace and is replaced the same way for all of them.

Testing Instructions

Run the testing toolchain.

Summary by CodeRabbit

  • Security
    • WhatsApp access tokens are now encrypted at rest using the application’s encryption key. Storing workspace tokens requires that key.
    • Tokens saved with the previous WhatsApp-specific key are no longer read and must be entered again.
  • Documentation
    • Updated self-hosting guidance with the encryption key requirement and token migration information.

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 883f1d3 and 082f9ea.

Files selected for processing: 19
  • .env.example
  • .golangci.yml
  • Makefile
  • cmd/alphone/whatsapptokens_feature_test.go
  • docs/src/content/docs/self-hosting/configuration.md
  • docs/src/content/docs/self-hosting/updates-and-backups.md
  • plugins/whatsapp/credentials.go
  • plugins/whatsapp/credentials_internal_test.go
  • plugins/whatsapp/e2e.env
  • plugins/whatsapp/events_test.go
  • plugins/whatsapp/export_test.go
  • plugins/whatsapp/fetcher_internal_test.go
  • plugins/whatsapp/send_test.go
  • plugins/whatsapp/whatsapp.go
  • plugins/whatsapp/whatsapp_internal_test.go
  • plugins/whatsapp/whatsapp_test.go
  • sdk/commands_test.go
  • sdk/sdk.go
  • test/features/features/whatsapp-tokens.feature
Files with no reviewable changes: 3
  • .env.example
  • plugins/whatsapp/e2e.env
  • plugins/whatsapp/whatsapp_test.go

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

Walkthrough

The WhatsApp plugin now uses the host-provided encrypter for workspace access tokens. The change removes the plugin-specific credentials key, updates self-hosting and end-to-end configuration, and adds tests for encryption, tenant isolation, and missing-key behavior.

Changes: WhatsApp token encryption

Layer / File(s) Summary
Host-encrypter credential flow
plugins/whatsapp/credentials.go, plugins/whatsapp/whatsapp.go, sdk/sdk.go
The plugin receives an sdk.Encrypter and uses the access_token purpose to encrypt tokens before storage and decrypt them during credential lookup.
Credential behavior and integration tests
plugins/whatsapp/credentials_internal_test.go, plugins/whatsapp/events_test.go, plugins/whatsapp/export_test.go, plugins/whatsapp/fetcher_internal_test.go, plugins/whatsapp/send_test.go, cmd/alphone/whatsapptokens_feature_test.go, test/features/features/whatsapp-tokens.feature, Makefile
Tests cover tenant-bound tokens, encryption and decryption errors, environment credentials, and WhatsApp token scenarios. The end-to-end server receives ALPHONE_ENCRYPTION_KEY.
Legacy key removal and enforcement
.env.example, .golangci.yml, plugins/whatsapp/e2e.env, plugins/whatsapp/whatsapp_internal_test.go, plugins/whatsapp/whatsapp_test.go, sdk/commands_test.go, docs/src/content/docs/self-hosting/configuration.md, docs/src/content/docs/self-hosting/updates-and-backups.md
The plugin-specific key is removed from settings and documentation. A lint rule denies cipher-package imports in plugin and enterprise production Go files. The migration notes say tokens stored under the old key must be entered again.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant WhatsAppPlugin
  participant sdkEncrypter
  participant TenantScopedDatabase
  WhatsAppPlugin->>sdkEncrypter: Encrypt token with access_token purpose
  sdkEncrypter-->>WhatsAppPlugin: Return encrypted token
  WhatsAppPlugin->>TenantScopedDatabase: Store encrypted token for tenant
  WhatsAppPlugin->>TenantScopedDatabase: Read tenant token
  TenantScopedDatabase-->>WhatsAppPlugin: Return encrypted token
  WhatsAppPlugin->>sdkEncrypter: Decrypt token with access_token purpose
  sdkEncrypter-->>WhatsAppPlugin: Return token or decryption error
Loading

Possibly related PRs

  • gopherium/AlphOne#311: Adds the sdk.Encrypter contract and host-side encryption wiring used by this plugin change.
  • gopherium/AlphOne#282: Updates the WhatsApp end-to-end configuration that this change also modifies.

Suggested reviewers: codescene-access

Merge Risk: Minimal · up to 082f9

No actionable merge-blocking issue is established from the supplied evidence. Normal build and test checks remain appropriate before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed 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 and concisely describes the main change: encrypting each WhatsApp workspace access token with the server key and binding it to that workspace.
Linked Issues check Passed Issue #312 has coding requirements, and the pull request implements them. plugins/whatsapp/credentials.go uses the host sdk.Encrypter with the access_token purpose for workspace token encryption…
Out of Scope Changes check Passed The changed files stay within issue #312. The e2e encryption-key setting and feature harness support the required automated scenarios. Test updates replace the removed plugin-owned cipher setup. The l…
Full details: Linked Issues check

Explanation

Issue #312 has coding requirements, and the pull request implements them. plugins/whatsapp/credentials.go uses the host sdk.Encrypter with the access_token purpose for workspace token encryption and decryption. The tenant context is passed to the encrypter, which binds copied tokens to their workspace. The environment-file fallback remains for the default workspace. The feature scenarios verify workspace access, unreadable-at-rest storage, rejection of copied tokens, the ALPHONE_ENCRYPTION_KEY error, and the default-workspace fallback. The change removes ALPHONE_WHATSAPP_CREDENTIALS_KEY, adds the plugin encryption depguard rule, and updates the documented migration and configuration text.

Full details: Out of Scope Changes check

Explanation

The changed files stay within issue #312. The e2e encryption-key setting and feature harness support the required automated scenarios. Test updates replace the removed plugin-owned cipher setup. The lint configuration prevents the encryption implementation that issue #312 replaces. Environment and documentation changes remove the old key and describe the new host-key behavior.

Full details: Docstring Coverage

Explanation

Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 30 functions across 11 files. (5 skipped: 5 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codescene-access codescene-access 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.

Gates Passed
4 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: Clean Code Collective
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@gitar-bot

gitar-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Code Review ✅ Approved

🔴 High risk · Moving WhatsApp tokens to workspace-bound host encryption changes sensitive credential handling; legacy values no longer decrypt, potentially interrupting messaging until re-entered.

Switches WhatsApp access token encryption to the host-provided encrypter, binding each token to its workspace and removing the plugin-specific ALPHONE_WHATSAPP_CREDENTIALS_KEY. No issues found.

Verification

Rules No rules evaluated

Functional validation Not enabled

Set up

For more verification details, comment gitar display:verbose.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing compact verification results.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

@codecov

codecov Bot commented Oct 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[High impact] No merge-blocking concerns remain in the validated token-storage and workspace-isolation behavior.

Summary

WhatsApp now uses the host's sdk.Encrypter to protect each workspace's stored access token.

  • WhatsApp workspace tokens stay tied to the workspace that saved them.

Database-backed checks passed: all four WhatsApp token scenarios and thirty steps succeeded. These cover storing and reading fresh tokens, rejecting ciphertext copied into another workspace, refusing token storage without ALPHONE_ENCRYPTION_KEY, and preserving the default workspace's environment credentials without a key. An additional check verified exact token recovery through the real host encrypter and rejection of copied ciphertext.

SirLouen explicitly acknowledged that old stored tokens will stop opening as an intentional format change. The upgrade notes require entering those tokens again.

No actionable issues were found in the validated scope. No merge-blocking concerns remain. The full testing toolchain was not run.

Reviews (1) · Last reviewed commit: "docs(self-hosting): drop the WhatsApp cr..." · Reviewed by Greptile

@SirLouen
SirLouen merged commit 8b12fee into main Oct 28, 2026
19 checks passed
@SirLouen
SirLouen deleted the fix/312 branch October 28, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WhatsApp keeps workspace tokens under a key only it owns

1 participant