Authentification
S'authentifier auprès des APIs M&NTIS
Les APIs REST M&NTIS (dont l'API Scenario) sont protégées par OpenID Connect (Keycloak). Chaque requête doit porter un jeton d'accès valide dans un en-tête Authorization: Bearer <token>, ainsi que les en-têtes de contexte identifiant l'espace de travail / l'organisation concernés.
Endpoints
Pour un déploiement sur le domaine <votre-domaine> (ex. mantis-platform.io) :
| Rôle | URL |
|---|---|
| Base de l'API (Scenario) | https://app.<votre-domaine>/api/scenario/lab |
| Émetteur OpenID Connect | https://id.<votre-domaine>/realms/mantis |
| Document de découverte OIDC | https://id.<votre-domaine>/realms/mantis/.well-known/openid-configuration |
| Endpoint de jeton | https://id.<votre-domaine>/realms/mantis/protocol/openid-connect/token |
Le document de découverte liste les endpoints et scopes exacts de votre déploiement.
1. Obtenir un jeton d'accès
Connectez-vous une fois avec le CLI mantis, puis échangez depuis votre code le jeton de rafraîchissement qu'il a stocké contre des jetons d'accès. L'identifiant de client est frontend : c'est un client public, identique pour tous les utilisateurs, et ce n'est pas un secret.
mantis user login --domain mantis-platform.io # ouvre un navigateur, une seule fois
mantis user organization # affiche vos ids d'organisation et d'espace de travailLa connexion stocke un jeton de rafraîchissement offline dans ~/.config/mantis/config.yml, sous profiles.<domaine>.refresh_token. Traitez-le comme un mot de passe : à lui seul, il suffit à produire des jetons d'accès. Ce jeton et les deux identifiants sont ce que le reste de cette page attend dans votre shell :
export REFRESH_TOKEN="<profiles.<domaine>.refresh_token, depuis ~/.config/mantis/config.yml>"
export ORGANIZATION_ID="<l'id d'organisation affiché ci-dessus>"
export WORKSPACE_ID="<l'id d'espace de travail affiché ci-dessus>"
export TOKEN="<le jeton d'accès obtenu juste en dessous>"Échangez le jeton de rafraîchissement chaque fois qu'il vous faut un nouveau jeton d'accès :
curl -X POST "https://id.mantis-platform.io/realms/mantis/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=frontend" \
-d "refresh_token=$REFRESH_TOKEN"
# -> {"access_token": "...", "expires_in": ..., "refresh_token": "...", ...}import requests
OIDC = "https://id.mantis-platform.io/realms/mantis/protocol/openid-connect/token"
def get_access_token(refresh_token: str) -> str:
resp = requests.post(
OIDC,
data={
"grant_type": "refresh_token",
"client_id": "frontend",
"refresh_token": refresh_token,
},
)
resp.raise_for_status()
return resp.json()["access_token"]Les jetons d'accès ont une durée de vie courte (quelques minutes) : échangez à la demande plutôt que d'en conserver un. Le jeton de rafraîchissement, lui, ne porte aucune date d'expiration : il reste valable tant qu'il est utilisé, et meurt après une période d'inactivité configurée sur le realm — 30 jours avec les réglages par défaut de Keycloak. Lorsqu'il cesse de fonctionner, l'échange répond 400 invalid_grant : relancez mantis user login et reprenez le nouveau jeton de rafraîchissement. Le CLI mantis réalise exactement cet échange (mantis_api_client/mantis_api_client/oidc.py).
La connexion demande déjà les scopes attendus par l'API — openid, scenario:run et groups — de sorte qu'un jeton obtenu ainsi est accepté par les endpoints de lancement de scénario sans configuration supplémentaire.
Pour une intégration de production non supervisée
Ne bâtissez pas sur un jeton de rafraîchissement adossé au compte personnel de quelqu'un : il hérite du cycle de vie de cette personne, ne peut pas être rotaté indépendamment, et attribue chaque action à son nom. Demandez à votre administrateur M&NTIS un client OIDC dédié et un compte de service membre de l'espace de travail, porteur des scopes openid scenario:run groups.
2. Appeler l'API avec le jeton
Passez le jeton en en-tête Bearer, accompagné des identifiants affichés par mantis user organization :
| En-tête | Valeur | Obligatoire |
|---|---|---|
Authorization | Bearer <access_token> | toujours |
X-Workspace-Id | votre identifiant d'espace de travail | sur les endpoints de scénario |
X-Organization-Id | votre identifiant d'organisation | dès qu'un endpoint résout des permissions, dont la liste des labs |
Envoyez les deux identifiants ensemble, comme le fait le CLI mantis. Un endpoint qui résout des permissions a besoin de l'identifiant d'organisation pour le faire, et répond 500 si seul l'en-tête d'espace de travail est présent.
curl "https://app.mantis-platform.io/api/scenario/lab/version" \
-H "Authorization: Bearer $TOKEN"
curl "https://app.mantis-platform.io/api/scenario/lab/scenario/" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Workspace-Id: $WORKSPACE_ID" \
-H "X-Organization-Id: $ORGANIZATION_ID"import requests
BASE = "https://app.mantis-platform.io/api/scenario/lab"
def api_headers(token: str, workspace_id: str, organization_id: str) -> dict:
return {
"Authorization": f"Bearer {token}",
"X-Workspace-Id": workspace_id,
"X-Organization-Id": organization_id,
}
headers = api_headers(TOKEN, WORKSPACE_ID, ORGANIZATION_ID)
resp = requests.get(f"{BASE}/scenario/", headers=headers)
resp.raise_for_status()
print(resp.json())Certains endpoints de lancement de scénario exigent en plus que le jeton porte des scopes spécifiques (ex. scenario:run). Ils sont indiqués par opération dans la référence de l'API et vérifiés côté serveur.
3. Liens d'accès public (avancé)
Lors de la création d'un lab avec public_access_enabled: true, le client réalise un échange de jeton OIDC pour générer un jeton dédié au lien public, transmis dans le corps de la requête via public_access_config. Voir exchange_token_public_access() dans mantis_authz et create_lab_scenario() dans le client de référence pour le déroulé exact.
Étape suivante
Passez au Démarrage rapide pour lancer un lab de bout en bout.

