denoland/deno · error
No means to authenticate. Pass a token to `--token`, or enab
Error message
No means to authenticate. Pass a token to `--token`, or enable tokenless publishing from GitHub Actions using OIDC. Learn more at https://deno.co/ghoidc
What it means
When publishing from GitHub Actions without --token, Deno attempts tokenless OIDC auth using the ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN env vars that Actions injects when the job has the id-token permission. This error means GITHUB_ACTIONS=true but both vars are absent — the workflow never granted OIDC — and no other credential was supplied.
Source
Thrown at cli/tools/publish/auth.rs:36
}
pub(crate) fn is_gha() -> bool {
std::env::var("GITHUB_ACTIONS").unwrap_or_default() == "true"
}
pub(crate) fn gha_oidc_token() -> Option<String> {
std::env::var("ACTIONS_ID_TOKEN_REQUEST_TOKEN")
.ok()
.filter(|s| !s.is_empty())
}
fn get_gh_oidc_env_vars() -> Option<Result<(String, String), AnyError>> {
if std::env::var("GITHUB_ACTIONS").unwrap_or_default() == "true" {
let url = std::env::var("ACTIONS_ID_TOKEN_REQUEST_URL");
let token = std::env::var("ACTIONS_ID_TOKEN_REQUEST_TOKEN");
match (url, token) {
(Ok(url), Ok(token)) => Some(Ok((url, token))),
(Err(_), Err(_)) => Some(Err(anyhow::anyhow!(
"No means to authenticate. Pass a token to `--token`, or enable tokenless publishing from GitHub Actions using OIDC. Learn more at https://deno.co/ghoidc"
))),
_ => None,
}
} else {
None
}
}
pub fn get_auth_method(
maybe_token: Option<String>,
dry_run: bool,
) -> Result<AuthMethod, AnyError> {
if dry_run {
// We don't authenticate in dry-run mode.
return Ok(AuthMethod::Interactive);
}
View on GitHub (pinned to 89f33cbef2)
Solutions
- Add `permissions: id-token: write` (plus `contents: read`) to the publishing job so Actions provides the OIDC vars
- Or pass a credential explicitly: deno publish --token $DENO_TOKEN
- Verify the vars exist in the job: env | grep ACTIONS_ID_TOKEN
- If OIDC is blocked by policy, store a PAT as a secret and use --token
Example fix
# .github/workflows/publish.yml — before
jobs:
publish:
steps:
- run: deno publish
# after
jobs:
publish:
permissions:
id-token: write
contents: read
steps:
- uses: denoland/setup-deno@v2
- run: deno publish Defensive patterns
Strategy: validation
Validate before calling
# CI preflight: detect missing OIDC grant before publishing
if [ "${GITHUB_ACTIONS:-}" = "true" ] && [ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" ]; then
echo '::error::job needs permissions: id-token: write for tokenless publish'
exit 1
fi
deno publish Prevention
- Keep the permissions block (id-token: write) in the publish workflow template
- Verify with env | grep ACTIONS_ID_TOKEN when wiring a new publish workflow
- Store a PAT secret as a fallback for runners without OIDC
When it happens
Trigger: `deno publish` in a GitHub Actions workflow with no --token where the job is missing permissions: id-token: write, or where OIDC is disabled at the enterprise/organization level.
Common situations: Publish workflows copied without the permissions block; org policies restricting id-token; self-hosted or non-GitHub runners where the ACTIONS_ID_TOKEN_* vars are never set.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- GITHUB_REPOSITORY environment variable is not set
- GITHUB_SERVER_URL environment variable is not set
- GITHUB_REF environment variable is not set
- GITHUB_SHA environment variable is not set
- RUNNER_ENVIRONMENT environment variable is not set
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/47e24cb27ac4201d.
Report an issue: GitHub.