Skip to content

Slack: route OAuth through the privacy relay - #1035

Merged
jeffhuber merged 2 commits into
mainfrom
codex/v150-slack-relay-contract
Sep 18, 2026
Merged

jeffhuber merged 2 commits into
mainfrom
codex/v150-slack-relay-contract

Conversation

@jeffhuber

Copy link
Copy Markdown
Contributor

The v1.5.0 candidate's hosted Slack manifest sends the OAuth authorization code directly to the application callback, bypassing the dedicated query-scrubbing relay required by the reviewed hosted contract. An imported app therefore cannot both match the packaged manifest and pass the live privacy gate.

This change makes the relay the sole Slack OAuth redirect while keeping slash commands and interactivity on the application routes. Unit and installed-wheel rehearsal assertions now pin all three endpoints so a replacement candidate cannot repeat the mismatch. The operator guide explains the relay handoff.

Validation:

  • Slack setup behavior: 6 tests passed
  • Ruff on changed Python and test files: passed
  • Diff hygiene: passed

The existing candidate run is invalid and must not be published. After exact-head review, CI, and the authoritative gate, merge this PR and build one replacement immutable candidate from the merge SHA before resuming #918 and #920.

},
"oauth_config": {
"redirect_urls": ["https://codemower.com/api/slack/oauth/callback"],
"redirect_urls": ["https://codemower-slack-oauth-ingress.jhuber.workers.dev/callback"],

@gitar-bot gitar-bot Bot Sep 18, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Security: OAuth redirect now hardcodes a personal workers.dev domain

The hosted manifest's OAuth redirect_urls changes from the org-owned codemower.com to codemower-slack-oauth-ingress.jhuber.workers.dev, a personal Cloudflare Workers subdomain tied to an individual account (jhuber) rather than the codemower.com org. Slack OAuth redirect URLs are security-sensitive: whoever controls that domain/worker can intercept authorization codes for every installed workspace using this manifest. Baking an individual's personal cloud subdomain into a production/hosted contract creates an ownership and continuity risk (account loss, employee departure, DNS takeover) that isn't mitigated anywhere in this diff. Consider proxying through an org-owned domain (e.g. oauth-relay.codemower.com via a CNAME to the worker) so ownership stays with the organization rather than an individual's personal account.

Front the worker with an org-owned custom domain and point the manifest at that instead of the raw workers.dev subdomain.:

"redirect_urls": ["https://slack-oauth-relay.codemower.com/callback"],

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because your team has used its included automatic processing for this billing period (headroom scales with your seat count). You can still comment "Gitar review" to run one anytime, and automatic reviews resume on their own by October 1. Add seats for more headroom.
Learn more

Code Review ⚠️ Changes requested 0 closed / 1 findings

🟡 Medium risk

Routes Slack OAuth through a privacy relay to comply with the hosted contract, but the redirect URL is hardcoded to a personal Cloudflare Workers domain (codemower-slack-oauth-ingress.jhuber.workers.dev) instead of an org-owned domain. Since OAuth redirect URLs are security-sensitive and can intercept authorization codes, this creates an ownership and continuity risk if the personal account is lost or compromised. Use an org-owned domain (e.g., oauth-relay.codemower.com) proxied to the worker instead.

⚠️ Security: OAuth redirect now hardcodes a personal workers.dev domain

📄 src/code_mower/templates/slack/hosted-app-manifest.json:18 📄 scripts/rehearse_v150.py:234-235 📄 tests/test_slack_setup.py:216-218

The hosted manifest's OAuth redirect_urls changes from the org-owned codemower.com to codemower-slack-oauth-ingress.jhuber.workers.dev, a personal Cloudflare Workers subdomain tied to an individual account (jhuber) rather than the codemower.com org. Slack OAuth redirect URLs are security-sensitive: whoever controls that domain/worker can intercept authorization codes for every installed workspace using this manifest. Baking an individual's personal cloud subdomain into a production/hosted contract creates an ownership and continuity risk (account loss, employee departure, DNS takeover) that isn't mitigated anywhere in this diff. Consider proxying through an org-owned domain (e.g. oauth-relay.codemower.com via a CNAME to the worker) so ownership stays with the organization rather than an individual's personal account.

Front the worker with an org-owned custom domain and point the manifest at that instead of the raw workers.dev subdomain.
"redirect_urls": ["https://slack-oauth-relay.codemower.com/callback"],
🤖 Prompt for agents
Code Review: Routes Slack OAuth through a privacy relay to comply with the hosted contract, but the redirect URL is hardcoded to a personal Cloudflare Workers domain (`codemower-slack-oauth-ingress.jhuber.workers.dev`) instead of an org-owned domain. Since OAuth redirect URLs are security-sensitive and can intercept authorization codes, this creates an ownership and continuity risk if the personal account is lost or compromised. Use an org-owned domain (e.g., `oauth-relay.codemower.com`) proxied to the worker instead.

1. ⚠️ Security: OAuth redirect now hardcodes a personal workers.dev domain
   Files: src/code_mower/templates/slack/hosted-app-manifest.json:18, scripts/rehearse_v150.py:234-235, tests/test_slack_setup.py:216-218

   The hosted manifest's OAuth `redirect_urls` changes from the org-owned `codemower.com` to `codemower-slack-oauth-ingress.jhuber.workers.dev`, a personal Cloudflare Workers subdomain tied to an individual account (`jhuber`) rather than the `codemower.com` org. Slack OAuth redirect URLs are security-sensitive: whoever controls that domain/worker can intercept authorization codes for every installed workspace using this manifest. Baking an individual's personal cloud subdomain into a production/hosted contract creates an ownership and continuity risk (account loss, employee departure, DNS takeover) that isn't mitigated anywhere in this diff. Consider proxying through an org-owned domain (e.g. `oauth-relay.codemower.com` via a CNAME to the worker) so ownership stays with the organization rather than an individual's personal account.

   Fix (Front the worker with an org-owned custom domain and point the manifest at that instead of the raw workers.dev subdomain.):
   "redirect_urls": ["https://slack-oauth-relay.codemower.com/callback"],

Review coverage

Rules No rules evaluated

Functional validation Not enabled · Set up

Options

Display: compact → Counting what did not apply, without listing it.

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

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@jeffhuber

Copy link
Copy Markdown
Contributor Author

Owner gate override for exact head 4a48986d530efe40c508a1825197f5956054fa5a.

  • Independent Claude audit source run 35328831946 completed with sealed metadata verdict PASS and P0/P1/P2 = 0.
  • Required CI is green across Python 3.12/3.13/3.14, Board qualification, graph containment, release-wheel rehearsal, and package.
  • The trusted publication run 35328982802 refused the otherwise valid sealed result with INTERNAL_ERROR; this is a publication-path failure, not a product or review finding.
  • The earlier Gitar ownership finding is resolved by the owner-controlled custom domain in this exact head.

Applying the documented owner-only, current-head gate:override escape hatch. This does not authorize reuse of the superseded v1.5 candidate; a new immutable candidate will be built from the merge commit.

@jeffhuber jeffhuber added the gate:override Code Mower generated label label Sep 18, 2026
@jeffhuber
jeffhuber merged commit 027a249 into main Sep 18, 2026
17 checks passed
@jeffhuber
jeffhuber deleted the codex/v150-slack-relay-contract branch September 18, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builder:codex Code Mower generated label gate:override Code Mower generated label needs-claude-audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant