Authentification et sécurité
Sécuriser votre application ChatGPT
Une application qui manipule des données utilisateur, se connecte à des API et traite des paiements doit être sécurisée dès la conception. Le Apps SDK intègre des mécanismes d’authentification et de sécurité que vous devez comprendre et configurer correctement.
Les modes d’authentification
Le SDK supporte trois modes d’authentification selon votre cas d’usage :
| Mode | Cas d'usage | Complexité |
|---|---|---|
| Aucune | App publique sans données personnelles | Minimale |
| Clé API | Service tiers avec clé utilisateur | Simple |
| OAuth 2.0 | Connexion à un compte utilisateur | Standard |
OAuth 2.0 : le standard recommandé
Pour la plupart des applications, OAuth 2.0 est le choix approprié. Il permet à l’utilisateur de connecter son compte sans partager son mot de passe.
Configuration dans le manifest
{
"auth": {
"type": "oauth2",
"clientId": "${OAUTH_CLIENT_ID}",
"authorizationUrl": "https://monsite.com/oauth/authorize",
"tokenUrl": "https://monsite.com/oauth/token",
"scopes": ["read:profile", "write:orders"],
"pkce": true
}
}
Flux côté serveur
// Votre serveur OAuth
app.get("/oauth/authorize", (req, res) => {
const { client_id, redirect_uri, state, code_challenge } = req.query;
// Vérifier le client_id
if (client_id !== process.env.CHATGPT_APP_CLIENT_ID) {
return res.status(400).json({ error: "Client inconnu" });
}
// Afficher la page de connexion / consentement
res.render("authorize", { state, redirect_uri, scopes: req.query.scope });
});
app.post("/oauth/token", async (req, res) => {
const { code, code_verifier } = req.body;
// Vérifier le code et le PKCE verifier
const session = await validateAuthCode(code, code_verifier);
res.json({
access_token: session.accessToken,
refresh_token: session.refreshToken,
expires_in: 3600,
token_type: "Bearer",
});
});
Utiliser le token dans les actions
app.action("getMyOrders", {
description: "Récupère les commandes de l'utilisateur connecté",
auth: "required", // Force l'authentification
handler: async (_, context) => {
// Le token est automatiquement disponible
const response = await fetch("https://api.monsite.com/me/orders", {
headers: {
Authorization: `Bearer ${context.auth.accessToken}`,
},
});
return response.json();
},
});
Authentification par clé API
Pour les services tiers (Notion, GitHub, etc.), l’utilisateur fournit sa propre clé :
{
"auth": {
"type": "api_key",
"header": "X-API-Key",
"instructions": "Entrez votre clé API depuis les paramètres de votre compte"
}
}
Le SDK stocke la clé de manière sécurisée côté OpenAI. Elle est injectée dans le context de vos actions.
Sécurité des actions
Validation des entrées
Validez toujours les données reçues, même si le schema les type :
import { z } from "zod";
const orderSchema = z.object({
productId: z.string().uuid(),
quantity: z.number().int().min(1).max(100),
couponCode: z.string().optional(),
});
handler: async (params) => {
const validated = orderSchema.parse(params);
// Utiliser validated, pas params
}
Rate limiting
Protégez vos endpoints contre les abus :
export const searchAction = defineAction({
name: "search",
description: "Recherche dans le catalogue",
rateLimit: {
maxCalls: 20, // 20 appels max
windowMs: 60_000, // par minute
perUser: true, // par utilisateur
},
handler: async ({ query }) => { /* ... */ },
});
Protection CSRF et vérification des signatures
Le SDK signe chaque requête envoyée à votre serveur. Vérifiez ces signatures :
import { verifyWebhookSignature } from "@openai/apps-sdk";
app.post("/webhook", (req, res) => {
const isValid = verifyWebhookSignature(
req.body,
req.headers["x-openai-signature"],
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: "Signature invalide" });
}
// Traiter le webhook
});
Bonnes pratiques de sécurité
- Ne stockez jamais de tokens en clair dans votre code ou vos logs
- Activez PKCE pour tous les flux OAuth (protection contre l’interception)
- Validez les entrées avec un schema strict (zod, joi) en plus du typage SDK
- Limitez les scopes OAuth au strict minimum nécessaire
- Vérifiez les signatures de chaque webhook reçu
- Utilisez HTTPS pour tous vos endpoints sans exception
- Expirez les tokens : access_token court (1h), refresh_token plus long (30j)
Mise en pratique
Configurez l’authentification OAuth pour une app qui se connecte à un CRM :
- Définissez les scopes nécessaires (lecture contacts, création opportunités)
- Implémentez les endpoints
/authorizeet/token - Ajoutez une action
getContactsqui utilise le token pour appeler le CRM - Gérez le cas du token expiré avec un refresh automatique
Points clés à retenir
- OAuth 2.0 avec PKCE est le mode recommandé pour la plupart des apps
- Le context des actions contient automatiquement les tokens d’authentification
- Validez les entrées côté serveur même si le SDK les type
- Le rate limiting protège vos endpoints contre les abus
- Vérifiez les signatures des webhooks pour authentifier les requêtes OpenAI