Module: Anthropic::Credentials
- Defined in:
- lib/anthropic/credentials.rb,
lib/anthropic/credentials/constants.rb,
lib/anthropic/credentials/token_cache.rb,
lib/anthropic/credentials/access_token.rb,
lib/anthropic/credentials/static_token.rb,
lib/anthropic/credentials/config_provider.rb,
lib/anthropic/credentials/credentials_file.rb,
lib/anthropic/credentials/in_memory_config.rb,
lib/anthropic/credentials/workload_identity.rb,
lib/anthropic/credentials/identity_token_file.rb
Defined Under Namespace
Classes: AccessToken, ConfigProvider, CredentialResult, CredentialsFile, IdentityTokenFile, InMemoryConfig, StaticToken, TokenCache, WorkloadIdentity, WorkloadIdentityError
Constant Summary collapse
- GRANT_TYPE_JWT_BEARER =
OAuth grant type for RFC 7523 JWT Bearer assertion.
"urn:ietf:params:oauth:grant-type:jwt-bearer"- GRANT_TYPE_REFRESH_TOKEN =
OAuth grant type for refresh token exchange.
"refresh_token"- TOKEN_ENDPOINT =
Path to the OAuth token endpoint.
"/v1/oauth/token"- TOKEN_EXCHANGE_TIMEOUT =
Timeout in seconds for token exchange HTTP requests.
30- OAUTH_API_BETA_HEADER =
Beta header required for OAuth API requests.
"oauth-2025-04-20"- FEDERATION_BETA_HEADER =
Beta header for OIDC federation routing.
"oidc-federation-2026-04-01"- ADVISORY_REFRESH_SECONDS =
Seconds before expiry to attempt advisory (non-blocking) refresh.
120- MANDATORY_REFRESH_SECONDS =
Seconds before expiry when refresh becomes mandatory (blocking).
30- DEFAULT_PROFILE =
Default profile name when none is specified.
"default"- DEFAULT_BASE_URL =
Default API base URL.
"https://api.anthropic.com"- ENV_API_KEY =
Environment variable for explicit API key authentication.
"ANTHROPIC_API_KEY"- ENV_AUTH_TOKEN =
Environment variable for explicit bearer token authentication.
"ANTHROPIC_AUTH_TOKEN"- ENV_BASE_URL =
Environment variable for API base URL override.
"ANTHROPIC_BASE_URL"- ENV_CONFIG_DIR =
Environment variable to override the config directory location.
"ANTHROPIC_CONFIG_DIR"- ENV_PROFILE =
Environment variable to select a specific profile.
"ANTHROPIC_PROFILE"- ENV_IDENTITY_TOKEN =
Environment variable for inline identity token (not recommended).
"ANTHROPIC_IDENTITY_TOKEN"- ENV_IDENTITY_TOKEN_FILE =
Environment variable for path to identity token file.
"ANTHROPIC_IDENTITY_TOKEN_FILE"- ENV_FEDERATION_RULE_ID =
Environment variable for federation rule ID.
"ANTHROPIC_FEDERATION_RULE_ID"- ENV_ORGANIZATION_ID =
Environment variable for organization ID.
"ANTHROPIC_ORGANIZATION_ID"- ENV_SERVICE_ACCOUNT_ID =
Environment variable for service account ID.
"ANTHROPIC_SERVICE_ACCOUNT_ID"- ENV_SCOPE =
Environment variable for OAuth scope.
"ANTHROPIC_SCOPE"- AUTH_TYPE_OIDC_FEDERATION =
Config file authentication type for OIDC workload identity federation.
"oidc_federation"- AUTH_TYPE_USER_OAUTH =
Config file authentication type for user OAuth (interactive login).
"user_oauth"
Class Method Summary collapse
-
.active_profile ⇒ String
Returns the active profile name.
-
.active_profile_config? ⇒ Boolean
Checks if the active profile has a config file.
-
.auto_discoverable_credentials? ⇒ Boolean
Checks if auto-discoverable credentials are available.
-
.config_dir ⇒ Pathname
Returns the config directory path.
-
.config_file_path(profile) ⇒ Pathname
Returns the path to a profile’s config file.
-
.default_credentials(base_url: DEFAULT_BASE_URL) ⇒ Object
Resolve a CredentialResult from the environment per the credential-resolution spec.
-
.explicit_active_config? ⇒ Boolean
Checks if there’s an explicit active_config pointer file.
-
.read_active_config_pointer ⇒ String?
Reads the active config pointer file.
-
.resolve_identity_token_path(path = nil) ⇒ Pathname?
Resolves an identity token file path.
Class Method Details
.active_profile ⇒ String
Returns the active profile name.
Resolution order:
-
ANTHROPIC_PROFILEenvironment variable -
active_configpointer file contents -
“default”
122 123 124 125 126 127 128 129 |
# File 'lib/anthropic/credentials/constants.rb', line 122 def active_profile return ENV[ENV_PROFILE] if env_present?(ENV_PROFILE) pointer = read_active_config_pointer return pointer if pointer DEFAULT_PROFILE end |
.active_profile_config? ⇒ Boolean
Checks if the active profile has a config file.
143 144 145 146 147 |
# File 'lib/anthropic/credentials/constants.rb', line 143 def active_profile_config? config_file_path(active_profile).file? rescue StandardError false end |
.auto_discoverable_credentials? ⇒ Boolean
Checks if auto-discoverable credentials are available.
Returns true if the environment or filesystem contains signals that would drive the tier-1 (profile) or tier-2 (env federation) credential paths. Used for shadow-warning detection in the client constructor.
174 175 176 177 178 179 180 181 |
# File 'lib/anthropic/credentials/constants.rb', line 174 def auto_discoverable_credentials? return true if env_present?(ENV_PROFILE) return true if env_present?(ENV_CONFIG_DIR) return true if explicit_active_config? return true if federation_configured? false end |
.config_dir ⇒ Pathname
Returns the config directory path.
Resolution order:
-
ANTHROPIC_CONFIG_DIRenvironment variable -
Platform default:
-
Windows: %APPDATA%Anthropic
-
Unix/macOS: ~/.config/anthropic
-
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/anthropic/credentials/constants.rb', line 84 def config_dir return Pathname.new(ENV[ENV_CONFIG_DIR]) if env_present?(ENV_CONFIG_DIR) if RUBY_PLATFORM =~ /mswin|mingw|cygwin/ && env_present?("APPDATA") return Pathname.new(ENV["APPDATA"]).join("Anthropic") end begin home = Dir.home return Pathname.new(home).join(".config", "anthropic") unless home.empty? rescue ArgumentError # Dir.home raises when HOME is unset. Fall through to the error below. end raise Anthropic::Errors::ConfigurationError, "Cannot determine config directory: neither #{ENV_CONFIG_DIR}, APPDATA, nor HOME is set" end |
.config_file_path(profile) ⇒ Pathname
Returns the path to a profile’s config file.
135 136 137 138 |
# File 'lib/anthropic/credentials/constants.rb', line 135 def config_file_path(profile) base = config_dir base.join("configs", "#{profile}.json") end |
.default_credentials(base_url: DEFAULT_BASE_URL) ⇒ Object
Resolve a CredentialResult from the environment per the credential-resolution spec. First match wins.
Implements steps 2-5 of the spec precedence chain (step 1 is handled at the client constructor level):
Step 2a: ANTHROPIC_API_KEY -> return nil so the client uses its
existing +X-Api-Key+ header path. (API keys are not Bearer
tokens, so they can't flow through this chain.)
Step 2b: ANTHROPIC_AUTH_TOKEN -> StaticToken (Bearer). Step 3: ANTHROPIC_PROFILE set -> load that profile. This is
*explicit profile selection* via env var; failures propagate.
Note: the +active_config+ pointer file is **not** treated as
explicit selection -- a leftover pointer from a past `ant
auth login` shouldn't preempt env-var WIF.
Step 4: ANTHROPIC_FEDERATION_RULE_ID + ANTHROPIC_ORGANIZATION_ID
+ +ANTHROPIC_IDENTITY_TOKEN[_FILE]+ -> direct jwt-bearer
exchange via WorkloadIdentity. Critically, step 4 sits
*between* explicit profile (step 3) and fallback profile
(step 5): a machine with WIF env vars wired up must use WIF
even if a leftover +default+ profile (or active_config
pointer) exists on disk, but a user who explicitly sets
+ANTHROPIC_PROFILE=dev+ still gets their profile.
Step 5: Fallback active profile from disk (configs/default.json
or whatever +active_config+ points at). Errors at this step
are swallowed and the chain falls through -- a corrupt
unselected profile shouldn't break an otherwise-explicit
api_key= path.
Returns nil when nothing matches – the client will fall back to its normal “no auth configured” error.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/anthropic/credentials.rb', line 47 def default_credentials(base_url: DEFAULT_BASE_URL) # Step 2a -- env api_key: return nil so the base client handles X-Api-Key. # Treat an empty string the same as unset, matching the Python client. unless ENV[ENV_API_KEY].to_s.empty? return nil end # Step 2b -- env auth_token: static bearer. # Guard against empty string: in Ruby an empty string is truthy, so # a bare `if auth_token` would wrap "" in a StaticToken. auth_token = ENV[ENV_AUTH_TOKEN] if auth_token && !auth_token.empty? return CredentialResult.new(provider: StaticToken.new(auth_token)) end # Step 3 -- explicit profile selection via ANTHROPIC_PROFILE env var. # Failures propagate -- a user who explicitly names a profile expects # a broken config to surface, not to fall through. The active_config # pointer file is *not* considered explicit here; it's handled in # step 5 so env-var WIF can preempt a stale pointer. unless ENV[ENV_PROFILE].to_s.empty? creds_file = CredentialsFile.new creds_file.bind_base_url(base_url) extra_headers = creds_file.extra_headers return CredentialResult.new( provider: creds_file, extra_headers: extra_headers, base_url: creds_file.resolved_base_url ) end # Step 4 -- env-var workload identity federation. Sits above the # fallback on-disk profile so a machine with WIF env vars uses WIF # even if a leftover +default+ profile exists on disk. federation_result = build_federation_result(base_url: base_url) return federation_result if federation_result # Step 5 -- fallback active profile from disk. Errors are swallowed and # the chain falls through because the user didn't explicitly select # this profile; a corrupt auto-discovered config shouldn't break # construction. # # Resolve the profile once and pass it explicitly: active_profile # reads the active_config pointer file, and handing the result to # CredentialsFile.new avoids a second read inside its constructor. profile = Credentials.active_profile if Credentials.config_file_path(profile).file? creds_file = CredentialsFile.new(profile) creds_file.bind_base_url(base_url) begin extra_headers = creds_file.extra_headers rescue Anthropic::Errors::Error return nil end return CredentialResult.new( provider: creds_file, extra_headers: extra_headers, base_url: creds_file.resolved_base_url ) end nil end |
.explicit_active_config? ⇒ Boolean
Checks if there’s an explicit active_config pointer file.
152 153 154 |
# File 'lib/anthropic/credentials/constants.rb', line 152 def explicit_active_config? !read_active_config_pointer.nil? end |
.read_active_config_pointer ⇒ String?
Reads the active config pointer file.
106 107 108 109 110 111 112 |
# File 'lib/anthropic/credentials/constants.rb', line 106 def read_active_config_pointer path = config_dir.join("active_config") content = path.read.strip content.empty? ? nil : content rescue Errno::ENOENT, Errno::EACCES nil end |
.resolve_identity_token_path(path = nil) ⇒ Pathname?
Resolves an identity token file path.
160 161 162 163 164 165 |
# File 'lib/anthropic/credentials/constants.rb', line 160 def resolve_identity_token_path(path = nil) return Pathname.new(path) if path return Pathname.new(ENV[ENV_IDENTITY_TOKEN_FILE]) if env_present?(ENV_IDENTITY_TOKEN_FILE) nil end |