hashicorp/packer · error
signing_mode %q requires an ambient OIDC token; set SIGSTORE
Error message
signing_mode %q requires an ambient OIDC token; set SIGSTORE_ID_TOKEN, use a CI-provided OIDC token, or switch to signing_mode="none" or a key-backed mode
What it means
resolveAmbientIDToken could not find any ambient OIDC token for keyless signing. It checks SIGSTORE_ID_TOKEN, GitLab's CI_JOB_JWT_V2/CI_JOB_JWT, and GitHub Actions' OIDC endpoint (ACTIONS_ID_TOKEN_REQUEST_URL/TOKEN); when none yield a token, keyless signing cannot obtain a Fulcio certificate and fails with this actionable message.
Source
Thrown at internal/attestation/sign_keyless.go:316
return append([]byte(nil), p.certDER...), nil
}
func resolveAmbientIDToken(ctx context.Context, env map[string]string) (string, error) {
if token := strings.TrimSpace(env["SIGSTORE_ID_TOKEN"]); token != "" {
return token, nil
}
if token := strings.TrimSpace(env["CI_JOB_JWT_V2"]); token != "" {
return token, nil
}
if token := strings.TrimSpace(env["CI_JOB_JWT"]); token != "" {
return token, nil
}
if token, err := resolveGitHubActionsIDToken(ctx, env); err == nil && token != "" {
return token, nil
}
return "", fmt.Errorf("signing_mode %q requires an ambient OIDC token; set SIGSTORE_ID_TOKEN, use a CI-provided OIDC token, or switch to signing_mode=\"none\" or a key-backed mode", SigningModeKeyless)
}
func resolveGitHubActionsIDToken(ctx context.Context, env map[string]string) (string, error) {
requestURL := strings.TrimSpace(env["ACTIONS_ID_TOKEN_REQUEST_URL"])
requestToken := strings.TrimSpace(env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"])
if requestURL == "" || requestToken == "" {
return "", nil
}
parsedURL, err := url.Parse(requestURL)
if err != nil {
return "", fmt.Errorf("parse GitHub OIDC request URL: %w", err)
}
query := parsedURL.Query()
if query.Get("audience") == "" {
query.Set("audience", "sigstore")
parsedURL.RawQuery = query.Encode()
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Set SIGSTORE_ID_TOKEN to a valid OIDC ID token whose issuer/identity match the configured keyless_identity and keyless_oidc_issuer.
- On GitHub Actions, add `permissions: id-token: write` to the workflow so ACTIONS_ID_TOKEN_REQUEST_URL/TOKEN are injected.
- Switch to signing_mode="none" or a key-backed mode if no OIDC identity is available.
- If on GitHub Actions with permissions set, check why the OIDC request failed — the underlying error is suppressed; run resolveGitHubActionsIDToken directly to see it.
Example fix
// before (GitHub Actions workflow)
jobs:
sign:
steps:
- run: packer ...
// after
jobs:
sign:
permissions:
id-token: write
steps:
- run: packer ... Defensive patterns
Strategy: validation
Validate before calling
func ambientTokenAvailable(env map[string]string) bool {
if strings.TrimSpace(env["SIGSTORE_ID_TOKEN"]) != "" {
return true
}
if strings.TrimSpace(env["CI_JOB_JWT_V2"]) != "" || strings.TrimSpace(env["CI_JOB_JWT"]) != "" {
return true
}
return strings.TrimSpace(env["ACTIONS_ID_TOKEN_REQUEST_URL"]) != "" &&
strings.TrimSpace(env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]) != ""
}
if !ambientTokenAvailable(cfg.Env) {
return fmt.Errorf("no ambient OIDC token; set SIGSTORE_ID_TOKEN or run in CI with OIDC enabled")
} Type guard
func hasCIContext(env map[string]string) bool {
return strings.TrimSpace(env["ACTIONS_ID_TOKEN_REQUEST_URL"]) != "" ||
strings.TrimSpace(env["CI_JOB_JWT"]) != ""
} Try / catch
signer, err := newKeylessSigner(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "requires an ambient OIDC token") {
return fmt.Errorf("keyless signing unavailable outside OIDC-enabled CI; switch signing_mode or export SIGSTORE_ID_TOKEN: %w", err)
} Prevention
- Export SIGSTORE_ID_TOKEN before running keyless signing locally.
- Add `permissions: id-token: write` to GitHub Actions workflows that sign.
- Prefer signing_mode="none" or key-backed modes outside OIDC-enabled CI.
- Check env vars are non-blank, not just present (whitespace-only values are rejected).
When it happens
Trigger: newKeylessSigner runs with signing_mode="keyless" when: SIGSTORE_ID_TOKEN is unset/blank, CI_JOB_JWT(_V2) are unset, and either ACTIONS_ID_TOKEN_REQUEST_URL/ACTIONS_ID_TOKEN_REQUEST_TOKEN are unset or the GitHub OIDC request fails/returns empty (its errors are swallowed here).
Common situations: Running keyless signing locally without exporting SIGSTORE_ID_TOKEN (e.g. from `fulcio` or an OIDC flow); a GitHub Actions job missing `permissions: id-token: write` so the runtime env vars are absent; self-hosted runners without OIDC configured; GitLab CI with older JWT variables only partially set.
Related errors
- request Fulcio certificate: %w
- create keyless verifier: %w
- sign payload with keyless signer: %w
- keyless attestation does not contain a signing certificate
- static certificate provider is missing a certificate
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/2b9ceef8a5fc76a6.
Report an issue: GitHub.