Hub documentation
Éditeurs de confiance
É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 vie | Jusqu'à révocation | 1 heure |
| Stockage | Secret CI | Rien à stocker |
| Rotation | Manuel | Automatique, à chaque exécution |
| En cas de fuite | Valide jusqu'à révocation | Au 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-trainingbranch=mainworkflow=publish.yml
repositoryseul limite l’éditeur à un dépôt GitHub. Ajoutezbranchet/ouworkflowpour 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_RESOURCEpour 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 :
- GitHub Actions —
github.com/coyotte508/publish-to-hf - GitLab CI —
gitlab.com/coyotte508/publish-to-hf
Deux variantes : les éditeurs de dépôts et les identités CI/CD
| Saveur | Configuré sur | Ce que vous obtenez | L'utiliser pour… |
|---|---|---|---|
| Éditeur de dépôt de confiance | Les Paramètres → Éditeurs de confiance d’un dépôt | Un 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 compte | Les Paramètres d’authentification → Accès CI/CD de votre compte | Un jeton en lecture seule avec l'étendue gated-repos, ainsi que inference-api si vous optez pour cette option | Lisez 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-modelSur 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-modelLe 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 cloneou un outil qui litHF_TOKEN) ?hf auth tokeneffectue 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-modelComme 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.pyLes é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 | Émetteur | Comment obtenir le jeton d'identification |
|---|---|---|
| GitHub Actions | https://token.actions.githubusercontent.com | Définissez permissions: id-token: write, puis appelez le point de terminaison de métadonnées avec audience=https://huggingface.co. Docs. |
| GitLab CI | https://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. |
| CircleCI | https://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 Pipelines | https://api.bitbucket.org/2.0/workspaces/<workspace>/pipelines-config/identity/oidc | Dé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
- 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, …).
- Votre workflow
POSTe ce jeton àhttps://huggingface.co/oauth/token, accompagné d’unresource(le dépôt ou le nom d’utilisateur auquel il souhaite accéder). - 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 :
| Champ | Requis | Valeur |
|---|---|---|
grant_type | oui | urn:ietf:params:oauth:grant-type:token-exchange |
subject_token_type | oui | urn:ietf:params:oauth:token-type:id_token |
subject_token | oui | Le jeton d’identification OIDC brut (JWT) de votre fournisseur CI. Sa revendication aud doit être https://huggingface.co. |
resource | oui | Un 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 :
error | Pourquoi |
|---|---|
invalid_request | Paramètre manquant ou mal formé, ou format resource invalide. |
invalid_grant | Dé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-modelne 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-repospar défaut — aucune écriture, aucun dépôt privé, aucune gestion de compte. Le périmètre facultatifinference-apiajoute 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_refde 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
- Jetons d’accès utilisateur — le bon choix pour les humains et les scripts ponctuels
- OAuth / Connexion avec HF — le même point de terminaison
/oauth/token, utilisé pour les flux interactifs - Gérer les Spaces avec GitHub Actions
- Intégration de GitHub Actions pour le Hub