Skip to content

feat: serve OpenAI apps domain challenge from secret - #230

Merged
khaliqgant merged 1 commit into
mainfrom
feat/openai-apps-challenge-secret
Oct 18, 2026
Merged

khaliqgant merged 1 commit into
mainfrom
feat/openai-apps-challenge-secret

Conversation

@miyaontherelay

@miyaontherelay miyaontherelay commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Why

OpenAI verifies ChatGPT app domain ownership by fetching https://agentrelay.com/.well-known/openai-apps-challenge and comparing the bare token. Today that path falls through to the marketing site and returns a Next.js HTML 404.

This repo's router is the only Worker on the prod agentrelay.com apex (cloud infra/web.ts: the SST AgentRelayRouter is gated !isProd). So this is the layer that has to answer.

Supersedes #207, which has the same idea. This PR adds:

What

  • On the apex host only, for exactly /.well-known/openai-apps-challenge:
    • GET/HEAD → 200 text/plain; charset=utf-8 with cache-control: no-store. The body is only the trimmed token: no HTML, JSON or redirect.
    • Token unset or blank → 404 text/plain.
    • Other methods → 405, without the token.
  • Answered before any upstream dispatch, so the token never enters the traffic recorder.
  • deploy-router.yml passes OPENAI_APPS_CHALLENGE_TOKEN from GitHub Actions secrets into the --secrets-file. When the secret is absent nothing is written, so the path 404s.
  • The token is not committed anywhere.

Making it live (human steps)

  1. Set the repo secret with the token from the OpenAI app submission page: gh secret set OPENAI_APPS_CHALLENGE_TOKEN -R AgentWorkforce/agentrelay.com. It is also in Settings → Secrets → Actions.
  2. Merge. A push to main touching router/** or the workflow triggers Deploy Router (Cloudflare). That job waits for the same commit's Deploy Web run, then deploys with the secret.
    • If the secret is set after the merge deploy, re-run Deploy Router with workflow_dispatch.
  3. Verify: curl -si https://agentrelay.com/.well-known/openai-apps-challenge should return 200, text/plain, and only the token.

Verification

  • cd router && vitest run: 11 files, 111 tests pass. The new test/openai-apps-challenge.test.ts has 9 tests: 200 with only the token, trimming, HEAD, 404 when undefined/empty/blank, 405, apex-only, and neighbouring paths.
  • tsc --noEmit -p router/tsconfig.json: clean.
  • The workflow YAML parses.

No deploy, secret or DNS change was made.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Note

Low Risk
Adds an isolated early-return route and optional deploy secret; no changes to auth, payments, or existing routing when the path or secret is unused.

Overview
Adds OpenAI apps domain verification at https://agentrelay.com/.well-known/openai-apps-challenge. The router answers that path before any upstream routing so the token is never proxied or recorded.

When the OPENAI_APPS_CHALLENGE_TOKEN Worker secret is set, GET/HEAD return 200 with plain text (trimmed token, no-store). Missing or blank secret → plain 404 (not marketing HTML). Other methods → 405 without exposing the token. Only the exact path on the agentrelay.com apex qualifies.

Deploy Router now includes OPENAI_APPS_CHALLENGE_TOKEN in the optional --secrets-file bundle (same pattern as analytics hashing). If the GitHub secret is absent, nothing is written and the path 404s.

New Vitest coverage exercises success, trimming, HEAD, unset secret, method/host/path edge cases, and confirms cloud worker is not invoked.

Reviewed by Cursor Bugbot for commit 6ad57dd. Bugbot is set up for automated code reviews on this repo. Configure here.


Agent Relay sessions

  • claude session e4b9f1e5 · opened via gh pr create · last active 2026-10-16

Answer https://agentrelay.com/.well-known/openai-apps-challenge with the bare
token from the OPENAI_APPS_CHALLENGE_TOKEN Worker secret (text/plain, 200),
404 when unset or blank. Apex host only, before any upstream dispatch so the
token never reaches the traffic recorder.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Session-Id: e4b9f1e5-e901-4bea-8fc8-1f08bd07c6d3

Session-Id: e4b9f1e5-e901-4bea-8fc8-1f08bd07c6d3
@coderabbitai

coderabbitai Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 86995cec-7a70-4e43-bf0d-c1c24d748773
  • 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.

@capy-ai capy-ai 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.

Capy found no issues.

View 1 other finding in Capy.

Open in Capy

@github-actions

Copy link
Copy Markdown
Contributor

Preview deployed!

Environment URL
Web https://b1dab911-agentrelay-web.agent-workforce.workers.dev

This is a Cloudflare Workers preview version of this PR's build.

@khaliqgant
khaliqgant merged commit b3ec51b into main Oct 18, 2026
5 checks passed
@khaliqgant
khaliqgant deleted the feat/openai-apps-challenge-secret branch October 18, 2026 02:10
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.

2 participants