How to make an organization access token?
This can get pretty tangled pretty quickly:
I’m not Hugging Face staff, so please treat this as a community answer. But based on the current docs and the older staff discussion around organization tokens, I would not start by looking for a new “organization access token” for this Colab upload workflow.
For normal Hub uploads from Colab / huggingface_hub / CLI, the usual path is:
Use a User Access Token from a user account that has access to the organization. The organization part comes from that user’s organization membership/role, and, for fine-grained tokens, from the token’s resource scope.
So the short version is:
| Goal | What I would use |
|---|---|
| Push model files from Colab to an org repo | A User Access Token with write permission, or preferably a fine-grained token scoped to the target org/repo |
Push to my-org/my-model |
Use repo_id="my-org/my-model" |
| Avoid a broad token in a shared notebook / CI | Use a fine-grained token scoped as narrowly as possible |
| Long-lived automation not tied to one employee | Consider a dedicated “machine user”-style account + fine-grained token |
| Team/Enterprise org with token policies | Check whether the org requires fine-grained tokens or admin approval |
1. The main point: token permission and org role both matter
The current User Access Tokens docs say that User Access Tokens are the preferred way to authenticate an application or notebook to Hugging Face services.
They also describe the practical permission model:
readtoken: can read repos that the user can read.writetoken: can additionally create/push/modify repos that the user has write access to.fine-grainedtoken: can be restricted to specific resources, such as selected repos or organization resources.
For organization repos, there are two separate checks:
| Layer | Example question |
|---|---|
| User’s org role | Is this user allowed to write/admin this organization or repo? |
| Token permission/scope | Does this token allow write access to this target resource? |
A useful mental model is:
Effective access = user/org permissions ∩ token permissions/scope
So, for example:
| User/org situation | Token situation | Likely result |
|---|---|---|
User has only org read role |
write token |
Still not enough to push |
User has org write or admin role |
read token |
Still not enough to push |
User has org write or admin role |
write token |
Should work for normal repo push, assuming repo/type/path are correct |
User has org admin role |
fine-grained token not scoped to the target repo/org | May fail with 403 or repo-not-found-like behavior |
User has org admin role |
fine-grained token scoped correctly | Usually the safer production/shared-notebook path |
The org role side is described in Access control in organizations, where org members can have roles like read, contributor, write, and admin. The token side is described in User Access Tokens.
2. Why “organization access token” is confusing here
There is older wording and older behavior around organization API tokens, so the confusion is understandable.
The important historical context is this forum thread:
- Organization API token deprecation
In that thread, Hugging Face staff explained that organization API tokens were on a deprecation path, and that scoped tokens were intended as the replacement direction before fully removing org-token support. The same staff reply also mentions the common workaround for non-human automation: use a dedicated machineuser-style account and that account’s token.
That maps pretty closely to the current practical answer:
- For a human user in Colab: use that user’s User Access Token.
- For safer automation: use a fine-grained User Access Token.
- For automation that should not die when an employee leaves: use a dedicated machine-user-style account, then create a token from that account.
- For Team/Enterprise cases: also check organization token policies.
Also, the Python client itself points in this direction. In huggingface_hub, login() rejects old api_org... organization tokens and tells you to use a personal account token instead:
- huggingface_hub/_login.py
- huggingface_hub authentication docs
So for a Colab / huggingface_hub.login() / normal upload workflow, I would not try to create or use an old organization token.
3. Practical Colab path
Option A: simple one-off test
For a quick test, create a User Access Token with write permission from:
https://huggingface.co/settings/tokens
Then make sure the user who owns that token has enough permission in the organization, usually write or admin.
In Colab, store the token as a Colab secret or environment variable, commonly HF_TOKEN.
The huggingface_hub quickstart says HF_TOKEN can be used for authentication and that Colab supports private keys/secrets for notebooks. The environment variable docs also say HF_TOKEN overrides the token stored on the machine.
A minimal upload pattern would look like this:
# pip install -U huggingface_hub
import os
from huggingface_hub import HfApi, create_repo, whoami
token = os.environ["HF_TOKEN"]
# Check which HF account this token belongs to.
# Do not print the token itself.
print(whoami(token=token))
repo_id = "<org-name>/<repo-name>"
create_repo(
repo_id=repo_id,
repo_type="model",
private=True,
exist_ok=True,
token=token,
)
api = HfApi(token=token)
api.upload_folder(
folder_path="<local-output-folder>",
repo_id=repo_id,
repo_type="model",
)
The important details are:
| Detail | Why it matters |
|---|---|
repo_id="<org-name>/<repo-name>" |
The namespace is part of repo_id; do not push to your personal namespace by accident |
repo_type="model" |
Use the right repo type: model, dataset, or space |
token=token |
Makes it explicit which token Colab is using |
whoami(token=token) |
Confirms the token owner; browser login and Colab token can be different identities |
For the repo/upload API details, see:
- Create and manage a repository
- Upload files to the Hub
- HfApi client docs
Option B: safer shared notebook / CI pattern
For anything shared or long-lived, I would prefer a fine-grained token:
- Create a fine-grained User Access Token.
- Scope it only to the target organization/repository if possible.
- Give it only the permissions needed for the job.
- Store it as a secret, not directly in the notebook.
This is also the direction suggested by the GitHub Actions docs, which say to create a Hugging Face access token with write permission to the target repo and, for better security, use a fine-grained token scoped only to the repository being synced.
4. Avoid older examples using organization=...
Some older examples and issues mention an organization= argument. I would avoid mixing that mental model with the current repo_id form.
Prefer this:
repo_id = "<org-name>/<repo-name>"
rather than trying to pass the org separately.
There is an old huggingface_hub issue showing how mixing repo_id with the deprecated organization argument could cause confusion:
- huggingface_hub issue #821
For a normal current workflow, repo_id="<org>/<repo>" is the low-confusion form.
5. Troubleshooting table
| Symptom | Most likely checks |
|---|---|
401 Unauthorized |
Token missing, invalid, deleted, not loaded in this runtime |
403 Forbidden |
Token lacks write/scope, user lacks org permission, org token policy blocks this token, token pending/denied/revoked |
Repository Not Found |
Wrong repo_id, wrong repo_type, private repo not accessible to this token, stale/wrong token |
| Works in browser but fails in Colab | Browser session and Colab token are different identities |
| User is org admin but push still fails | Token may be read-only, fine-grained scope may not include target repo, or Team/Enterprise token policy may apply |
login() rejects the token |
You may be trying to use an old organization token instead of a User Access Token |
| Inference calls fail but uploads work | Inference Providers permissions are separate from Hub repo write permissions |
| Inference usage bills personal account | Billing is separate from authentication; see bill_to / X-HF-Bill-To for Team/Enterprise Inference Providers billing |
Helpful checks:
import os
from huggingface_hub import whoami
token = os.environ.get("HF_TOKEN")
print("HF_TOKEN present:", bool(token))
if token:
print(whoami(token=token))
And from CLI:
hf auth whoami
hf auth list
Do not print or paste the actual token into a public notebook, forum post, or issue.
6. Team/Enterprise orgs can add another layer
If the organization is on Team/Enterprise, token policy can matter.
The Tokens Management docs describe policies such as:
| Org token policy | Effect |
|---|---|
| Allow access via User Access Tokens | Normal read/write and fine-grained tokens can be authorized |
| Only access via fine-grained tokens | Broad read/write tokens are rejected for org resources |
| Require administrator approval | Fine-grained tokens may need org admin approval before access works |
The User Access Tokens docs also describe the member-side behavior: pending, denied, revoked, and fine-grained-only policy cases can produce 403 errors against organization resources.
So if everything looks correct but you still get 403, check whether the org has a token policy requiring fine-grained tokens or administrator approval.
7. Separate concepts that often get mixed in
These are related but not the same as “push model files to an org repo”.
Inference Providers permission
Calling Inference Providers is not the same permission as pushing files to a Hub repo. Inference Providers may require a separate fine-grained permission such as making calls to Inference Providers.
Docs:
- Inference Providers
Organization billing for inference
If the reason you are looking for an org token is billing for Inference Providers, that is a separate concept. The Inference Providers pricing docs say that each user still uses their own User Access Token, while organization billing can be selected with X-HF-Bill-To or bill_to for Team/Enterprise organizations.
So:
| Concept | Mechanism |
|---|---|
| Authentication identity | User Access Token |
| Org repo write access | User’s org role + token permission/scope |
| Inference billing to org | X-HF-Bill-To header or bill_to parameter, where supported |
Gated models
Gated third-party models are another separate case. The gated models docs explain that access requests are granted to individual users, not to an organization as a whole.
So an org token mental model can be especially misleading there: the token owner must be the user who has accepted / been approved for the gate.
8. My practical recommendation
For your specific Colab upload case, I would try this order:
- Confirm your HF account is a member of the org and has
writeoradmin. - Create a User Access Token.
- For a quick test:
write. - For safer usage: fine-grained, scoped to the target org/repo.
- For a quick test:
- Put it in Colab as
HF_TOKEN. - In Colab, run
whoami(token=token)to confirm the token identity. - Use
repo_id="<org-name>/<repo-name>". - Use
repo_type="model"if this is a model repo. - If you get
403, check token scope, org role, and Team/Enterprise token policy.
The main thing I would not do is spend time trying to find a new organization token for huggingface_hub.login() or a normal Colab upload. The supported/default path is a User Access Token whose effective access comes from both the token and the user’s organization membership.
Discussion in the ATmosphere