Skip to content

Brancher une application sur le SDK Auth

Guide pratique pour connecter une nouvelle application au SSO Heriade via @heriade-app/auth-sdk. Il complete la reference d'architecture du SDK, qui decrit l'API ; ici on couvre la plomberie (acces au package prive, .npmrc, CI, Docker, hebergement) et les pieges rencontres lors du premier pilote (contact).

A garder en tete

Le package est prive sur GitHub Packages. Il ne s'installe pas comme un package npm public : il faut un token d'acces a chaque endroit qui fait install, y compris les builds Docker isoles et l'hebergeur. C'est 90 % du travail d'onboarding.

Vue d'ensemble du flux

console-admin (proprietaire)          application consommatrice
  packages/heriade-auth-sdk    ─────►   .npmrc + dep par workspace
  publie 0.x.y sur                      ├─ CI            (GITHUB_TOKEN)
  npm.pkg.github.com                    ├─ build Docker  (PAT en build-arg)
                                        └─ hebergeur     (PAT en variable)

Prerequis

  1. Autoriser le repo a lire le package. Sur github.com/heriade-app/console-adminPackagesauth-sdkPackage settingsManage Actions access → ajouter le repo consommateur en Read. Sans ca, GITHUB_TOKEN de la CH du repo ne peut pas telecharger le package (403 read package).
  2. Un PAT classique read:packages pour tout ce qui tourne hors GitHub Actions (build Docker local, Railway, Scaleway...). GITHUB_TOKEN n'existe qu'a l'interieur d'un job Actions. Cree un fine-grained token avec le scope Packages: read (ou un classic PAT read:packages).

Secrets

Ne colle jamais un token dans un commit, un chat ou une capture d'ecran. Un token expose est compromis : revoque-le et regenere-le. Les tokens vivent dans les secrets CI et les variables d'hebergeur, jamais dans le code.

Etape 1 — .npmrc a la racine

Cree (ou complete) le .npmrc a la racine du repo :

ini
@heriade-app:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}

Le token n'est pas ecrit en dur : il est resolu depuis la variable d'environnement NODE_AUTH_TOKEN au moment de l'install.

yarn v1

Yarn classic echoue durement si ${NODE_AUTH_TOKEN} n'est pas resolu (Failed to replace env in config). Dans un monorepo, ca casse tous les install, pas seulement ceux qui touchent le SDK. Il faut donc que la variable soit presente partout ou un install tourne.

Etape 2 — Declarer la dep dans chaque workspace qui l'importe

C'est le piege n°1. Chaque workspace dont le code importe le SDK doit le declarer dans son propre package.json :

jsonc
// apps/web/package.json  ET  apps/api/package.json
"dependencies": {
  "@heriade-app/auth-sdk": "^0.3.0"
}

Hoisting trompeur

Si un seul workspace le declare, le hoisting yarn le rend disponible aux autres → la CI passe. Mais un build Docker qui n'installe qu'un seul workspace echouera avec Cannot find module '@heriade-app/auth-sdk'. Regle : qui importe declare.

Etape 3 — Plomber le token dans la CI

Dans chaque workflow qui fait un install (CI, deploy, e2e...) :

yaml
permissions:
  contents: read
  packages: read          # autorise GITHUB_TOKEN a lire le package

env:
  NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Dans GitHub Actions, secrets.GITHUB_TOKEN suffit (pas besoin de PAT), a condition d'avoir fait l'etape Prerequis 1 (Read access) et d'avoir mis packages: read.

Etape 4 — Builds Docker isoles

Un build Docker ne voit ni ton ~/.npmrc, ni le GITHUB_TOKEN d'Actions. Il faut lui passer un PAT en build-arg, copier le .npmrc, puis nettoyer le token du runtime.

dockerfile
# --- Build stage ---
FROM node:20-bullseye-slim AS builder
WORKDIR /app

ARG NODE_AUTH_TOKEN
ENV NODE_AUTH_TOKEN=$NODE_AUTH_TOKEN

COPY .npmrc ./
COPY package.json yarn.lock ./
# ... copie des package.json de workspaces ...
RUN yarn install --frozen-lockfile
# ... build ...

# --- Production stage ---
FROM node:20-bullseye-slim
WORKDIR /app

# L'ARG ne traverse PAS les stages : le redeclarer.
ARG NODE_AUTH_TOKEN
ENV NODE_AUTH_TOKEN=$NODE_AUTH_TOKEN

COPY .npmrc ./
# ... install prod ...

ENV NODE_ENV=production
# Le token n'a servi qu'au build : on le vide du runtime pour ne pas le fuiter.
ENV NODE_AUTH_TOKEN=""

Cote pipeline qui build l'image :

yaml
- uses: docker/build-push-action@v6
  with:
    build-args: |
      NODE_AUTH_TOKEN=${{ secrets.GITHUB_TOKEN }}

Multi-stage

Un ARG ne traverse pas les stages. Si l'install a lieu dans les deux stages (build et prod, ex. Prisma), il faut redeclarer ARG NODE_AUTH_TOKEN et recopier .npmrc dans chaque stage. Verifie l'absence de fuite : docker inspect sur l'image finale ne doit pas exposer le token.

Etape 5 — Hebergeur (Railway, Scaleway...)

Si l'hebergeur build depuis les sources (hors Actions), il n'a pas de GITHUB_TOKEN. Fournis-lui le PAT classique :

  • Railway : variable de service NODE_AUTH_TOKEN=<PAT> (utilisee par le build Nixpacks/Docker).
  • Image pre-buildee (Scaleway registry) : le token a deja ete injecte au build via le build-arg, rien a ajouter au runtime.

Etape 6 — Prisma et image de base (si backend Prisma)

Independant du SDK mais rencontre pendant le pilote : Prisma detecte la libssl au build. node:20-slim a derive vers bookworm (libssl3) ou Prisma 5.x retombe sur openssl-1.1.x et plante au runtime (Schema engine error ... failed to detect libssl).

Fix connu-qui-marche : epingler la base sur node:20-bullseye-slim (libssl 1.1) dans tous les stages. A moyen terme, la voie propre est bookworm + binaryTargets explicites dans schema.prisma.

Etape 7 — Migrer le code

Cote code, suivre la reference d'architecture :

  • Front : remplacer la copie locale d'auth par createHeriadeAuthClient, brancher handleCallback sur la page de callback, remplacer le wrapper fetch par authFetch.
  • Back : remplacer le guard custom par extractAppAccessToken + verifyAppAccessToken (import depuis @heriade-app/auth-sdk/server), ou par l'introspection centralisee POST /auth-app/context.
  • Supprimer les anciens fichiers d'auth dupliques.

Checklist de validation

Avant de considerer l'app branchee :

  • [ ] .npmrc racine avec les 2 lignes (registry + _authToken).
  • [ ] SDK declare dans le package.json de chaque workspace qui l'importe.
  • [ ] NODE_AUTH_TOKEN + packages: read dans tous les workflows qui font install.
  • [ ] Dockerfiles : ARG/ENV/COPY .npmrc dans chaque stage qui installe, token vide dans l'image finale.
  • [ ] Variable NODE_AUTH_TOKEN (PAT) sur l'hebergeur si build hors Actions.
  • [ ] CI verte + deploiements verts.
  • [ ] Test SSO reel : login → refresh silencieux → 401 retry → logout → reconnexion.

Publier une nouvelle version du SDK (mainteneurs)

Depuis console-admin :

  1. bump version dans packages/heriade-auth-sdk/package.json (semver) ;
  2. merger sur staging → le workflow publish-auth-sdk.yml fait npm install + npm run build + npm publish sur GitHub Packages ;
  3. bumper la contrainte ^x.y.z dans les apps consommatrices, puis install.

Build dual-format

Le SDK est publie en ESM + CommonJS (tsup) avec des types dedies par condition (index.d.ts pour import, index.d.cts pour require). C'est ce qui permet de le consommer depuis un front ESM (Nuxt/Vite) et un back NestJS (CommonJS). Ne pas casser cette dualite : un SDK ESM-only provoque TS1479 cote NestJS.

Pieges rencontres — memo

SymptomeCauseFix
403 read package en CIrepo pas autorise sur le packageManage Actions access → Read
403 write_package a la publicationrepo publieur sans WriteManage Actions access → Write (console-admin)
Failed to replace env in config: ${NODE_AUTH_TOKEN}yarn v1 sans la variableplomber NODE_AUTH_TOKEN dans le job
Cannot find module '@heriade-app/auth-sdk' en Dockerdep non declaree dans le workspacedeclarer la dep dans son package.json
TS1479 (require ESM) cote NestJSSDK ESM-onlybuild dual-format (deja en place)
Token present dans l'image finalepas vide entre stagesENV NODE_AUTH_TOKEN="" en fin de Dockerfile
Prisma failed to detect libssl au runtimebase derivee vers bookworm/libssl3node:20-bullseye-slim