Hub documentation

Éditeurs de confiance

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Éditeurs de confiance

Pousser vers le Hub depuis CI sans stocker un secret HF_TOKEN.

Votre tâche CI prouve son identité à Hugging Face à l’aide d’un jeton OpenID Connect (OIDC) à durée de vie courte fourni par votre fournisseur CI, et reçoit en échange un jeton Hugging Face à durée de vie courte. Aucun jeton HF à stocker en tant que secret ni à faire tourner.

Jeton d'accès personnelÉditeur de confiance
Durée de vieJusqu'à révocation1 heure
StockageSecret CIRien à stocker
RotationManuelAutomatique, à chaque exécution
En cas de fuiteValide jusqu'à révocationAu maximum ~1 heure, et limité à un seul dépôt

Les Trusted Publishers reposent sur le même principe que les Trusted Publishers de PyPI et le Trusted Publishing de npm.

Exemple rapide : publier un modèle depuis GitHub Actions

Vous maintenez acme/awesome-model sur le HF Hub et souhaitez que la CI d’un dépôt hébergé en externe, acme/awesome-model-training (sur GitHub, GitLab ou tout fournisseur compatible OIDC), pousse de nouveaux checkpoints — sans secret HF_TOKEN.

1. Configurer l’éditeur de confiance sur le Hub

Sur https://huggingface.co/acme/awesome-model/settings, ouvrez Trusted Publishers et ajoutez :

  • Fournisseur : GitHub Actions
  • Claims (toutes doivent correspondre pour que l'échange réussisse :
    • repository = acme/awesome-model-training
    • branch = main
    • workflow = publish.yml

repository seul limite l’éditeur à un dépôt GitHub. Ajoutez branch et/ou workflow pour l’ancrer également à une branche ou à un fichier de workflow — recommandé.

2. Ajouter le workflow à votre dépôt GitHub

.github/workflows/publish.yml:

name: Publish to Hugging Face

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest

    permissions:
      id-token: write  # required so the job can request an OIDC token
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Install the hf CLI
        run: |
          curl -LsSf https://hf.co/cli/install.sh | bash
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"

      - name: Upload checkpoint
        env:
          # The HF repo to publish to. For non-model repos, prefix accordingly:
          #   datasets/acme/awesome-dataset, spaces/acme/awesome-space, kernels/acme/awesome-kernel
          HF_OIDC_RESOURCE: acme/awesome-model
        run: hf upload acme/awesome-model ./checkpoint . --commit-message "Publish from ${GITHUB_SHA::7}"

C’est tout. Sur GitHub Actions, le CLI hf (huggingface_hub>=1.19.0) détecte le fournisseur, effectue l’échange et utilise automatiquement le jeton résultant. Vous n’avez qu’à définir HF_OIDC_RESOURCE.

Publier dans plusieurs dépôts lors d'une seule exécution (par exemple, un modèle et un jeu de données) ? Définissez HF_OIDC_RESOURCE pour chaque étape afin que chaque jeton soit limité au dépôt vers lequel cette étape pousse.

Autres fournisseurs de CI

La CLI hf génère le jeton d’identification nativement uniquement sur GitHub Actions pour le moment. Sur GitLab, CircleCI, Bitbucket ou tout autre fournisseur, générez le jeton d’identification vous-même (voir Fournisseurs CI pris en charge) et transmettez-le via HF_OIDC_ID_TOKEN — la CLI l’échange directement :

# GitLab CI (.gitlab-ci.yml)
publish:
  id_tokens:
    HF_ID_TOKEN:
      aud: https://huggingface.co
  script:
    - curl -LsSf https://hf.co/cli/install.sh | bash
    - export PATH="$HOME/.local/bin:$PATH"
    - HF_OIDC_ID_TOKEN="$HF_ID_TOKEN" HF_OIDC_RESOURCE="acme/awesome-model" hf upload acme/awesome-model ./checkpoint .

Exemples complets et fonctionnels :

Deux variantes : les éditeurs de dépôts et les identités CI/CD

SaveurConfiguré surCe que vous obtenezL'utiliser pour…
Éditeur de dépôt de confianceLes Paramètres → Éditeurs de confiance d’un dépôtUn jeton avec un accès en écriture à ce dépôt unique (ou un accès en lecture seule)Publier un modèle, un jeu de données, un Space, un kernel ou un bucket depuis CI, ou en tirer un privé
Identité CI/CD du compteLes Paramètres d’authentification → Accès CI/CD de votre compteUn jeton en lecture seule avec l'étendue gated-repos, ainsi que inference-api si vous optez pour cette optionLisez les dépôts à accès restreint auxquels vous avez accès, utilisez vos limites de débit et, le cas échéant, appelez les fournisseurs d'inférence depuis CI

Les deux jetons expirent après 60 minutes. Vous avez besoin du rôle Write sur un dépôt du Hub pour gérer ses éditeurs de confiance.

Accéder aux dépôts restreints depuis CI

Si vous n'avez besoin que de lire des dépôts restreints (par exemple, pour télécharger un modèle depuis un job), ajoutez une identité CI/CD sur votre compte sous Authentication settings → CI/CD Access plutôt que sur un dépôt spécifique, puis utilisez votre username en tant que ressource.

Sur GitHub Actions, le CLI hf effectue l’échange à votre place, il suffit de définir HF_OIDC_RESOURCE :

      - name: Download a gated model
        env:
          HF_OIDC_RESOURCE: your-hf-username
        run: hf download acme/gated-model

Sur les autres fournisseurs, générez le jeton d’identification vous-même (voir Autres fournisseurs CI) et transmettez-le via HF_OIDC_ID_TOKEN :

# $ID_TOKEN is the OIDC token your provider minted (e.g. $HF_ID_TOKEN on GitLab)
HF_OIDC_ID_TOKEN="$ID_TOKEN" HF_OIDC_RESOURCE="your-hf-username" hf download acme/gated-model

Le jeton résultant peut lire les dépôts gérés auxquels vous avez accès et utilise les limites de débit de votre compte. Il ne peut rien écrire et ne peut pas lire vos dépôts privés. Pour récupérer un dépôt privé depuis une CI, utilisez plutôt un éditeur de dépôt en lecture seule.

Besoin du jeton lui-même (pour curl, git clone ou un outil qui lit HF_TOKEN) ? hf auth token effectue l’échange et affiche le jeton à durée de vie courte sur la sortie standard :

      - name: Get a short-lived HF token
        env:
          HF_OIDC_RESOURCE: your-hf-username  # or a repo, e.g. acme/awesome-model
        run: echo "HF_TOKEN=$(hf auth token)" >> "$GITHUB_ENV"

Cela fonctionne avec les identités CI/CD comme avec les éditeurs de dépôt — le jeton est limité à la ressource vers laquelle pointe HF_OIDC_RESOURCE.

Éditeurs de dépôts en lecture seule

Par défaut, un éditeur de confiance d’un dépôt émet des jetons permettant de pousser vers le dépôt. Si une charge de travail n’a besoin que de tirer un dépôt (par exemple, pour télécharger un modèle ou un jeu de données privé depuis un travail CI ou une plateforme externe qui émet ses propres jetons OIDC), cochez Lecture seule lors de l’ajout de l’éditeur. Les jetons échangés peuvent alors lire le contenu du dépôt mais ne peuvent pas y écrire, et l’entrée affiche un badge Lecture seule dans la liste. Cela fonctionne pour les modèles, les jeux de données, les Spaces, les noyaux et les buckets.

L'échange lui-même n'est pas modifié. Pointez HF_OIDC_RESOURCE (ou resource) vers le dépôt.

    permissions:
      id-token: write  # required so the job can request an OIDC token

    steps:
      - name: Download a private model
        env:
          HF_OIDC_RESOURCE: acme/private-model
        run: hf download acme/private-model

Comme pour les autres paramètres de l’éditeur, l’autorisation est fixée à la création. Pour la modifier, supprimez l’éditeur puis ajoutez-le à nouveau.

Appeler les fournisseurs d'inférence depuis CI

Les jetons issus d’une identité CI/CD sont en lecture seule par défaut. Pour leur permettre d’appeler également les Inference Providers, cochez Allow Inference Providers calls lors de l’ajout de l’identité — les jetons échangés portent alors l’étendue inference-api en plus de gated-repos, et l’entrée affiche un badge Inference dans la liste.

L’utilisation de l’inférence est facturée à votre compte, exactement comme si vous aviez effectué les requêtes vous-même — veillez donc à restreindre strictement les autorisations (repository et branch et/ou workflow) avant de l’activer.

      - name: Run inference from CI
        env:
          HF_OIDC_RESOURCE: your-hf-username
        run: |
          export HF_TOKEN="$(hf auth token)"
          python inference_script.py

Les éditeurs de dépôts ne sont pas éligibles — leurs jetons sont limités au dépôt et ne peuvent pas appeler les fournisseurs d’inférence. Cette capacité est fixée à la création ; pour la modifier, supprimez l’identité puis ajoutez-la à nouveau.

Fournisseurs CI pris en charge

L’interface de configuration est livrée avec des préréglages pour les fournisseurs ci-dessous, mais tout fournisseur compatible OIDC fonctionne (AWS, GCP, Buildkite, votre propre IdP, …).

FournisseurÉmetteurComment obtenir le jeton d'identification
GitHub Actionshttps://token.actions.githubusercontent.comDéfinissez permissions: id-token: write, puis appelez le point de terminaison de métadonnées avec audience=https://huggingface.co. Docs.
GitLab CIhttps://gitlab.com (ou votre URL auto-hébergée)Déclarez id_tokens: { HF_ID_TOKEN: { aud: https://huggingface.co } } sur le job ; lisez $HF_ID_TOKEN. Docs.
CircleCIhttps://oidc.circleci.com/org/<org-uuid>Utilisez $CIRCLE_OIDC_TOKEN_V2 (v2 permet de définir l’audience dans les paramètres du projet). Docs.
Bitbucket Pipelineshttps://api.bitbucket.org/2.0/workspaces/<workspace>/pipelines-config/identity/oidcDéfinissez oidc: true sur l’étape ; lisez $BITBUCKET_STEP_OIDC_TOKEN. Docs.

Une fois que vous avez le jeton d’identification, l’appel d’échange est identique pour tous les fournisseurs — seules les claims que vous configurez côté Hub diffèrent.

Fonctionnement

  1. Votre fournisseur de CI génère un jeton d’identification OIDC à durée de vie courte décrivant le travail (dépôt, branche, workflow, …).
  2. Votre workflow POSTe ce jeton à https://huggingface.co/oauth/token, accompagné d’un resource (le dépôt ou le nom d’utilisateur auquel il souhaite accéder).
  3. Le Hub vérifie la signature et les revendications du jeton par rapport aux éditeurs que vous avez configurés pour cette ressource, puis renvoie un jeton Hugging Face.
┌──────────┐  1. mint ID token   ┌──────────┐  2. exchange   ┌────────────┐
│ CI job   │ ─────────────────▶  │ CI OIDC  │ ──────────────▶│ huggingface│
│          │                     │ issuer   │                │  /oauth/   │
│          │ ◀──────────────────────────────────────────────│  token     │
└──────────┘        3. short-lived HF token (valid 1 h)      └────────────┘

Référence de l'API

Endpoint, request, and response

Point de terminaison : POST https://huggingface.co/oauth/token avec Content-Type: application/json.

Aucune authentification client n’est requise — le jeton d’identification OIDC authentifie la requête. L’échange suit RFC 8693 — OAuth 2.0 Token Exchange.

Corps de la requête :

ChampRequisValeur
grant_typeouiurn:ietf:params:oauth:grant-type:token-exchange
subject_token_typeouiurn:ietf:params:oauth:token-type:id_token
subject_tokenouiLe jeton d’identification OIDC brut (JWT) de votre fournisseur CI. Sa revendication aud doit être https://huggingface.co.
resourceouiUn dépôt Hub (namespace/name, datasets/namespace/name, spaces/namespace/name, kernels/namespace/name, buckets/namespace/name) ou un username Hub (sans barre oblique) pour un jeton de portée utilisateur.

Réponse de succès :

{
  "access_token":      "hf_jwt_…",   // "hf_oauth_…" for user resources
  "token_type":        "bearer",
  "expires_in":        3600,
  "issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}

Erreurs — 400 Bad Request avec un corps au format OAuth :

errorPourquoi
invalid_requestParamètre manquant ou mal formé, ou format resource invalide.
invalid_grantDépôt ou utilisateur introuvable ; aucun éditeur ne correspond à cet émetteur ; les revendications configurées ne correspondent pas ; échec de la vérification de la signature ou de l'audience ; compte verrouillé.

Lorsque le CLI hf effectue l'échange, une erreur affiche le code error accompagné d'un (Request ID: …) — incluez cet identifiant de requête lors de la déclaration d'un problème afin que nous puissions retracer l'échange dans nos journaux.

Modèle de sécurité

  • Les jetons sont à durée de vie courte. 60 minutes à compter du moment de l'échange — le chronomètre ne démarre que lorsque vous appelez le point de terminaison, et non lorsque le flux de travail démarre. Il n'existe pas de jeton de rafraîchissement ; les tâches de longue durée doivent rééchanger.
  • Les jetons de dépôt sont limités au dépôt concerné. Un jeton pour acme/awesome-model ne peut pas accéder à acme/anything-else. Les pousses sont attribuées à un utilisateur système synthétique [OIDC], avec une référence à l’émetteur et au sujet d’origine. Les jetons d’un éditeur en lecture seule ne peuvent que lire ce dépôt.
  • Les jetons d'utilisateur sont en lecture seule. gated-repos par défaut — aucune écriture, aucun dépôt privé, aucune gestion de compte. Le périmètre facultatif inference-api ajoute les appels Inference Providers (facturés à votre compte), mais toujours sans accès en écriture ni aux dépôts privés.
  • Les revendications sont appariées exactement, ou par préfixe si un préréglage de fournisseur l’exige (le workflow_ref de GitHub). Aucune expression régulière.
  • Journaux d’audit. L’ajout ou le retrait d’un éditeur est consigné, et les échanges réussis mettent à jour l’heure de dernière utilisation.

Voir aussi

Update on GitHub