hermes - ✅(Solved) Fix Copilot auth accepts arbitrary non-empty GITHUB_TOKEN values and skips valid gh fallback [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#12650Fetched 2026-04-20 12:17:39
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

Root Cause

Because resolve_copilot_token() trusts that result, a bad env token can block fallback to a valid gh auth token credential.

Fix Action

Fix / Workaround

Minimal reproduction / evidence

source venv/bin/activate && python - <<'PY'
from hermes_cli.copilot_auth import validate_copilot_token, resolve_copilot_token
from unittest.mock import patch
import os

print(validate_copilot_token('not_a_github_token'))
with patch.dict(os.environ, {'GITHUB_TOKEN':'not_a_github_token'}, clear=True):
    with patch('hermes_cli.copilot_auth._try_gh_cli_token', return_value='gho_valid_fallback'):
        print(resolve_copilot_token())
PY

Observed output:

  • validate_copilot_token('not_a_github_token') -> (True, 'OK')
  • resolve_copilot_token() -> ('not_a_github_token', 'GITHUB_TOKEN')

PR fix notes

PR #13538: fix(copilot): validate supported token prefixes

Description (problem / solution / changelog)

Summary

  • restrict Copilot token validation to the supported GitHub token families already documented in the module
  • reject arbitrary non-empty env token values instead of treating them as usable Copilot credentials
  • add regression coverage for invalid env tokens falling back to gh auth token

Fixes #12650

Root Cause

validate_copilot_token() only rejected classic ghp_* PATs and accepted any other non-empty string. That let garbage values from COPILOT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN block resolution from continuing to a valid gh auth token fallback, even though the module already declares the supported token prefixes.

Validation

  • PYTHONPATH=/Users/zzl/.hermes/hermes-agent-pr-12650 /Users/zzl/.hermes/hermes-agent-update-20260421/venv/bin/python -m pytest -o addopts= tests/hermes_cli/test_copilot_auth.py -q
  • PYTHONPATH=/Users/zzl/.hermes/hermes-agent-pr-12650 /Users/zzl/.hermes/hermes-agent-update-20260421/venv/bin/python -m pytest -o addopts= tests/hermes_cli/test_api_key_providers.py -k copilot -q
  • PYTHONPATH=/Users/zzl/.hermes/hermes-agent-pr-12650 /Users/zzl/.hermes/hermes-agent-update-20260421/venv/bin/python -m py_compile hermes_cli/copilot_auth.py tests/hermes_cli/test_copilot_auth.py tests/hermes_cli/test_api_key_providers.py
  • git diff --check

Changed files

  • hermes_cli/copilot_auth.py (modified, +8/-1)
  • tests/hermes_cli/test_api_key_providers.py (modified, +11/-2)
  • tests/hermes_cli/test_copilot_auth.py (modified, +16/-0)

Code Example

source venv/bin/activate && python - <<'PY'
from hermes_cli.copilot_auth import validate_copilot_token, resolve_copilot_token
from unittest.mock import patch
import os

print(validate_copilot_token('not_a_github_token'))
with patch.dict(os.environ, {'GITHUB_TOKEN':'not_a_github_token'}, clear=True):
    with patch('hermes_cli.copilot_auth._try_gh_cli_token', return_value='gho_valid_fallback'):
        print(resolve_copilot_token())
PY
RAW_BUFFERClick to expand / collapse

Bug Description

validate_copilot_token() accepts any non-empty token except ghp_*, so arbitrary garbage values from COPILOT_GITHUB_TOKEN, GH_TOKEN, or GITHUB_TOKEN are treated as valid Copilot credentials.

Because resolve_copilot_token() trusts that result, a bad env token can block fallback to a valid gh auth token credential.

Affected files / lines

  • hermes_cli/copilot_auth.py:35-36_SUPPORTED_PREFIXES is declared
  • hermes_cli/copilot_auth.py:46-64validate_copilot_token() only rejects ghp_*
  • hermes_cli/copilot_auth.py:73-93resolve_copilot_token() returns the first "valid" env token and never reaches gh auth token

Why this is a bug

The code appears intended to recognize supported token families, but today it accepts arbitrary junk strings. That can produce confusing downstream auth failures and mask the fact that a valid fallback token is available.

Minimal reproduction / evidence

source venv/bin/activate && python - <<'PY'
from hermes_cli.copilot_auth import validate_copilot_token, resolve_copilot_token
from unittest.mock import patch
import os

print(validate_copilot_token('not_a_github_token'))
with patch.dict(os.environ, {'GITHUB_TOKEN':'not_a_github_token'}, clear=True):
    with patch('hermes_cli.copilot_auth._try_gh_cli_token', return_value='gho_valid_fallback'):
        print(resolve_copilot_token())
PY

Observed output:

  • validate_copilot_token('not_a_github_token') -> (True, 'OK')
  • resolve_copilot_token() -> ('not_a_github_token', 'GITHUB_TOKEN')

Expected Behavior

Clearly invalid token strings should be rejected so resolution can continue to a valid fallback source such as gh auth token.

Actual Behavior

Any non-empty non-ghp_* token is accepted as usable.

Suggested investigation direction

  • Enforce supported token shapes/prefixes instead of only blacklisting ghp_*.
  • Add regression coverage for invalid env tokens blocking a valid gh auth token fallback.

extent analysis

TL;DR

Update the validate_copilot_token() function to enforce supported token shapes and prefixes, rather than just rejecting ghp_* tokens.

Guidance

  • Review the _SUPPORTED_PREFIXES declaration in hermes_cli/copilot_auth.py:35-36 to ensure it includes all valid token prefixes.
  • Modify the validate_copilot_token() function in hermes_cli/copilot_auth.py:46-64 to check for supported prefixes instead of just rejecting ghp_* tokens.
  • Add unit tests to cover the case where an invalid env token blocks a valid gh auth token fallback, as suggested in the issue.
  • Consider adding a whitelist of supported token prefixes to the validate_copilot_token() function to improve security.

Example

def validate_copilot_token(token):
    supported_prefixes = ['gho_', 'ghs_', 'ghp_']  # example supported prefixes
    if not any(token.startswith(prefix) for prefix in supported_prefixes):
        return False, 'Invalid token prefix'
    # ... rest of the function ...

Notes

The current implementation only rejects ghp_* tokens, which is not sufficient to prevent arbitrary garbage values from being accepted as valid Copilot credentials. By enforcing supported token shapes and prefixes, we can improve the security of the validate_copilot_token() function.

Recommendation

Apply a workaround by updating the validate_copilot_token() function to enforce supported token shapes and prefixes, as this will prevent invalid env tokens from blocking a valid gh auth token fallback.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Copilot auth accepts arbitrary non-empty GITHUB_TOKEN values and skips valid gh fallback [1 pull requests, 1 participants]