From 9bb3bac84a441e8154718577e60367bbf61d18be Mon Sep 17 00:00:00 2001 From: Georges Gabereau Date: Tue, 9 Dec 2025 12:16:35 -0500 Subject: [PATCH 1/4] Add vertexai_service_account_key to configuration and update authorization logic - Added `vertexai_service_account_key` to the configuration requirements for Vertex AI. - Updated the authorization method to use service account credentials if the key is provided, otherwise defaults to application default credentials. --- lib/ruby_llm/configuration.rb | 1 + lib/ruby_llm/providers/vertexai.rb | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/ruby_llm/configuration.rb b/lib/ruby_llm/configuration.rb index e1c12902a..c0e720aa7 100644 --- a/lib/ruby_llm/configuration.rb +++ b/lib/ruby_llm/configuration.rb @@ -13,6 +13,7 @@ class Configuration :gemini_api_base, :vertexai_project_id, :vertexai_location, + :vertexai_service_account_key, :deepseek_api_key, :perplexity_api_key, :bedrock_api_key, diff --git a/lib/ruby_llm/providers/vertexai.rb b/lib/ruby_llm/providers/vertexai.rb index 268774eec..42f85d689 100644 --- a/lib/ruby_llm/providers/vertexai.rb +++ b/lib/ruby_llm/providers/vertexai.rb @@ -10,6 +10,11 @@ class VertexAI < Gemini include VertexAI::Models include VertexAI::Transcription + SCOPES = [ + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/generative-language.retriever' + ] + def initialize(config) super @authorizer = nil @@ -32,7 +37,7 @@ def headers class << self def configuration_requirements - %i[vertexai_project_id vertexai_location] + %i[vertexai_project_id vertexai_location vertexai_service_account_key] end end @@ -40,12 +45,14 @@ def configuration_requirements def initialize_authorizer require 'googleauth' - @authorizer = ::Google::Auth.get_application_default( - scope: [ - 'https://www.googleapis.com/auth/cloud-platform', - 'https://www.googleapis.com/auth/generative-language.retriever' - ] - ) + @authorizer = if @config.vertexai_service_account_hash + ::Google::Auth::ServiceAccountCredentials.make_creds( + json_key_io: StringIO.new(@config.vertexai_service_account_key), + scope: SCOPES + ) + else + ::Google::Auth.get_application_default(scope: SCOPES) + end rescue LoadError raise Error, 'The googleauth gem ~> 1.15 is required for Vertex AI. Please add it to your Gemfile: gem "googleauth"' From f936e736a728324ea12e38d5f3602eb8757cd8d2 Mon Sep 17 00:00:00 2001 From: Georges Gabereau Date: Tue, 9 Dec 2025 12:34:50 -0500 Subject: [PATCH 2/4] Add documentation --- docs/_getting_started/configuration.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/_getting_started/configuration.md b/docs/_getting_started/configuration.md index e14152053..3be815ac1 100644 --- a/docs/_getting_started/configuration.md +++ b/docs/_getting_started/configuration.md @@ -55,6 +55,7 @@ RubyLLM.configure do |config| config.gemini_api_key = ENV['GEMINI_API_KEY'] config.vertexai_project_id = ENV['GOOGLE_CLOUD_PROJECT'] # Available in v1.7.0+ config.vertexai_location = ENV['GOOGLE_CLOUD_LOCATION'] + config.vertexai_service_account_key = ENV['VERTEXAI_SERVICE_ACCOUNT_KEY'] # JSON Key as String from GCP config.deepseek_api_key = ENV['DEEPSEEK_API_KEY'] config.mistral_api_key = ENV['MISTRAL_API_KEY'] config.perplexity_api_key = ENV['PERPLEXITY_API_KEY'] @@ -90,6 +91,12 @@ end These headers are optional and only needed for organization-specific billing or project tracking. +### Vertex AI Authentication Configuration + +Google Cloud disallows the creation of Vertex AI API keys for Service Accounts, by default. The recommended way to connect is by using a Service Account's JSON key with appropriate IAM roles or by using Application Default Credentials. + +RubyLLM supports both methods of authenticating to Vertex AI and will only use a Service Account key if the key is provided in the `config.vertexai_service_account_key` configuration field. Otherwise, it will fallback to ADC. + ## Custom Endpoints ### OpenAI-Compatible APIs @@ -383,6 +390,7 @@ RubyLLM.configure do |config| config.gemini_api_key = String config.vertexai_project_id = String # GCP project ID config.vertexai_location = String # e.g., 'us-central1' + config.vertexai_service_account_key = String # The JSON key as available for GCP Service Accountss config.deepseek_api_key = String config.mistral_api_key = String config.perplexity_api_key = String From 5fbe54d2b24f54d530db37e4487bd352600675ce Mon Sep 17 00:00:00 2001 From: Georges Gabereau Date: Tue, 9 Dec 2025 14:12:25 -0500 Subject: [PATCH 3/4] Remove trailing whitespace, add new param to spec configuration --- docs/_getting_started/configuration.md | 2 +- spec/support/rubyllm_configuration.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/_getting_started/configuration.md b/docs/_getting_started/configuration.md index 3be815ac1..f3f07f5d2 100644 --- a/docs/_getting_started/configuration.md +++ b/docs/_getting_started/configuration.md @@ -93,7 +93,7 @@ These headers are optional and only needed for organization-specific billing or ### Vertex AI Authentication Configuration -Google Cloud disallows the creation of Vertex AI API keys for Service Accounts, by default. The recommended way to connect is by using a Service Account's JSON key with appropriate IAM roles or by using Application Default Credentials. +Google Cloud disallows the creation of Vertex AI API keys for Service Accounts, by default. The recommended way to connect is by using a Service Account's JSON key with appropriate IAM roles or by using Application Default Credentials. RubyLLM supports both methods of authenticating to Vertex AI and will only use a Service Account key if the key is provided in the `config.vertexai_service_account_key` configuration field. Otherwise, it will fallback to ADC. diff --git a/spec/support/rubyllm_configuration.rb b/spec/support/rubyllm_configuration.rb index 25a2a5b90..4528355b2 100644 --- a/spec/support/rubyllm_configuration.rb +++ b/spec/support/rubyllm_configuration.rb @@ -26,6 +26,7 @@ config.vertexai_project_id = ENV.fetch('GOOGLE_CLOUD_PROJECT', 'test-project') config.vertexai_location = ENV.fetch('GOOGLE_CLOUD_LOCATION', 'us-central1') + config.vertexai_service_account_key = ENV.fetch('VERTEXAI_SERVICE_ACCOUNT_KEY', "{ secret_key: 'test' }") config.request_timeout = 240 config.max_retries = 10 From e249746c4f35b58fe43e70422c91faac4942d72c Mon Sep 17 00:00:00 2001 From: Simmon Li Date: Mon, 5 Jan 2026 16:30:37 -0500 Subject: [PATCH 4/4] Change service account hash to key for authorizer We initially named this configuration `_hash` but was later updated to `_key` --- lib/ruby_llm/providers/vertexai.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ruby_llm/providers/vertexai.rb b/lib/ruby_llm/providers/vertexai.rb index 42f85d689..d349ef2ad 100644 --- a/lib/ruby_llm/providers/vertexai.rb +++ b/lib/ruby_llm/providers/vertexai.rb @@ -45,7 +45,7 @@ def configuration_requirements def initialize_authorizer require 'googleauth' - @authorizer = if @config.vertexai_service_account_hash + @authorizer = if @config.vertexai_service_account_key ::Google::Auth::ServiceAccountCredentials.make_creds( json_key_io: StringIO.new(@config.vertexai_service_account_key), scope: SCOPES