Aller au contenu principal

API HTTP

Disponible

Fonctionnalité déployée et prise en charge. Les champs et commandes décrits ici sont stables au sein de la version v1alpha1.

L'API StackNGO est une API REST en JSON. La CLI sng et la console l'utilisent exclusivement : tout ce qu'elles font, vous pouvez le faire avec curl ou un client généré depuis la spécification OpenAPI.

Adresse et version​

Base URLhttps://api.dev.stackngo.fr/v1
Spécification OpenAPI 3.1https://api.dev.stackngo.fr/v1/openapi.yaml (publique, sans authentification)
VersionTout est préfixé par /v1. Il n'y a pas d'en-tête de version.
SantéGET /healthz (processus vivant), GET /readyz (dépendances prêtes), hors /v1 et sans authentification

Les routes sont documentées une par une dans Endpoints, générées depuis la spécification. Chaque route indique l'action IAM qu'elle exige (deploy:write, ssm:read, …) : c'est ce qu'une policy doit accorder pour qu'elle réponde autre chose que 403.

Authentification en deux temps​

  1. Obtenir un jeton d'identité (OIDC, auprès de https://auth.dev.stackngo.app).
  2. L'échanger contre une session de tenant avec POST /v1/iam/session.
  3. Envoyer la session dans Authorization: Bearer <session> sur toutes les routes du tenant.

Le détail, avec des exemples curl, est dans Authentification. Un seul jeton par requête ; l'en-tête X-Tenant-Token est refusé (400) sur toutes les routes /v1, ouverture de session comprise : la session de tenant suffit.

Conventions de requête​

  • Corps en JSON : Content-Type: application/json obligatoire sur POST, PUT et PATCH qui portent un corps. Sinon 415.
  • Champs inconnus refusés : un champ non prévu dans le corps vaut 400. Les schémas OpenAPI sont donc exhaustifs.
  • Taille : un corps est limité à 1 Mo.
  • Noms dans le chemin : les noms de ressources ({name}, {tenant}) sont des labels DNS en minuscules. Le tenant d'une requête vient toujours de la session, jamais du chemin ni d'un en-tête ; sur les routes /v1/tenants/{tenant}/…, {tenant} doit être celui de la session.

Conventions de réponse​

  • Content-Type: application/json.
  • Les listes renvoient un objet qui enveloppe le tableau, nommé d'après la ressource : {"secrets": […]}, {"apps": […]}, {"items": […]}. Il n'y a pas de pagination : les listes sont complètes.
  • Les créations répondent 201, les suppressions 204 sans corps, le reste 200.
  • Les erreurs ont toutes la forme {"error": "message"}, 415 et 429 compris. Voir Erreurs.
  • Retry-After accompagne les 409 policies_pending (tenant tout juste créé) et les 429.

Limites et délais​

300 requêtes par minute et par adresse IP sur les routes /v1 ; délais serveur de 30 s en lecture et 60 s en écriture. Détail et conseils dans Limites.

Idempotence​

  • PUT /v1/secrets/{name} et PUT /v1/iam/policies/{name} créent ou remplacent : rejouer la même requête donne le même état.
  • POST /v1/apply puis POST /v1/apply/complete sont conçus pour être rejoués : un manifeste identique est marqué unchanged.
  • Les POST d'action (/scale, /restart, /rotate) ne sont pas idempotents.

Générer un client​

curl -fsSL https://api.dev.stackngo.fr/v1/openapi.yaml -o openapi.yaml
npx openapi-typescript openapi.yaml -o stackngo.d.ts # TypeScript
go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest -package stackngo openapi.yaml # Go

La console StackNGO est elle-même générée depuis ce fichier.

Exemple complet​

# 1. Identité (ici : un jeton déjà obtenu par la CLI)
ID_TOKEN=$(yq '.access_token' ~/.config/stackngo/config.yaml)

# 2. Session de tenant
SESSION=$(curl -fsS https://api.dev.stackngo.fr/v1/iam/session \
-H "Authorization: Bearer $ID_TOKEN" -H 'Content-Type: application/json' \
-d '{"tenant":"acme"}' | jq -r .access_token)

# 3. Une route du tenant
curl -fsS https://api.dev.stackngo.fr/v1/secrets -H "Authorization: Bearer $SESSION"
{"secrets":[{"name":"db-password","version_id":"3","version_stages":{"current":"3"},"updated_at":"2026-10-01T09:12:44Z"}]}