DevOps — SLO, chaîne d'approvisionnement, observabilité LLM
1. SLO + error budget par application
Dans le tableau de bord
- Sidebar → Apps → cliquer votre application → onglet SLO
- Bouton ‘Define SLO’ → target 0.999 + fenêtre 30 jours
- Sparkline burn-down apparaît dans le même onglet
- Bouton ‘Embed badge’ copie markdown pour README
Définissez une application et liez-y des metrics :
Ou via API (avancé — pour automatisation)
curl -X POST https://app.monsys.ai/api/v1/apps \ -H "Authorization: Bearer $TOKEN" \ -d '{ "name": "checkout-api", "type": "http", "agent_id": "<agent_uuid_of_web_lb>", "endpoint": "https://checkout.example.com/healthz", "interval_seconds": 30 }'Définissez SLO + fenêtre :
curl -X POST https://app.monsys.ai/api/v1/apps/<app_id>/slo \ -H "Authorization: Bearer $TOKEN" \ -d '{ "target": 0.999, "window_days": 30, "minimum_data": 0.95 }'/operations/mttr affiche par application :
- Uptime rolling 30j actuel (% et minutes-down)
- Error budget restant (en minutes)
- Sparkline burn-down (taux actuel vs cible)
- “Jours avant épuisement du budget” si vous continuez à brûler au rythme de cette semaine
Pour votre sprint review : récupérez le CSV SLO via
/api/v1/apps/<id>/slo/history?days=90. Pour votre deploy-gate,
vérifiez que le burn rate était < 2.0 dans la dernière heure.
2. Alerte Slack/ntfy quand un conteneur redémarre > 3× en une heure
Dans le tableau de bord
- Sidebar → Settings → Alert rules → ‘Nouvelle règle’
- Metric : container_restart_count, opérateur >, seuil 3, window 1h
- Champ webhook URL : https://hooks.slack.com/services/T0/B0/xxx
- WebhookDispatchWorker fait retries + ne lâche jamais secrets
monsys.ai ne poste pas directement sur Slack — il poste sur ntfy (self-host) ou via un webhook. Exemple webhook Slack :
Ou via API (avancé — pour automatisation)
curl -X POST https://app.monsys.ai/api/v1/alert-rules \ -H "Authorization: Bearer $TOKEN" \ -d '{ "name": "Container flapping", "metric": "container_restart_count", "operator": ">", "threshold": 3, "window": "1h", "severity": "warning", "group_by": ["agent_id", "container_name"], "webhook_url": "https://hooks.slack.com/services/T0/B0/xxx" }'WebhookDispatchWorker fait le POST sortant avec un body JSON minimal
({title, severity, agent, link}) — pas de contenu de prompts ni de
secrets. Retries 3× avec backoff. Logs dans /audit-log event_type
webhook_delivery.
3. Auto-update des deps npm vulnérables, mais pinner notre driver DB
Dans le tableau de bord
- Sidebar → Recommandations → onglet ‘Application CVEs’
- Par package vulnérable : bouton ‘Auto-update’ ou ‘3-points → Suppress this fix’
- Sur suppression : saisir expires_at + raison
- Future Auto-update-all montre skip avec raison dans les preuves mensuelles
Le scanning CVE des dépendances applicatives tourne toutes les heures.
Ouvrez /recommendations → “Application CVEs” → mettons que vous voyez
12 paquets avec des fixes disponibles.
Cliquez “Auto-update all” — conditions :
- TOTP requis
- Plafonné à 25 EATs par clic (évite un blast sur toute la flotte)
- Par (project, ecosystem) chaque hôte reçoit un EAT avec la liste combinée
Pour pinner un paquet (par ex. mysql2@2.3.0 car 2.4.x a un ABI
break) ? Ajoutez une suppression :
Ou via API (avancé — pour automatisation)
curl -X POST https://app.monsys.ai/api/v1/cve-suppressions \ -H "Authorization: Bearer $TOKEN" \ -d '{ "package_name": "mysql2", "ecosystem": "npm", "version_range": ">=2.4.0", "reason": "ABI break — see PROD-123 ticket", "expires_at": "2026-09-01" }'Les futurs auto-update-all sautent cet upgrade ET notent dans les preuves qu’il a été sauté avec la raison fournie.
4. Détecter un changement de mainteneur npm (indicateur d’attaque chaîne d’approvisionnement)
Dans le tableau de bord
- Sidebar → Inventaire → onglet Dependencies → filtre ‘Maintainer changed (7d)’
- Par package : maintainer set actuel + précédent
- Cliquer package suspect → ‘Pin version’ ou ‘Investigate’
- Hit déclenche automatiquement webhook vers outillage incident
Depuis schema 076 monsys trace l’ensemble des publish-emails par paquet npm dont vous dépendez. Changement = alerte.
Ou via API (avancé — pour automatisation)
SELECT package_name, ecosystem, maintainers, deprecated, last_maintainer_change_at, seen_at FROM supply_chain_maintainer_cache WHERE tenant_id = $1::UUID AND last_maintainer_change_at >= NOW() - INTERVAL '7 days' ORDER BY last_maintainer_change_at DESC;Workflow sur un hit :
- Vérifier si le nouveau mainteneur est un collaborateur d’org légitime (souvent oui → accepter le changement dans l’UI)
- Sinon : pinner la version actuelle via
cve_suppressions+ ouvrir un ticket upstream - Optionnel : déclencher un EAT
IsolateNetworksur les hôtes staging qui ont déjà installé le paquet
5. Config Terraform-managed vs drift detection
Dans le tableau de bord
- Sidebar → Settings → API tokens → générer token scoped readonly
- Sidebar → AI Insights → ‘Deploy gate template’ → copier snippet bash
- Coller dans CI yaml avant l’étape deploy
- Tester avec —dry-run — affiche Trust Score + alertes critiques ouvertes
On suppose que Terraform est la source de vérité pour
/etc/ssh/sshd_config. Drift = quelqu’un a fait une modification
manuelle.
Ou via API (avancé — pour automatisation)
# Après chaque terraform apply réussi : bumper la baselinecurl -X POST https://app.monsys.ai/api/v1/agents/<id>/config-hashes/rebase \ -H "Authorization: Bearer $TOKEN" \ -d '{ "paths": ["/etc/ssh/sshd_config", "/etc/nginx/nginx.conf"], "reason": "terraform apply commit 7a3c…" }'Drift dans les 7 jours après un rebase baseline par quelqu’un d’autre que le service-user Terraform = ticket automatique dans votre issue tracker via WebhookDispatch.
6. Coût LLM par équipe via SDK
Dans le tableau de bord
- Sidebar → AI → onglet ‘Par équipe’
- Groupement par défaut sur tag ‘team’ du SDK
- Filtre descending sur coût OU latence p95
- Bouton ‘Export CSV mois’ pour cross-charge financière
Ou via API (avancé — pour automatisation)
# Dans votre service Pythonfrom monsys_ai import MonsysClient
client = MonsysClient( hub_url="https://hub.monsys.ai", api_key=os.environ["MONSYS_AI_TOKEN"], tenant="acme", team="checkout", # → tag sur chaque trace)
with client.trace("price-lookup") as t: resp = openai.chat.completions.create(...) t.add_llm_call( model=resp.model, prompt_tokens=resp.usage.prompt_tokens, completion_tokens=resp.usage.completion_tokens, )Dans /ai/quadrant vous voyez par équipe : coût, latence p95, top 3
modèles, taux de refus. Export CSV pour la cross-charge mensuelle.
La redaction PII se fait dans le SDK, pas au hub. L’agent ne voit jamais le prompt brut — uniquement les compteurs de tokens et un hash SHA256 du prompt pour le dédup.
7. Deploy gate : bloquer la release si une alerte critique est ouverte
Dans le tableau de bord
- Sidebar → Webhooks → ‘Register endpoint’
- URL + HMAC secret partagé + events filter (alert.created, alert.resolved)
- Min severity = warning + agent_filter sur tag
- Retries 3× avec backoff ; failures atterrissent dans audit_log
Pour votre pipeline CI :
Ou via API (avancé — pour automatisation)
#!/usr/bin/env bash# Avant `helm upgrade` / `kubectl apply` etc.OPEN_CRITICAL=$(curl -s \ "https://app.monsys.ai/api/v1/alerts?severity=critical&is_resolved=false&tag=production" \ -H "Authorization: Bearer $MONSYS_TOKEN" | jq '. | length')
if [[ "$OPEN_CRITICAL" -gt 0 ]]; then echo "✗ refusing deploy: $OPEN_CRITICAL critical alerts open on production" exit 1fi
# Gate Trust ScoreSCORE=$(curl -s "https://app.monsys.ai/api/v1/trust-score/v12/tenant" \ -H "Authorization: Bearer $MONSYS_TOKEN" | jq '.final_score')
if [[ "$SCORE" -lt 70 ]]; then echo "✗ refusing deploy: Trust Score $SCORE/100 below threshold 70" exit 1fi
echo "✓ Trust Score $SCORE, no open critical alerts — proceeding"Évite l’anti-pattern “deploy maintenant, regarder les alertes plus tard”.
8. Intégration webhook avec votre propre outillage incident-response
Dans le tableau de bord
- Sidebar → Settings → ‘Embed badge’ (panneau Trust Score)
- Copier URL SVG avec votre tenant_id
- Coller markdown dans README ou status-page interne
- Mise à jour toutes les 30 min, pas de JS, pas de tracking
WebhookDispatchWorker fait un POST sur chaque alerte avec severity ≥
warning. Enregistrez un endpoint custom :
Ou via API (avancé — pour automatisation)
curl -X POST https://app.monsys.ai/api/v1/webhooks \ -H "Authorization: Bearer $TOKEN" \ -d '{ "url": "https://incidents.acme.com/api/v1/intake", "secret": "shared-hmac-secret", "events": ["alert.created","alert.resolved"], "min_severity": "warning", "agent_filter": {"tag":"production"} }'Forme du body :
{ "event": "alert.created", "alert": { "id": "…", "severity": "critical", "category": "cpu", "title": "Host CPU > 95% sustained 10min", "agent": { "id": "…", "hostname": "web-03", "tags": ["production"] } }, "tenant_id": "…", "timestamp": "2026-05-19T20:34:00Z"}Headers :
X-Monsys-Signature: sha256=…(HMAC sur body avecsecret)X-Monsys-Delivery: <uuid>(clé d’idempotence)X-Monsys-Event: alert.created
Retries : 3× avec backoff exponentiel (10s / 60s / 5min). L’échec
final atterrit dans /audit-log comme webhook_delivery_failed et
votre endpoint passe en cooldown 10 min pour éviter les hot loops.
9. Badge Trust Score dans votre README/dashboard
Ou via API (avancé — pour automatisation)
SVG server-rendered. Mise à jour toutes les 30 minutes (cycle worker Trust Score). Le badge colorie par bande : <50 rouge, 50-70 orange, 70-85 vert, >85 vert foncé. Pas de JavaScript, pas de tracking — rendu directement depuis TimescaleDB.
Tip pour orgs multi-tenant : par repo, utilisez le tenant id du projet (DEV, STG, PROD séparés) et mettez 3 badges côte à côte — visible immédiatement si staging diffère de production.