docs/TROUBLESHOOTING.md · erreurs réelles du lab

Dépannage : erreur → correctif

Règle numéro 1 : quand OpenCode se comporte mal après le login, commencer par inspecter les claims du jeton d’accès — le symptôme y est presque toujours déjà écrit.

Diagnostics rapides

Les commandes qui disent tout

# Pile
docker compose ps
curl -sI http://127.0.0.1:8080/mcp | head -15
curl -s http://127.0.0.1:8080/.well-known/oauth-protected-resource/mcp

# OpenCode
opencode mcp list
ss -ltnp | grep 19876 || echo "callback port free"

# Jeton (après une tentative de login)
python3 - <<'PY'
import json
from pathlib import Path
from jose import jwt
p = Path.home() / ".local/share/opencode/mcp-auth.json"
if not p.exists():
    print("no mcp-auth.json")
else:
    at = json.loads(p.read_text())["ords-mcp"]["tokens"]["accessToken"]
    c = jwt.get_unverified_claims(at)
    print("aud        ", c.get("aud"))
    print("roles2     ", c.get("roles2"))
    print("permissions", c.get("permissions"))
    print("scope      ", c.get("scope"))
    print("sub        ", c.get("sub"))
PY

# Erreurs JWT côté ORDS
docker logs ords 2>&1 | grep -iE 'JWT|Role Claim|JWK|Forbidden' | tail -20

Erreurs Auth0 (navigateur)

Côté Auth0

« … is not in the list of allowed callback URLs »

Cause : la redirection d’OpenCode n’est pas dans les Allowed Callback URLs de l’app Native.

Correctif : ajouter exactement :

http://127.0.0.1:19876/mcp/oauth/callback

(et http://localhost:19876/mcp/oauth/callback si besoin). Le chemin doit inclure /mcp/oauth/callback.

« Grant type 'authorization_code' not allowed »

Cause : app en Machine to Machine, ou grant Authorization Code désactivé.

Correctif : type d’application = Native (ou SPA) ; Advanced → Grant Types → Authorization Code (+ Refresh Token) → Save. Passer M2M → Native désactive Client Credentials sur cette app — normal pour OpenCode.

ORDS annonce https://my-proxy/mcp mais le client utilise https://my-proxy/ords/mcp

Cause : le proxy mappe https://my-proxy/ords/ → http://ords (en enlevant le préfixe). MCP est une ressource à la racine de l’hôte (/mcp), pas sous standalone.context.path. ORDS reconstruit la ressource depuis Host + /mcp. Il n’existe pas de réglage de préfixe public, et l’audience ne réécrit pas les URL annoncées.

Correctif : servir MCP sur un hôte dédié (https://ords-mcp.company.com/mcp) sans enlever de préfixe. Voir reverse proxy.

« Service not found: http://127.0.0.1:8080/mcp »

Cause : Auth0 n’a pas d’API dont l’Identifier est exactement cette chaîne. OpenCode envoie resource=http://127.0.0.1:8080/mcp ; une API nommée seulement https://ords.lab/mcp ne correspond pas.

Correctif : créer l’API avec l’Identifier exactement http://127.0.0.1:8080/mcp (http, 127.0.0.1, port 8080, chemin /mcp). Mettre AUTH0_AUDIENCE et l’audience ORDS à la même valeur ; recréer le volume ords-config si ORDS avait l’ancienne audience. Le texte côté Auth0 ressemble à : Service not enabled within domain : http://127.0.0.1:8080/mcp.

« Grant type 'password' / 'password-realm' not allowed »

Cause : l’app Native n’active pas le Resource Owner Password.

Correctif : normal pour OpenCode (qui utilise le code d’autorisation). Pour les tests scripts/test_auth0.py : soit activer le grant password sur une app dev uniquement (déconseillé en prod), soit utiliser les jetons OpenCode / une app confidentielle séparée.

Erreurs CLI OpenCode

Côté OpenCode

« Authentication failed » (message vide)

Causes fréquentes : 1) port 19876 déjà pris par un autre processus opencode ; 2) le serveur de callback n’a pas pu démarrer ; 3) navigateur fermé avant la fin du CLI.

Correctif :

ss -ltnp | grep 19876
kill <pid>          # le opencode qui tient le port
rm -f ~/.local/share/opencode/mcp-auth.json
set -a && source .env && set +a
opencode mcp auth ords-mcp

Navigateur : « Authorization successful » · CLI : « Unexpected status: needs_auth »

Signification : l’échange du code a souvent réussi (vérifier mcp-auth.json pour un accessToken), mais OpenCode ne peut pas utiliser MCP. Réponse ORDS typique avec ce jeton : 403 Forbidden.

ClaimMauvaisBon
roles2[] ou absent["POOL.FIN"]
permissions[]["urn:oracle:dbtools:ords:mcpserver:all"]

Correctif :

  1. L’utilisateur a un rôle Auth0 (POOL.FIN / POOL.HR)
  2. Rôle → Permissions inclut la permission MCP sur l’API http://127.0.0.1:8080/mcp
  3. L’Action post-login pose bien roles2
  4. API : RBAC + « Add Permissions in the Access Token »
  5. opencode mcp logout && opencode mcp auth à nouveau

Une fois corrigé, opencode mcp list affiche connected (OAuth).

opencode mcp list → needs authentication (après un auth réussi)

Identique au cas ci-dessus : le jeton existe mais ORDS le refuse (401/403). Inspecter les claims et les logs ORDS.

Pas d’onglet APIs/Permissions sur l’application Native

Normal. Configurer via Applications → APIs (resource server) et Roles → Permissions — pas la liste M2M des apps Native.

Erreurs ORDS (logs / HTTP)

Côté ORDS

Missing Role Claim / Unsupported Role Claim Format

JSON Web Token Validation Error: Unsupported Role Claim Format / Missing Role Claim

Cause : le jeton n’a pas de tableau roles2 exploitable (ou ORDS pointe toujours sur un mauvais claim).

Correctif : l’Action doit faire setCustomClaim("roles2", roles) — pas "roles" ; MCP_ROLE_CLAIM=/roles2 et recréer la config ORDS si besoin ; se reloguer après le déploiement de l’Action.

HTTP 401 Unauthorized sur /mcp avec jeton Bearer

Causes : signature invalide, mauvais iss/aud, JWKS injoignable, claim de rôle absent.

Correctif :

HTTP 403 Forbidden sur /mcp avec jeton Bearer

Cause (ce lab) : JWT valide mais pas de scope/permission MCP et/ou rôle non autorisé pour un pool.

Correctif : ajouter la permission API au rôle Auth0 ; s’assurer que roles2 contient POOL.HR et/ou POOL.FIN ; se ré-authentifier.

No JWK State / UnknownHostException Auth0

Cause : le conteneur ORDS ne résout pas ou n’atteint pas Auth0.

Correctif : vérifier le DNS/réseau du conteneur ; le compose lab définit un DNS public sur ords. Redémarrer ords.

ORDS se ferme : « AUTH0_DOMAIN required »

Correctif : définir AUTH0_DOMAIN dans .env ; docker compose up -d ords.

Base / données

HR / FIN / utilisateurs MCP absents

Cause : sql/01_lab_schemas.sql ne s’exécute qu’à la première création du volume de données Oracle.

Correctif :

docker compose down -v
docker compose up -d --build

ou appliquer le SQL manuellement sur FREEPDB1 en tant que SYS.

Dérive de config

Audience ou claim modifiés, ORDS encore à l’ancienne valeur

docker compose stop ords && docker compose rm -f ords
docker volume rm ords_ords-config
docker compose up -d ords

scripts/configure-mcp.sh s’exécute à chaque démarrage et applique .env.

Checklist mentale

Un système qui marche