[Auth] Keyless CI/CD auth via OIDC token exchange#4326
Conversation
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
| def detect_provider() -> str | None: | ||
| """Detect the CI provider able to mint an OIDC id token, or `None` if not in a supported CI.""" | ||
| if os.environ.get("GITHUB_ACTIONS") == "true": | ||
| return GITHUB | ||
| return None | ||
|
|
There was a problem hiding this comment.
maybe add a way to pass the ID token directly for other providers than Github
eg HF_OIDC_ID_TOKEN=... HF_OIDC_RESOURCE=... hf upload ...
so the Gitlab example can also be simplified!
There was a problem hiding this comment.
in addition of HF_OIDC_ID_TOKEN we could also support Gitlab, etc. natively (can be a follow-up PR)
There was a problem hiding this comment.
Thanks for the PR! I left some cosmetic changes but otherwise looks good to me.
Could you also update the PR description with a more up-to-date example? e.g. install hf CLI using installer. Also potentially could be a more complex example pushing to both a dataset and a model at the end of a training step => would need to set HF_OIDC_RESOURCE per step targeting different resources. (asking because example will likely be copied to release notes)
Once merged the follow-up would be:
- update hub-docs
- add support/examples for more providers
Co-authored-by: Lucain <lucain@huggingface.co>
|
@Wauplin updated the PR description with a better example ✔️ |
|
I'm talking care of the follow-up PRs as well |
julien-c
left a comment
There was a problem hiding this comment.
This is very elegantly implemented! kudos
|
This PR has been shipped as part of the v1.19.0 release. |
This PR lets CI jobs authenticate to the Hub without storing an
HF_TOKENsecret, using the Hub's Trusted Publishers. SetHF_OIDC_RESOURCEto the repo (or username) to scope a short-lived token to, andhuggingface_hubdoes the OIDC exchange under the hood, no token, no setup code.Example: publish a model and a dataset from one training run
Under the hood,
get_token()gains a last-resort source: whenHF_OIDC_RESOURCEis set and a supported CI provider is detected, it mints the provider's OIDC id token, exchanges it atPOST /oauth/tokenfor a short-lived Hub token, and caches it.Note
High Risk
Changes core authentication in
get_token()and introduces token exchange; misconfiguration or exchange failures affect all Hub calls whenHF_OIDC_RESOURCEis set.Overview
Adds Trusted Publishers keyless CI auth: CI jobs can authenticate to the Hub via OIDC token exchange instead of storing
HF_TOKEN.A new internal
_oidcmodule mints GitHub Actions OIDC id tokens (whenpermissions: id-token: writeis set) and exchanges them atPOST /oauth/token(RFC 8693), scoped withresource. Other providers can pass a pre-minted id token viaHF_OIDC_ID_TOKEN.get_token()now tries OIDC last whenHF_OIDC_RESOURCEis set (repo or username to scope the token). Failures raiseOIDCErrorinstead of silently returning unauthenticated. Exchanged tokens are cached with refresh before expiry for auto-minted GitHub flows.Debug
HF_DEBUGcurl logging redacts OAuth body fields such assubject_token.Reviewed by Cursor Bugbot for commit a48753a. Configure here.