docs/WORK_REPRODUCTION.md

Reproduire ce lab au travail

Porter le même modèle de sécurité de Docker + Auth0 + OpenCode vers Kubernetes et un IdP d’entreprise (Entra ID / Okta / Auth0 Enterprise). Le JWT a la même forme — ce qui change, c’est l’environnement.

À garder identique

Ce qui ne change pas

ConceptValeur du labAu travail
Protocole MCPORDS standalone /mcpIdentique (pas de Tomcat pour MCP)
Validation JWTiss, aud, JWKSIssuer d’entreprise + JWKS
Claim des rôlesroles2 (ou nom sûr)Mapper des groupes → mêmes chaînes, ou changer le pointeur ORDS
Chaînes de rôlePOOL.HR, POOL.FINRôles / groupes applicatifs stables
Scope MCP globalurn:oracle:dbtools:ords:mcpserver:allMême chaîne sur l’API / le scope
Liaison poolmcp.role + mcp.scope par poolUn pool par vraie base de données
ClientOpenCode OAuth PKCEOpenCode ou autre client MCP avec OAuth

À faire changer

Ce qui doit changer

LabTravail
API Identifier / URL MCP http://127.0.0.1:8080/mcpURL publique HTTPS, ex. https://ords-mcp.company.com/mcp (hôte dédié ; ne pas retirer /ords — voir reverse proxy)
Tenant Auth0 gratuitEntra ID / Okta / Auth0 Enterprise
Un Oracle Free, deux schémasN bases ; un pool MCP par base
Docker ComposeDeployment + Ingress + Secrets + NetworkPolicy
Mots de passe d’exemple dans .envVault / External Secrets
⚠️ Règle qui reste absolue L’API Identifier (audience) IdP = l’URL MCP exacte utilisée par le client (schéma et chemin compris), parce que les clients envoient OAuth resource= égal à cette URL. MCP est à /mcp sur l’hôte ORDS, pas sous /ords. Un mapping https://my-proxy/ords/ → http://ords fait annoncer à ORDS https://my-proxy/mcp.

Déploiement suggéré

Feuille de route

  1. POC (ce lab) — OpenCode + Auth0 + isolation par rôle prouvée.
  2. ORDS en staging — Ingress HTTPS ; API Identifier = URL publique du MCP ; même modèle roles2 + permissions.
  3. Bascule IdP — pointer le profil JWT ORDS vers l’issuer/JWKS d’entreprise ; mapper les groupes vers POOL.* (ou renommer pools/rôles de façon cohérente).
  4. Catalogue de pools — table GitOps : nom du pool, connexion DB, mcp.role, équipe propriétaire.
  5. Durcissement — utilisateurs DB en lecture seule, réplicas, NetworkPolicy, audit (DBTOOLS$MCP_LOG, module/action de session), jetons de courte durée.

Réglages ORDS à exporter

Depuis scripts/configure-mcp.sh / config courante :

feature.mcp = true
mcp.security.jwt.profile.issuer
mcp.security.jwt.profile.audience          # = URL publique du MCP
mcp.security.jwt.profile.jwk.url
mcp.security.jwt.profile.authorization.server.url
mcp.security.jwt.profile.role.claim.name   # /roles2 ou pointeur du claim entreprise
# par pool :
db.hostname, db.port, db.servicename, db.username
mcp.role, mcp.scope
db.password (wallet / secret)

Mapping IdP

Notes de correspondance

Auth0 (lab)Exemple entreprise
Rôle POOL.FINRôle d’application ou groupe POOL.FIN
Claim roles2Claim personnalisé (éviter les noms réservés par l’IdP)
Permission sur le rôleLe rôle d’app inclut le scope/permission de l’API MCP
App Native + PKCEClient public pour les postes des développeurs
Action post-loginEntra : optional claims / token configuration

OpenCode au bureau

Socle de sécurité

Baseline

Matrice de validation

Tests à réutiliser

TestRésultat attendu
Utilisateur avec POOL.FIN seulementdatabase_list = pool fin uniquement
Utilisateur avec POOL.HR seulementpool hr uniquement
Utilisateur avec les deuxles deux pools
Jeton sans permission MCP403 / client en needs_auth
Jeton sans claim de rôle401 Missing Role Claim
Mauvaise audience401

Passer à l’image de production →