Créer / connecter un compte Datadog
Cette skill amène l'utilisateur à un état connu et validé : une clé API valide + clé d'application, sur la bonne région, validée contre l'API Datadog. C'est l'« étape 0 » dont dépendent les skills de setup/instrumentation — exécutez-la en premier, puis transmettez.
C'est un flux guidé autonome : détecte ce qui existe déjà, et quand rien d'exploitable n'est trouvé, se connecte via OAuth (navigateur, PKCE + state) ou crée un nouveau compte (en terminal, avec un mot de passe généré sauvegardé dans .env), puis transforme cette session en clé API. Tout s'exécute en petites commandes bash + curl inline (OAuth utilise aussi openssl) — aucun script groupé, aucun node ; multiplateforme (macOS, Linux, Windows via WSL/Git Bash).
Ce SKILL.md en est la colonne vertébrale — il porte les courtes étapes inline et renvoie vers references/ pour la machinerie lourde par étape. Lisez une référence seulement quand vous atteindrez l'étape qui la nomme.
Le flux en un coup d'œil
headless demandé ? ──oui──▶ Étape H: clés env uniquement (OAuth nécessite un navigateur), valider, terminer
│non (défaut — interactif)
▼
Étape 1 Détecter les credentials existants (env)
│
▼
Étape 2 Déterminer région / site (DD_SITE → valider; sinon détection IP → confirmer)
│
▼
Étape 3 S'authentifier — demander d'abord (même si des clés env ont été détectées) → references/authenticate.md
│ └─ QUESTION : comment se connecter ? ↴
│ ├─ A. Utiliser la clé env détectée (uniquement si l'une existe) → valider → Étape 5
│ ├─ B. Se connecter (j'ai un compte) → OAuth (navigateur, PKCE + state) ──▶ Bearer token
│ └─ C. Créer un nouveau compte → Chemin C: signup auto en terminal, mot de passe généré ──▶ puis OAuth
▼
Étape 4 Transformer la session OAuth en clé API → references/get-api-key.md
│ (identité + région via /current_user; OAuth→récupérer clé la plus récente, app-key→créer → écrire droit dans .env; sinon guider vers la page UI des clés)
▼
Étape 5 Charger les credentials depuis .env, valider, transmettre
Règle d'or : ne jamais deviner ou fabriquer une clé API, clé d'application, token ou site. Lisez ce qui est dans l'environnement, validez-le, et s'il n'y est pas, authentifiez-vous — ne procédez pas sur des hypothèses.
Conventions d'affichage et de formulation — à lire une fois avant l'étape 1
Chaque étape obéit aux mêmes règles sur la façon de parler à l'utilisateur et de rendre les progrès : le contrat de présentation clean-status-line, demander avec le sélecteur natif du host (jamais l'entrée de lettres), et la checklist de progrès en direct avec sa discipline de marqueur. Ceux-ci se trouvent dans references/conventions.md — lisez-le avant l'étape 1 et appliquez-le partout. Chaque étape ci-dessous se termine par un indice ↳ Checklist: vous disant ce qu'il faut cocher.
Étape 0 — Préparation (tableau de readiness)
Exécutez ceci une fois, en premier, pour que l'utilisateur voit le chemin complet avant que quoi que ce soit ne se produise — quels outils sont présents, ce qui est déjà détecté, et ce que le flux fera (notamment qu'il ouvre le navigateur une fois). Il n'écrit rien et ne révèle aucun secret. Chaque invocation exécute le flux complet depuis l'étape 1 — il n'y a pas de reprise/saut ; une exécution antérieure n'est pas réutilisée.
DDLOG="${TMPDIR:-/tmp}/dd-onboard-$(id -u).log"; : >"$DDLOG" # journal frais pour cette exécution
mark(){ command -v "$1" >/dev/null 2>&1 && echo "✓" || echo "$2"; }
# python3 gère le callback de navigateur auto; repli sur python si c'est un vrai py3.
have_py3(){ command -v python3 >/dev/null 2>&1 && return 0; command -v python >/dev/null 2>&1 && python -c 'import sys;exit(0 if sys.version_info[0]==3 else 1)' 2>/dev/null; }
py3msg(){ have_py3 && echo '✓ (callback de navigateur auto)' || echo '⊘ (il faudra coller l'URL de redirection)'; }
echo "Setup du compte Datadog — préparation"
echo " dépendances (requises): bash ✓ curl $(mark curl ✗) openssl $(mark openssl ✗)"
echo " dépendances (optionnelles): python3 $(py3msg) browser-open $( { command -v open >/dev/null 2>&1 || command -v xdg-open >/dev/null 2>&1; } && echo ✓ || echo '⊘ (ouvrir l'URL manuellement)')"
# Chargeur DD_* canonique — ce même bloc est répété intégralement dans les étapes ultérieures car chaque ```bash exécute un shell frais (sans dérive).
# Charger DD_* avec précédence : env shell > .env.local > .env. Une vraie var env n'est jamais écrasée ; les guillemets environnants sont supprimés. *_SRC enregistre d'où chacune vient (non défini ⇒ de l'env shell).
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && { export "$k=$v"; eval "${k}_SRC=$f"; }; done; done
echo " credentials détectés: DD_SITE=${DD_SITE:-<non défini>}${DD_SITE_SRC:+ [$DD_SITE_SRC]} DD_API_KEY=$([ -n "$DD_API_KEY" ] && echo "défini …${DD_API_KEY: -4}${DD_API_KEY_SRC:+ [$DD_API_KEY_SRC]}" || echo '<non défini>') DD_APP_KEY=$([ -n "$DD_APP_KEY" ] && echo "défini${DD_APP_KEY_SRC:+ [$DD_APP_KEY_SRC]}" || echo '<non défini>')"
echo " ce qui se passe: confirmer région → s'authentifier (ouvre votre navigateur une fois) → obtenir une clé API → l'écrire dans .env → valider. ~2 min, une approbation navigateur."
[ "$(mark curl ✗)" = ✗ ] || [ "$(mark openssl ✗)" = ✗ ] && echo " ✗ dépendance requise manquante ci-dessus — installez-la avant de continuer."
Lisez le tableau à l'utilisateur tel quel (c'est déjà propre). Si une dépendance requise est manquante, arrêtez et dites-le. Puis cochez l'étape 1 de la checklist et continuez — allez toujours à l'étape 1 ; ne sautez jamais à une étape ultérieure.
↳ Checklist: affichez le tableau, puis la checklist ; marquez 1. Détecter les credentials ◔.
Étape H — Sans navigateur / non-interactif (pas de navigateur, pas de prompts)
Décidez ceci en premier, car les chemins du navigateur + signup sont impossibles sans un humain. Déduisez sans navigateur de la demande de l'utilisateur elle-même, pas de l'environnement — le déclencheur est la requête de l'utilisateur : ils demandent explicitement d'exécuter sans navigateur ou sans prompts interactifs (ex. « configurer Datadog de manière non-interactive », « je suis en CI, pas de navigateur »).
Ne déduisez pas sans navigateur simplement d'une absence de TTY — une exécution de terminal ordinaire obtient toujours le flux interactif. Seule une demande explicite l'éteint.
Quand vous avez déduit une demande sans navigateur, exécutez le bloc ci-dessous — et seulement alors. Il n'y a pas de navigateur pour OAuth et pas d'humain pour répondre aux prompts de signup, donc le seul chemin vers un état valide est avec des clés déjà fournies. Exigez DD_API_KEY, DD_APP_KEY, et DD_SITE, et échouez rapidement sinon :
# Exécutez ce bloc UNIQUEMENT quand vous avez déduit une demande non-interactive. Il applique la seule chose
# que sans navigateur a besoin — des clés déjà présentes — et échoue rapidement si l'une manque.
# Charger DD_* (env > .env.local > .env), même précédence que l'étape 1 — les clés CI vivent souvent dans .env, pas exportées.
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
missing=""
[ -z "$DD_API_KEY" ] && missing="$missing DD_API_KEY"
[ -z "$DD_APP_KEY" ] && missing="$missing DD_APP_KEY"
[ -z "$DD_SITE" ] && missing="$missing DD_SITE"
[ -n "$missing" ] && { echo "Le mode non-interactif exige :$missing — définissez-les et réexécutez. La connexion et la création de compte d'essai nécessitent un navigateur."; exit 1; }
Si tous les trois sont définis, transmettez à l'étape 5, qui valide la clé via /api/v1/validate (fonctionne avec l'en-tête DD-API-KEY). Note : /api/v1/validate vérifie DD_API_KEY uniquement — DD_APP_KEY est requis mais non indépendamment vérifié ici ; une mauvaise clé d'app/expirée apparaît plus tard lors du premier appel dans le champ d'application de la clé d'app. Il n'y a pas de fallback OAuth ou signup en mode sans navigateur — les deux nécessitent un navigateur — donc échouez avec le message ci-dessus et gardez les logs actionnables.
↳ Checklist (sans navigateur): deux éléments seulement — une fois la validation réussie, cochez les deux et sautez à l'étape 5.
Étape 1 — Détecter les credentials existants
Lisez l'environnement et les fichiers .env / .env.local du projet. Ne relisez pas les valeurs complètement à l'utilisateur ; masquez-les.
# Charger DD_* avec précédence : env shell > .env.local > .env (la vraie var env gagne ; guillemets supprimés). *_SRC = fichier d'où il provient (non défini ⇒ env shell).
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && { export "$k=$v"; eval "${k}_SRC=$f"; }; done; done
echo "DD_SITE = ${DD_SITE:-<non défini>}${DD_SITE_SRC:+ (depuis $DD_SITE_SRC)}"
echo "DD_API_KEY= $( [ -n "$DD_API_KEY" ] && echo "défini (…${DD_API_KEY: -4})${DD_API_KEY_SRC:+ (depuis $DD_API_KEY_SRC)}" || echo "<non défini>" )"
echo "DD_APP_KEY= $( [ -n "$DD_APP_KEY" ] && echo "défini (…${DD_APP_KEY: -4})${DD_APP_KEY_SRC:+ (depuis $DD_APP_KEY_SRC)}" || echo "<non défini>" )"
- Une
DD_API_KEYest présente (env ou.env/.env.local) → allez à l'étape 2 (épingler le site), puis à l'étape 3 et demandez (choix A = utiliser la clé détectée, ou B/C pour s'authentifier / créer un compte différent). La clé détectée est une option que l'utilisateur confirme à l'étape 3, pas une valeur par défaut à utiliser silencieusement — ils peuvent vouloir une org ou un compte différent. - Pas de
DD_API_KEYnulle part → l'utilisateur n'a rien d'exploitable pour le moment. Faites quand même l'étape 2 (pour que le signup les place sur la bonne région), puis allez à l'étape 3, où vous poserez comment se connecter.
Une clé d'app sans clé api n'est pas suffisante ; traitez-la comme « pas de clé ». Parce que le shell ne persiste pas entre les blocs, chaque bloc ultérieur qui consomme $DD_API_KEY réexécute ce même chargeur en haut — c'est pourquoi il réapparaît dans le chemin A, l'étape 4, et l'étape 5.
↳ Checklist: affichez la liste maintenant — cochez 1. Détecter les credentials, marquez 2. Confirmer région ◔.
Étape 2 — Déterminer région / site
Le site pilote chaque URL en aval (signup, hôte API, pages de clés), donc épinglez-le avant de valider. La table de région et le mapping pays→région par IP se trouvent dans references/regions.md.
-
Si
DD_SITEest défini (env ou.env) : validez-le contre la liste de sites autorisés dansreferences/regions.md. S'il n'est pas dans cette liste, arrêtez et affichez une erreur claire :DD_SITE="<valeur>"n'est pas un site Datadog reconnu. Choisissez l'une des régions dansreferences/regions.mdet définissezDD_SITEen conséquence. -
Si
DD_SITEn'est pas défini : auto-détectez la région depuis la localisation de l'utilisateur, puis confirmez — ne validez jamais une région silencieusement.country=$(curl -s --max-time 2 https://ipinfo.io/json \ | grep -o '"country"[^,]*' | grep -o '"[A-Z][A-Z]"' | tr -d '"') echo "Pays détecté : ${country:-inconnu}"Mappez le pays à une région en utilisant la table Pays → mapping région dans
references/regions.md. En cas de timeout, d'erreur, ou d'absence de correspondance, par défaut US1 (datadoghq.com) — et dites-le. Puis dites à l'utilisateur, par ex. :Vous semblez être en DE → proposant EU1 (Frankfurt),
datadoghq.eu. Utiliser celui-ci, ou en choisir un autre région ci-dessous ?Attendez une confirmation. La région ne peut pas être changée après la création d'un compte, donc ce choix compte.
L'hôte API est uniformément https://api.${DD_SITE}.
↳ Checklist: après que l'utilisateur confirme la région, cochez 2. Confirmer région, marquez 3. S'authentifier ◔.
Étape 3 — S'authentifier
Demandez comment se connecter en premier — même quand l'étape 1 a détecté des credentials env — puis exécutez le chemin que l'utilisateur choisit. Présentez « Le choix » avant de toucher à n'importe quel credential : une DD_API_KEY ambiante peut appartenir à une org ou un compte différent de celui que l'utilisateur a l'intention, et région/IP ne peuvent pas révéler lequel, donc laissez l'utilisateur décider plutôt que de le déduire. (Sans navigateur/Étape H est exempté — pas de TTY pour demander, clés env uniquement.)
La documentation complète — le libellé du sélecteur natif de « Le choix » plus les trois chemins — se trouve dans references/authenticate.md :
| L'utilisateur choisit | Chemin | Ce que cela fait |
|---|---|---|
| Utiliser mes credentials existants (offert seulement si l'étape 1 a détecté une clé) | A | Valide la clé détectée (capte aussi une clé mauvaise région → retour à l'étape 2). |
| Se connecter — j'ai déjà un compte | B | OAuth dans le navigateur (PKCE + state), Bearer token vers un fichier 0600. |
| Créer un nouveau compte (défaut) | C | Signup automatisé en terminal avec un mot de passe généré → puis chemin B. |
Lisez references/authenticate.md, présentez le choix via le sélecteur natif du host, et exécutez le chemin correspondant. Ré-offrez le choix chaque fois qu'un chemin atteint une impasse (OAuth ne trouve pas de compte → C ; une clé mauvaise région a renvoyé l'utilisateur à l'étape 2 en premier).
↳ Checklist: gardez 3. S'authentifier ◔ jusqu'à ce qu'un token ou une clé soit réellement en main (voir les indices par chemin dans
references/authenticate.md).
Étape 4 — Transformer la session OAuth en clé API
Le token OAuth authentifie l'utilisateur, mais l'instrumentation en aval a besoin d'une DD_API_KEY. Utilisez le Bearer token pour confirmer l'identité, puis obtenez une clé — récupérez la clé la plus récente de l'org sur une session OAuth (les tokens OAuth ne peuvent pas créer de clés), ou créez-en une lors de l'authentification avec une clé d'app ; sinon guidez l'utilisateur vers la page UI des clés.
La branche complète (vérification d'identité, retrieve-vs-create, le bloc balisé par code HTTP, et la table de résultats pour EMPTY_ORG / LIST_DENIED / SECRET_DENIED / CREATE_DENIED / TRANSPORT_ERROR) se trouve dans references/get-api-key.md — suivez-la. Le secret est écrit directement dans .env, jamais affiché.
↳ Checklist: une fois qu'une clé validée est en main, cochez 4. Obtenir & valider une clé API, marquez 5 ◔.
Étape 5 — Confirmer et transmettre
La clé est déjà dans .env. Chargez-la et validez-la (un shell frais à chaque appel — toujours charger .env d'abord en le analysant, jamais le source, donc un .env conçu ne peut pas s'exécuter ; ne jamais intégrer la clé littérale) :
DDLOG="${TMPDIR:-/tmp}/dd-onboard-$(id -u).log"; tf="${TMPDIR:-/tmp}/dd-oauth-$(id -u).token"
# Charger DD_* (env > .env.local > .env) — analyser, ne pas sourcer, pour qu'un .env conçu ne puisse pas s'exécuter. Couvre une clé du chemin-A qui vit uniquement dans l'env shell ou .env.local.
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
vcode=$(curl -sg -o "$DDLOG" -w '%{http_code}' -H "DD-API-KEY: $DD_API_KEY" "https://api.${DD_SITE}/api/v1/validate")
# redériver org/email pour la carte (shell frais — les vars de l'étape 4 ne persistent pas) ; seulement si un token est toujours présent
who=""; [ -s "$tf" ] && who=$(curl -sg -H "Authorization: Bearer $(cat "$tf")" "https://api.${DD_SITE}/api/v2/current_user" 2>>"$DDLOG" | grep -oE '"email"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | cut -d'"' -f4)
# carte de credential cohérente 🔑 — l'endroit unique où l'état du credential est résumé ; secret montré seulement comme 4 derniers
echo "🔑 Credential Datadog"
[ -n "$who" ] && echo " org: $who"
echo " région: ${DD_SITE}"
echo " clé api: …${DD_API_KEY: -4} (dans .env — jamais imprimée intégralement)"
echo " statut: $([ "$vcode" = 200 ] && echo '✓ validé (HTTP 200)' || echo "✗ valider HTTP $vcode — voir : tail -n 30 \"$DDLOG\"")"
- La carte ci-dessus est le résumé canonique — ne dumpez pas aussi la réponse raw validate. Sur un non-200, surfacez
tail -n 30 "$DDLOG"et traitez-la selon la table de résultats (un403ici est généralement mauvaise région → étape 2). - Rapportez l'org/email authentifiée de l'appel d'identité.
- Les credentials vivent tous dans
.env(DD_SITE,DD_API_KEY, etDD_SIGNUP_PASSWORDsi le compte a été créé via le chemin C) — écrits là directement, jamais affichés. Nettoyez les fichiers temp de signup et les fichiers OAuth state + callback :rm -f "${TMPDIR:-/tmp}"/dd-signup-$(id -u).* "${TMPDIR:-/tmp}"/dd-oauth-$(id -u).state "${TMPDIR:-/tmp}"/dd-oauth-$(id -u).cb. - Handoff en aval — gardez le token OAuth. Laissez
${TMPDIR:-/tmp}/dd-oauth-$(id -u).token(0600) en place. L'instrumentation en aval réutilise ce Bearer token pour provisionner des ressources qu'une clé API basique ne peut pas créer — notamment une application RUM. Il est de courte durée et dans un champ d'application ; l'appelant du onboarding (par ex. l'orchestrateur) le supprime une fois que le setup se termine (rm -f "${TMPDIR:-/tmp}"/dd-oauth-$(id -u).token). Exécution de l'instrumentation en autonome ? Supprimez-le vous-même quand vous avez terminé. - Transmettre : « Le compte est prêt. Vous pouvez maintenant exécuter l'étape de setup / instrumentation. » (par ex.
studio-setup,browser-rum-setup,llm-observability-setup, ou n'importe quelle skill*-setup).
↳ Checklist: cochez 5. Prêt — transmettre — affichez la liste entièrement complétée pour que l'utilisateur voit que le flux est terminé.
Dépannage et référence
Quand une étape échoue, voir references/troubleshooting.md — la table symptôme→fix (mauvaise région, déaccord d'état OAuth, sortie sans navigateur, erreurs de signup du chemin C, …) plus les notes de décision de conception et d'état temp.