/ hermes_cli / vercel_auth.py
vercel_auth.py
1 """Helpers for reporting Vercel Sandbox authentication state.""" 2 3 from __future__ import annotations 4 5 import os 6 from dataclasses import dataclass 7 8 9 _TOKEN_TUPLE_VARS = ("VERCEL_TOKEN", "VERCEL_PROJECT_ID", "VERCEL_TEAM_ID") 10 11 12 @dataclass(frozen=True) 13 class VercelAuthStatus: 14 ok: bool 15 label: str 16 detail_lines: tuple[str, ...] 17 18 19 def _present(name: str) -> bool: 20 return bool(os.getenv(name)) 21 22 23 def describe_vercel_auth() -> VercelAuthStatus: 24 """Return Vercel auth status without exposing secret values.""" 25 26 has_oidc = _present("VERCEL_OIDC_TOKEN") 27 token_states = {name: _present(name) for name in _TOKEN_TUPLE_VARS} 28 present_token_vars = tuple(name for name, present in token_states.items() if present) 29 missing_token_vars = tuple(name for name, present in token_states.items() if not present) 30 31 if has_oidc: 32 details = [ 33 "mode: OIDC", 34 "active env: VERCEL_OIDC_TOKEN", 35 "note: OIDC tokens are development-only; use access-token auth for deployments and long-running processes", 36 ] 37 if present_token_vars: 38 details.append(f"also present: {', '.join(present_token_vars)}") 39 return VercelAuthStatus(True, "OIDC token via VERCEL_OIDC_TOKEN", tuple(details)) 40 41 if not missing_token_vars: 42 return VercelAuthStatus( 43 True, 44 "access token + project/team via VERCEL_TOKEN, VERCEL_PROJECT_ID, VERCEL_TEAM_ID", 45 ( 46 "mode: access token", 47 "active env: VERCEL_TOKEN, VERCEL_PROJECT_ID, VERCEL_TEAM_ID", 48 ), 49 ) 50 51 if present_token_vars: 52 return VercelAuthStatus( 53 False, 54 f"partial access-token auth (missing {', '.join(missing_token_vars)})", 55 ( 56 "mode: incomplete access token", 57 f"present env: {', '.join(present_token_vars)}", 58 f"missing env: {', '.join(missing_token_vars)}", 59 "recommended: set VERCEL_TOKEN, VERCEL_PROJECT_ID, and VERCEL_TEAM_ID together", 60 ), 61 ) 62 63 return VercelAuthStatus( 64 False, 65 "not configured", 66 ( 67 "recommended: set VERCEL_TOKEN, VERCEL_PROJECT_ID, and VERCEL_TEAM_ID", 68 "development-only alternative: set VERCEL_OIDC_TOKEN", 69 ), 70 )