Module: AgentHarness::Authentication
- Defined in:
- lib/agent_harness/authentication.rb
Overview
Authentication management for CLI agent providers
Provides methods for checking auth status, generating OAuth URLs, and refreshing credentials for providers that support it.
Class Method Summary collapse
-
.auth_capabilities(provider_name) ⇒ Hash
Get authentication flow capabilities for a provider.
-
.auth_status(provider_name) ⇒ Hash
Get detailed authentication status for a provider.
-
.auth_url(provider_name) ⇒ String
Generate an OAuth URL for a provider.
-
.auth_url_supported?(provider_name) ⇒ Boolean
Check whether OAuth URL generation is supported for a provider.
-
.auth_valid?(provider_name) ⇒ Boolean
Check if authentication is valid for a provider.
-
.exchange_code(provider_name, code:, code_verifier:) ⇒ Hash
Exchange an OAuth authorization code for tokens using PKCE.
-
.exchange_code_supported?(provider_name) ⇒ Boolean
Check whether PKCE code exchange is supported for a provider.
-
.exchange_refresh_token(provider_name) ⇒ Hash
Exchange a stored refresh token for a fresh access token (and rotated refresh token).
-
.exchange_refresh_token_supported?(provider_name) ⇒ Boolean
Check whether refresh-token exchange is supported for a provider.
-
.refresh_auth(provider_name, token: nil) ⇒ Hash
Refresh authentication credentials for a provider.
-
.refresh_auth_supported?(provider_name) ⇒ Boolean
Check whether credential refresh is supported for a provider.
Class Method Details
.auth_capabilities(provider_name) ⇒ Hash
Get authentication flow capabilities for a provider.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/agent_harness/authentication.rb', line 45 def auth_capabilities(provider_name) provider_name = provider_name.to_sym provider = resolve_provider(provider_name) canonical_name = Providers::Registry.instance.canonical_name(provider_name) flow_supported = claude_oauth_flow_provider?(provider_name, canonical_name) { auth_type: provider.auth_type, auth_url: flow_supported, exchange_code: flow_supported, refresh: flow_supported, exchange: flow_supported } end |
.auth_status(provider_name) ⇒ Hash
Get detailed authentication status for a provider
30 31 32 33 34 35 36 37 38 |
# File 'lib/agent_harness/authentication.rb', line 30 def auth_status(provider_name) provider_name = provider_name.to_sym case provider_name when :claude, :anthropic claude_auth_status else generic_auth_status(provider_name) end end |
.auth_url(provider_name) ⇒ String
Generate an OAuth URL for a provider
Only supported for :oauth auth type providers.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/agent_harness/authentication.rb', line 76 def auth_url(provider_name) provider_name = provider_name.to_sym provider = resolve_provider(provider_name) unless provider.auth_type == :oauth raise UnsupportedAuthFlowError, "Provider #{provider_name} uses #{provider.auth_type} auth and does not support OAuth URL generation" end case provider_name when :claude, :anthropic claude_auth_url else raise UnsupportedAuthFlowError, "OAuth URL generation is not yet implemented for provider #{provider_name}" end end |
.auth_url_supported?(provider_name) ⇒ Boolean
Check whether OAuth URL generation is supported for a provider.
65 66 67 |
# File 'lib/agent_harness/authentication.rb', line 65 def auth_url_supported?(provider_name) auth_capabilities(provider_name)[:auth_url] end |
.auth_valid?(provider_name) ⇒ Boolean
Check if authentication is valid for a provider
21 22 23 24 |
# File 'lib/agent_harness/authentication.rb', line 21 def auth_valid?(provider_name) status = auth_status(provider_name) !!status[:valid] end |
.exchange_code(provider_name, code:, code_verifier:) ⇒ Hash
Exchange an OAuth authorization code for tokens using PKCE.
Performs the code→token exchange with the provider's token endpoint and stores the resulting credentials in native shape.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/agent_harness/authentication.rb', line 115 def exchange_code(provider_name, code:, code_verifier:) provider_name = provider_name.to_sym provider = resolve_provider(provider_name) unless provider.auth_type == :oauth raise UnsupportedAuthFlowError, "Provider #{provider_name} uses #{provider.auth_type} auth and does not support PKCE code exchange" end case provider_name when :claude, :anthropic exchange_claude_code(code: code, code_verifier: code_verifier) else raise UnsupportedAuthFlowError, "PKCE code exchange is not yet implemented for provider #{provider_name}" end end |
.exchange_code_supported?(provider_name) ⇒ Boolean
Check whether PKCE code exchange is supported for a provider.
99 100 101 |
# File 'lib/agent_harness/authentication.rb', line 99 def exchange_code_supported?(provider_name) auth_capabilities(provider_name)[:exchange_code] end |
.exchange_refresh_token(provider_name) ⇒ Hash
Exchange a stored refresh token for a fresh access token (and rotated refresh token).
Reads the refresh token from the provider's credentials store, posts it to the OAuth token endpoint, persists the rotated tokens, and returns the credential in native claudeAiOauth shape.
Serializes through a file lock so that concurrent callers do not race on a
single-use/rotating refresh token. If the token server reports that the
refresh token has already been consumed (refresh_token_reused), raises
AuthenticationError so the caller can trigger a full re-auth.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/agent_harness/authentication.rb', line 197 def exchange_refresh_token(provider_name) provider_name = provider_name.to_sym provider = resolve_provider(provider_name) unless provider.auth_type == :oauth raise UnsupportedAuthFlowError, "Provider #{provider_name} uses #{provider.auth_type} auth and does not support token exchange" end case provider_name when :claude, :anthropic exchange_claude_refresh_token else raise UnsupportedAuthFlowError, "Token exchange is not yet implemented for provider #{provider_name}" end end |
.exchange_refresh_token_supported?(provider_name) ⇒ Boolean
Check whether refresh-token exchange is supported for a provider.
177 178 179 |
# File 'lib/agent_harness/authentication.rb', line 177 def exchange_refresh_token_supported?(provider_name) auth_capabilities(provider_name)[:exchange] end |
.refresh_auth(provider_name, token: nil) ⇒ Hash
Refresh authentication credentials for a provider
For OAuth providers, stores a pre-exchanged token directly. This method accepts a token (not an authorization code) because the OAuth code-exchange flow is provider-specific and should be handled by the caller or a CLI login command before calling this. For API key providers, raises UnsupportedAuthFlowError.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/agent_harness/authentication.rb', line 154 def refresh_auth(provider_name, token: nil) provider_name = provider_name.to_sym provider = resolve_provider(provider_name) unless provider.auth_type == :oauth raise UnsupportedAuthFlowError, "Provider #{provider_name} uses #{provider.auth_type} auth and does not support credential refresh" end case provider_name when :claude, :anthropic refresh_claude_auth(token: token) else raise UnsupportedAuthFlowError, "Credential refresh is not yet implemented for provider #{provider_name}" end end |
.refresh_auth_supported?(provider_name) ⇒ Boolean
Check whether credential refresh is supported for a provider.
138 139 140 |
# File 'lib/agent_harness/authentication.rb', line 138 def refresh_auth_supported?(provider_name) auth_capabilities(provider_name)[:refresh] end |