Audit des domaines publics (2026-09-25)
Suite : tranche pour sept sous-domaines (mcp, api, cdn, hooks, status, docs, preview). Le code est livre derriere un interrupteur ; checklist operateur : subdomains.md.
Suite : tranche pour sept sous-domaines (
mcp,api,cdn,hooks,status,docs,preview). Le code est livre derriere un interrupteur ; checklist operateur :subdomains.md.
Rapport seulement : rien n'a ete change dans l'infra, le DNS,
src/proxy.tsnisrc/env/*. Question : « pourquoi pasmcp.boostecom.app,cdn.boostecom.app,preview.boostecom.appau lieu d'URLs longues ou etranges, pour toute la codebase ? ».
Ce que le produit montre ou emet aujourd'hui
| Surface | Forme actuelle | Construite ou | Hote d'origine |
|---|---|---|---|
| Endpoint MCP (Studio, section MCP et API) | https://www.boostecom.app/api/mcp/v1/<storeId> | src/components/studio/connect-content.tsx (useEndpoint, window.location.origin) | l'origine du navigateur |
| Endpoint MCP (guides publics) | ${APP_URL}/api/mcp/v1/<STORE_ID> | src/app/(marketing)/features/mcp/connect/[client]/page.tsx:41 | APP_URL, src/config/platform.ts:19 (NEXT_PUBLIC_APP_URL, repli https://www.boostecom.app) |
| Endpoint MCP non versionne (clients installes) | /api/mcp/<storeId> | src/app/api/mcp/[storeId]/route.ts | requete |
| Metadonnees de ressource protegee (RFC 9728) | ${origin}/.well-known/oauth-protected-resource/api/mcp/v1/<id> | src/app/api/mcp/[storeId]/helpers.ts:44-48 | req.url |
| Serveur d'autorisation OAuth (RFC 8414) | issuer = origine nue | src/app/.well-known/oauth-authorization-server/route.ts:26 | req.url |
| Consentement OAuth | /oauth/authorize | src/app/oauth/authorize/page.tsx | origine de l'app |
| Jeton OAuth | /api/oauth/token | src/app/api/oauth/token/route.ts | origine de l'app |
| Callbacks OAuth sortants (Google, Meta, Klaviyo, Notion) | *_REDIRECT_URI | src/app/api/connectors/[connectorId]/route.ts:153-177, src/features/connectors/token-refresh.ts:93,131 | variables d'env, enregistrees chez chaque fournisseur |
| Webhook Shopify (Custom App) | ${NEXT_PUBLIC_APP_URL}/api/webhooks/shopify/events | src/app/api/integrations/shopify/custom-app/route.ts:359, src/features/ai/wizard-skills/webhook-wiring.ts:51 | env |
| Webhook WhatsApp | ${base}/api/webhooks/whatsapp | src/app/api/integrations/whatsapp/lib.ts:118 | env |
| Webhooks Stripe, Resend, GitHub, creative-render | /api/webhooks/<provider> | src/app/api/webhooks/* | saisis a la main dans chaque console fournisseur |
| Images OG | ${APP_URL}/api/og?... | src/lib/seo/marketing-metadata.ts:28 | APP_URL |
| Assets Vercel Blob (uploads, rendus Studio, captures de scan) | https://<store>.public.blob.vercel-storage.com/... | src/app/api/upload/route.ts:95, src/features/ai/orchestrator/runtime/studio-references.ts, src/features/tracking/lib/scan-retention.ts | l'URL rendue par put(), persistee en base |
| Proxy de preview storefront | /api/preview/proxy?url=... sur l'origine du dashboard | src/app/api/preview/proxy/route.ts | origine de l'app |
| Origine de preview dediee | boostecom.vercel.app | src/lib/storefront-origin-preview-host.ts:13 (DEDICATED_PREVIEW_HOST) | litteral |
Deux constats :
- L'URL MCP n'a pas de constante unique. Elle est ecrite deux fois
(Studio sur l'origine du navigateur, guides publics sur
APP_URL) et le serveur derive ses metadonnees OAuth dereq.url. UnNEXT_PUBLIC_MCP_ORIGINn'aurait donc pas ete un changement « tiny » : il faudrait d'abord une fonctionmcpEndpoint(storeId)danssrc/config/platform.ts(hot file), la cle danssrc/env/server.ts, une ligne dans l'audit d'env (env-audit-coverage.test.ts) et un lecteur (env-var-consumed.test.ts). Non fait, volontairement. - La longueur de l'URL MCP ne vient pas du domaine : elle vient de
/api/mcp/v1/et de l'identifiant de boutique (25 caracteres). Passer amcp.boostecom.app/<storeId>gagne environ 20 caracteres ; retirer l'id demande que la CLE designe la boutique (decision de securite).
Carte de sous-domaines proposee
| Sous-domaine | Sert | DNS | Vercel | src/proxy.ts | CORS / CSP / cookies | OAuth et clients installes |
|---|---|---|---|---|---|---|
mcp.boostecom.app | /<storeId> → /api/mcp/v1/<storeId>, plus ses .well-known | CNAME cname.vercel-dns.com | domaine ajoute au meme projet | rewrite par host : mcp.*/:id → /api/mcp/v1/:id, /.well-known/* passe tel quel ; tout autre chemin 404 (le dashboard ne doit pas repondre sur cet hote) | pas de cookie de session necessaire (Bearer) ; CORS inchange (les clients MCP sont serveur a serveur) | l'issuer et resource_metadata derivent de req.url, donc ils suivraient l'hote si le rewrite preserve host ; mais /oauth/authorize doit rester sur www (la session NextAuth est un cookie host-only) : l'issuer devra donc etre fixe sur www et non derive, sinon le consentement s'ouvre sur un hote sans session. Les URLs www/api/mcp/... deja collees dans Claude, ChatGPT, Cursor restent servies indefiniment : le resource OAuth est lie a l'URL appelee, une redirection casserait les jetons emis |
cdn.boostecom.app | assets Blob publics | CNAME vers Vercel | Vercel Blob n'accepte pas de domaine personnalise : il faut un rewrite cdn.*/:path* → https://<store>.public.blob.vercel-storage.com/:path* (egress facture deux fois : fonction ou edge + Blob), ou un CDN tiers devant | rewrite par host | img-src / media-src de src/lib/security/csp.ts:153 et images.remotePatterns de next.config.mjs:91 a completer ; aucun cookie | aucune. Les URLs deja persistees en base gardent l'hote Blob : il faut soit une reecriture a l'affichage, soit une migration de donnees. Gain surtout cosmetique |
preview.boostecom.app | proxy de preview storefront | CNAME vers Vercel | domaine ajoute au projet | deja prevu : src/app/api/preview/proxy/route.ts et storefront-origin-preview-host.ts l'attendent ; il suffit de changer DEDICATED_PREVIEW_HOST et de restreindre cet hote au seul proxy | meme site que www : un cookie Lax accompagne les fetchs, ce que boostecom.vercel.app empeche. Il faut donc que le proxy ne lise aucun cookie de session sur cet hote, et que la CSP de ce document ne l'autorise pas a appeler l'API | aucune. C'est le gain de securite reel (isoler du HTML tiers hors de l'origine du dashboard) |
api.boostecom.app | API Intelligence (bei_…) | CNAME | domaine au projet | rewrite api.*/:path* → /api/intelligence/:path* | Bearer, pas de cookie ; CORS a ouvrir si des appels navigateur sont vises | aucune ; la doc content/docs/en/api-* a mettre a jour, les anciennes URLs gardees |
og.boostecom.app | non recommande | /api/og n'est lu que par des crawlers, le chemin n'est jamais vu | ||||
hooks.boostecom.app | non recommande | chaque URL de webhook est enregistree chez Stripe, Shopify, Resend, GitHub, Meta : tout changement se re-saisit a la main, sans gain visible |
Recommandation
Ordre par rapport gain / risque : preview d'abord (securite, code deja
pret), puis mcp (lisibilite de l'URL que le client colle, a condition de
garder l'issuer sur www et de servir les deux formes), puis api. cdn
seulement si la marque blanche des URLs d'assets devient une exigence
client : aujourd'hui elle coute une migration de donnees et de l'egress.