class Google::Auth::Credentials
Credentials
is a high-level base class used by Google’s API client libraries to represent the authentication when connecting to an API. In most cases, it is subclassed by API-specific credential classes that can be instantiated by clients.
Important: If you accept a credential configuration (credential JSON/File/Stream) from an external source for authentication to Google
Cloud, you must validate it before providing it to any Google
API or library. Providing an unvalidated credential configuration to Google
APIs can compromise the security of your systems and data. For more information, refer to [Validate credential configurations from external sources](cloud.google.com/docs/authentication/external/externally-sourced-credentials).
## Options
Credentials
classes are configured with options that dictate default values for parameters such as scope and audience. These defaults are expressed as class attributes, and may differ from endpoint to endpoint. Normally, an API client will provide subclasses specific to each endpoint, configured with appropriate values.
Note that these options inherit up the class hierarchy. If a particular options is not set for a subclass, its superclass is queried.
Some older users of this class set options via constants. This usage is deprecated. For example, instead of setting the ‘AUDIENCE` constant on your subclass, call the `audience=` method.
## Example
class MyCredentials < Google::Auth::Credentials # Set the default scope for these credentials self.scope = "http://example.com/my_scope" end # creds is a credentials object suitable for Google API clients creds = MyCredentials.default creds.scope # => ["http://example.com/my_scope"] class SubCredentials < MyCredentials # Override the default scope for this subclass self.scope = "http://example.com/sub_scope" end creds2 = SubCredentials.default creds2.scope # => ["http://example.com/sub_scope"]
Constants
- AUDIENCE
-
The default target audience ID to be used when none is provided during initialization.
- TOKEN_CREDENTIAL_URI
-
The default token credential URI to be used when none is provided during initialization.
Attributes
The Signet::OAuth2::Client
object the Credentials
instance is using.
@return [Signet::OAuth2::Client]
Identifier for the project the client is authenticating with.
@return [String]
Identifier for a separate project used for billing/quota, if any.
@return [String,nil]
Public Class Methods
Source
# File lib/googleauth/credentials.rb, line 110 def self.audience lookup_auth_param :audience do lookup_local_constant :AUDIENCE end end
The default target audience ID to be used when none is provided during initialization. Used only by the assertion grant type.
@return [String]
Source
# File lib/googleauth/credentials.rb, line 121 def self.audience= new_audience @audience = new_audience end
Sets the default target audience ID to be used when none is provided during initialization.
@param [String] new_audience
Source
# File lib/googleauth/credentials.rb, line 436 def self.default options = {} # First try to find keyfile file or json from environment variables. client = from_env_vars options # Second try to find keyfile file from known file paths. client ||= from_default_paths options # Finally get instantiated client from Google::Auth client ||= from_application_default options client end
Creates a new Credentials
instance with auth credentials acquired by searching the environment variables and paths configured on the class, and with the default values configured on the class.
The auth credentials are searched for in the following order:
-
configured environment variables (see {Credentials.env_vars})
-
configured default file paths (see {Credentials.paths})
-
application default (see {Google::Auth.get_application_default})
@param [Hash] options
The options for configuring the credentials instance. The following is supported: * +:scope+ - the scope for the client * +"project_id"+ (and optionally +"project"+) - the project identifier for the client * +:connection_builder+ - the connection builder to use for the client * +:default_connection+ - the default connection to use for the client
@return [Credentials]
Source
# File lib/googleauth/credentials.rb, line 192 def self.env_vars env_vars_internal || [] end
The environment variables to search for credentials. Values can either be a file path to the credentials file, or the JSON contents of the credentials file. The env_vars
will never be nil. If there are no vars, the empty array is returned.
@return [Array<String>]
Source
# File lib/googleauth/credentials.rb, line 216 def self.env_vars= new_env_vars new_env_vars = Array new_env_vars unless new_env_vars.nil? @env_vars = new_env_vars end
Sets the environment variables to search for credentials. Setting to ‘nil` “unsets” the value, and defaults to the superclass (or to the empty array if there is no superclass).
@param [String, Array<String>, nil] new_env_vars
Source
# File lib/googleauth/credentials.rb, line 200 def self.env_vars_internal lookup_auth_param :env_vars, :env_vars_internal do # Pull values when PATH_ENV_VARS or JSON_ENV_VARS constants exists. path_env_vars = lookup_local_constant :PATH_ENV_VARS json_env_vars = lookup_local_constant :JSON_ENV_VARS (Array(path_env_vars) + Array(json_env_vars)).flatten.uniq if path_env_vars || json_env_vars end end
@private Internal recursive lookup for env_vars.
Source
# File lib/googleauth/credentials.rb, line 269 def self.lookup_auth_param name, method_name = name val = instance_variable_get :"@#{name}" val = yield if val.nil? && block_given? return val unless val.nil? return superclass.send method_name if superclass.respond_to? method_name nil end
@private Return the given parameter value, defaulting up the class hierarchy.
First returns the value of the instance variable, if set. Next, calls the given block if provided. (This is generally used to look up legacy constant-based values.) Otherwise, calls the superclass method if present. Returns nil if all steps fail.
@param name [Symbol] The parameter name @param method_name [Symbol] The lookup method name, if different @return [Object] The value
Source
# File lib/googleauth/credentials.rb, line 285 def self.lookup_local_constant name const_defined?(name, false) ? const_get(name) : nil end
@private Return the value of the given constant if it is defined directly in this class, or nil if not.
@param [Symbol] Name of the constant @return [Object] The value
Source
# File lib/googleauth/credentials.rb, line 394 def initialize source_creds, options = {} raise "The source credentials passed to Google::Auth::Credentials.new were nil." if source_creds.nil? options = symbolize_hash_keys options @project_id = options[:project_id] || options[:project] @quota_project_id = options[:quota_project_id] case source_creds when String update_from_filepath source_creds, options when Hash update_from_hash source_creds, options else update_from_client source_creds end setup_logging logger: options.fetch(:logger, :default) @project_id ||= CredentialsLoader.load_gcloud_project_id @env_vars = nil @paths = nil @scope = nil end
Creates a new Credentials
instance with the provided auth credentials, and with the default values configured on the class.
@param [String, Hash, Signet::OAuth2::Client
] source_creds
The source of credentials. It can be provided as one of the following: * The path to a JSON keyfile (as a `String`) * The contents of a JSON keyfile (as a `Hash`) * A `Signet::OAuth2::Client` credentials object * Any credentials object that supports the methods this wrapper delegates to an inner client. If this parameter is an object (`Signet::OAuth2::Client` or other) it will be used as an inner client. Otherwise the inner client will be constructed from the JSON keyfile or the contens of the hash.
@param [Hash] options
The options for configuring this wrapper credentials object and the inner client. The options hash is used in two ways: 1. **Configuring the wrapper object:** Some options are used to directly configure the wrapper `Credentials` instance. These include: * `:project_id` (and optionally `:project`) - the project identifier for the client * `:quota_project_id` - the quota project identifier for the client * `:logger` - the logger used to log credential operations such as token refresh. 2. **Configuring the inner client:** When the `source_creds` parameter is a `String` or `Hash`, a new `Signet::OAuth2::Client` is created internally. The following options are used to configure this inner client: * `:scope` - the scope for the client * `:target_audience` - the target audience for the client Any other options in the `options` hash are passed directly to the inner client constructor. This allows you to configure additional parameters of the `Signet::OAuth2::Client`, such as connection parameters, timeouts, etc.
Source
# File lib/googleauth/credentials.rb, line 227 def self.paths paths_internal || [] end
The file paths to search for credentials files. The paths will never be nil. If there are no paths, the empty array is returned.
@return [Array<String>]
Source
# File lib/googleauth/credentials.rb, line 250 def self.paths= new_paths new_paths = Array new_paths unless new_paths.nil? @paths = new_paths end
Set the file paths to search for credentials files. Setting to ‘nil` “unsets” the value, and defaults to the superclass (or to the empty array if there is no superclass).
@param [String, Array<String>, nil] new_paths
Source
# File lib/googleauth/credentials.rb, line 235 def self.paths_internal lookup_auth_param :paths, :paths_internal do # Pull in values if the DEFAULT_PATHS constant exists. vals = lookup_local_constant :DEFAULT_PATHS vals ? Array(vals).flatten.uniq : nil end end
@private Internal recursive lookup for paths.
Source
# File lib/googleauth/credentials.rb, line 136 def self.scope lookup_auth_param :scope do vals = lookup_local_constant :SCOPE vals ? Array(vals).flatten.uniq : nil end end
The default scope to be used when none is provided during initialization. A scope is an access range defined by the authorization server. The scope can be a single value or a list of values.
Either {#scope} or {#target_audience}, but not both, should be non-nil. If {#scope} is set, this credential will produce access tokens. If {#target_audience} is set, this credential will produce ID tokens.
@return [String, Array<String>, nil]
Source
# File lib/googleauth/credentials.rb, line 152 def self.scope= new_scope new_scope = Array new_scope unless new_scope.nil? @scope = new_scope end
Sets the default scope to be used when none is provided during initialization.
Either {#scope} or {#target_audience}, but not both, should be non-nil. If {#scope} is set, this credential will produce access tokens. If {#target_audience} is set, this credential will produce ID tokens.
@param [String, Array<String>, nil] new_scope
Source
# File lib/googleauth/credentials.rb, line 167 def self.target_audience lookup_auth_param :target_audience end
The default final target audience for ID tokens, to be used when none is provided during initialization.
Either {#scope} or {#target_audience}, but not both, should be non-nil. If {#scope} is set, this credential will produce access tokens. If {#target_audience} is set, this credential will produce ID tokens.
@return [String, nil]
Source
# File lib/googleauth/credentials.rb, line 181 def self.target_audience= new_target_audience @target_audience = new_target_audience end
Sets the default final target audience for ID tokens, to be used when none is provided during initialization.
Either {#scope} or {#target_audience}, but not both, should be non-nil. If {#scope} is set, this credential will produce access tokens. If {#target_audience} is set, this credential will produce ID tokens.
@param [String, nil] new_target_audience
Source
# File lib/googleauth/credentials.rb, line 89 def self.token_credential_uri lookup_auth_param :token_credential_uri do lookup_local_constant :TOKEN_CREDENTIAL_URI end end
The default token credential URI to be used when none is provided during initialization. The URI is the authorization server’s HTTP endpoint capable of issuing tokens and refreshing expired tokens.
@return [String]
Source
# File lib/googleauth/credentials.rb, line 100 def self.token_credential_uri= new_token_credential_uri @token_credential_uri = new_token_credential_uri end
Set the default token credential URI to be used when none is provided during initialization.
@param [String] new_token_credential_uri
Private Class Methods
Source
# File lib/googleauth/credentials.rb, line 480 def self.from_application_default options scope = options[:scope] || self.scope auth_opts = { token_credential_uri: options[:token_credential_uri] || token_credential_uri, audience: options[:audience] || audience, target_audience: options[:target_audience] || target_audience, enable_self_signed_jwt: options[:enable_self_signed_jwt] && options[:scope].nil? } client = Google::Auth.get_application_default scope, auth_opts new client, options end
@private Lookup Credentials
using Google::Auth.get_application_default
.
Source
# File lib/googleauth/credentials.rb, line 469 def self.from_default_paths options paths.each do |path| next unless path && ::File.file?(path) io = ::StringIO.new ::File.read path return from_io io, options end nil end
@private Lookup Credentials
from default file paths.
Source
# File lib/googleauth/credentials.rb, line 450 def self.from_env_vars options env_vars.each do |env_var| str = ENV[env_var] next if str.nil? io = if ::File.file? str ::StringIO.new ::File.read str else json = ::JSON.parse str rescue nil json ? ::StringIO.new(str) : nil end next if io.nil? return from_io io, options end nil end
@private Lookup Credentials
from environment variables.
Source
# File lib/googleauth/credentials.rb, line 493 def self.from_io io, options creds_input = { json_key_io: io, scope: options[:scope] || scope, target_audience: options[:target_audience] || target_audience, enable_self_signed_jwt: options[:enable_self_signed_jwt] && options[:scope].nil?, token_credential_uri: options[:token_credential_uri] || token_credential_uri, audience: options[:audience] || audience } client = Google::Auth::DefaultCredentials.make_creds creds_input options = options.select { |k, _v| k == :logger } new client, options end
@private Read credentials from a JSON stream.
Public Instance Methods
Source
# File lib/googleauth/credentials.rb, line 351 def_delegators :@client, :token_credential_uri, :audience, :scope, :issuer, :signing_key, :updater_proc, :target_audience, :universe_domain, :universe_domain=, :logger, :logger=
@!attribute [r] token_credential_uri
@return [String] The token credential URI. The URI is the authorization server's HTTP endpoint capable of issuing tokens and refreshing expired tokens.
@!attribute [r] audience
@return [String] The target audience ID when issuing assertions. Used only by the assertion grant type.
@!attribute [r] scope
@return [String, Array<String>] The scope for this client. A scope is an access range defined by the authorization server. The scope can be a single value or a list of values.
@!attribute [r] issuer
@return [String] The issuer ID associated with this client.
@!attribute [r] signing_key
@return [String, OpenSSL::PKey] The signing key associated with this client.
@!attribute [r] updater_proc
@return [Proc] Returns a reference to the {Signet::OAuth2::Client#apply} method, suitable for passing as a closure.
@!attribute [r] target_audience
@return [String] The final target audience for ID tokens returned by this credential.
@!attribute [rw] universe_domain
@return [String] The universe domain issuing these credentials.
@!attribute [rw] logger
@return [Logger] The logger used to log credential operations such as token refresh.
Source
# File lib/googleauth/credentials.rb, line 311 def disable_universe_domain_check return false unless @client.respond_to? :disable_universe_domain_check @client.disable_universe_domain_check end
@private Temporary; remove when universe domain metadata endpoint is stable (see b/349488459).
Source
# File lib/googleauth/credentials.rb, line 537 def duplicate options = {} options = deep_hash_normalize options options = { project_id: @project_id, quota_project_id: @quota_project_id }.merge(options) new_client = if @client.respond_to? :duplicate @client.duplicate options else @client end self.class.new new_client, options end
Creates a duplicate of these credentials. This method tries to create the duplicate of the wrapped credentials if they support duplication and use them as is if they don’t.
The wrapped credentials are typically ‘Signet::OAuth2::Client` objects and they keep the transient state (token, refresh token, etc). The duplication discards that state, allowing e.g. to get the token with a different scope.
@param options [Hash] Overrides for the credentials parameters.
The options hash is used in two ways: 1. **Configuring the duplicate of the wrapper object:** Some options are used to directly configure the wrapper `Credentials` instance. These include: * `:project_id` (and optionally `:project`) - the project identifier for the credentials * `:quota_project_id` - the quota project identifier for the credentials 2. **Configuring the duplicate of the inner client:** If the inner client supports duplication the options hash is passed to it. This allows for configuration of additional parameters, most importantly (but not limited to) the following: * `:scope` - the scope for the client
@return [Credentials]
Protected Instance Methods
Source
# File lib/googleauth/credentials.rb, line 563 def init_client hash, options = {} options = update_client_options options io = StringIO.new JSON.generate hash options.merge! json_key_io: io Google::Auth::DefaultCredentials.make_creds options end
Initializes the Signet
client.
Source
# File lib/googleauth/credentials.rb, line 623 def setup_logging logger: :default return unless @client.respond_to? :logger= logging_env = ENV["GOOGLE_SDK_RUBY_LOGGING_GEMS"].to_s.downcase if ["false", "none"].include? logging_env logger = nil elsif @client.logger logger = @client.logger elsif logger == :default logger = nil if ["true", "all"].include?(logging_env) || logging_env.split(",").include?("googleauth") formatter = Google::Logging::StructuredFormatter.new if Google::Cloud::Env.get.logging_agent_expected? logger = Logger.new $stderr, progname: "googleauth", formatter: formatter end end @client.logger = logger end
Source
# File lib/googleauth/credentials.rb, line 571 def stringify_hash_keys hash hash.to_h.transform_keys(&:to_s) end
returns a new Hash with string keys instead of symbol keys.
Source
# File lib/googleauth/credentials.rb, line 576 def symbolize_hash_keys hash hash.to_h.transform_keys(&:to_sym) end
returns a new Hash with symbol keys instead of string keys.
Source
# File lib/googleauth/credentials.rb, line 580 def update_client_options options options = options.dup # options have higher priority over constructor defaults options[:token_credential_uri] ||= self.class.token_credential_uri options[:audience] ||= self.class.audience options[:scope] ||= self.class.scope options[:target_audience] ||= self.class.target_audience if !Array(options[:scope]).empty? && options[:target_audience] raise ArgumentError, "Cannot specify both scope and target_audience" end options.delete :scope unless options[:target_audience].nil? options end
Source
# File lib/googleauth/credentials.rb, line 597 def update_from_client client @project_id ||= client.project_id if client.respond_to? :project_id @quota_project_id ||= client.quota_project_id if client.respond_to? :quota_project_id @client = client end
Source
# File lib/googleauth/credentials.rb, line 613 def update_from_filepath path, options verify_keyfile_exists! path json = JSON.parse ::File.read(path) json["scope"] ||= options[:scope] json["target_audience"] ||= options[:target_audience] @project_id ||= json["project_id"] || json["project"] @quota_project_id ||= json["quota_project_id"] @client = init_client json, options end
Source
# File lib/googleauth/credentials.rb, line 604 def update_from_hash hash, options hash = stringify_hash_keys hash hash["scope"] ||= options[:scope] hash["target_audience"] ||= options[:target_audience] @project_id ||= hash["project_id"] || hash["project"] @quota_project_id ||= hash["quota_project_id"] @client = init_client hash, options end
Source
# File lib/googleauth/credentials.rb, line 557 def verify_keyfile_exists! keyfile exists = ::File.file? keyfile raise "The keyfile '#{keyfile}' is not a valid file." unless exists end
Verify that the keyfile argument is a file.
Private Instance Methods
Source
# File lib/googleauth/credentials.rb, line 651 def deep_hash_normalize old_hash sym_hash = {} old_hash&.each { |k, v| sym_hash[k.to_sym] = recursive_hash_normalize_keys v } sym_hash end
Source
# File lib/googleauth/credentials.rb, line 643 def recursive_hash_normalize_keys val if val.is_a? Hash deep_hash_normalize val else val end end
Convert all keys in this hash (nested) to symbols for uniform retrieval