From 2883a2b5bf5a5c40b332c30ad74e283d00f34863 Mon Sep 17 00:00:00 2001 From: David Whittington Date: Thu, 23 Jul 2026 15:04:45 -0500 Subject: [PATCH] feat(config): make credential and cert paths configurable Allow the BigQuery service account key, gRPC TLS cert/key, and internal database SSL certificates to be located via environment variables, each falling back to the existing working-directory filename so current deployments are unaffected: - GOOGLE_APPLICATION_CREDENTIALS (default gcloud.json) - LOGFLARE_TLS_CERT_PATH / LOGFLARE_TLS_KEY_PATH (default cert.pem / cert.key) - DB_SSL_CA_CERT_PATH / DB_SSL_CLIENT_CERT_PATH / DB_SSL_CLIENT_KEY_PATH Also allow the service account key to be supplied inline via GOOGLE_APPLICATION_CREDENTIALS_JSON, which takes precedence over the file when set. This decouples credential loading from a fixed working directory, enabling deployments that inject secrets as environment variables or mounted volumes (e.g. Kubernetes) rather than baking them into the container image. --- config/runtime.exs | 37 ++++++++++++++----- .../docs/self-hosting/index.md | 22 +++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/config/runtime.exs b/config/runtime.exs index 225c7362ea..419c4014e1 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -317,8 +317,18 @@ cond do ) config_env() != :test -> - if File.exists?("gcloud.json") do - config :goth, json: File.read!("gcloud.json") + google_credentials = + case System.get_env("GOOGLE_APPLICATION_CREDENTIALS_JSON") do + json when is_binary(json) and json != "" -> + json + + _ -> + credentials_path = System.get_env("GOOGLE_APPLICATION_CREDENTIALS", "gcloud.json") + if File.exists?(credentials_path), do: File.read!(credentials_path) + end + + if google_credentials do + config :goth, json: google_credentials end config_env() == :test -> @@ -328,27 +338,34 @@ cond do raise "Missing Google or Backend credentials" end +tls_cert_path = System.get_env("LOGFLARE_TLS_CERT_PATH", "cert.pem") +tls_key_path = System.get_env("LOGFLARE_TLS_KEY_PATH", "cert.key") + if( Env.get_boolean("LOGFLARE_ENABLE_GRPC_SSL") && - File.exists?("cert.pem") && File.exists?("cert.key") + File.exists?(tls_cert_path) && File.exists?(tls_key_path) ) do config :logflare, ssl: [ - certfile: "cert.pem", - keyfile: "cert.key" + certfile: tls_cert_path, + keyfile: tls_key_path ] end +db_ssl_ca_cert_path = System.get_env("DB_SSL_CA_CERT_PATH", "db-server-ca.pem") +db_ssl_client_cert_path = System.get_env("DB_SSL_CLIENT_CERT_PATH", "db-client-cert.pem") +db_ssl_client_key_path = System.get_env("DB_SSL_CLIENT_KEY_PATH", "db-client-key.pem") + if( - Env.get_boolean("DB_SSL") && File.exists?("db-server-ca.pem") && - File.exists?("db-client-cert.pem") && File.exists?("db-client-key.pem") + Env.get_boolean("DB_SSL") && File.exists?(db_ssl_ca_cert_path) && + File.exists?(db_ssl_client_cert_path) && File.exists?(db_ssl_client_key_path) ) do base_db_ssl_opts = [ # ssl opts follow recs here: https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/ssl verify: :verify_peer, - cacertfile: Path.absname("db-server-ca.pem"), - certfile: Path.absname("db-client-cert.pem"), - keyfile: Path.absname("db-client-key.pem"), + cacertfile: Path.absname(db_ssl_ca_cert_path), + certfile: Path.absname(db_ssl_client_cert_path), + keyfile: Path.absname(db_ssl_client_key_path), depth: 3, versions: [:"tlsv1.2", :"tlsv1.3"], customize_hostname_check: [ diff --git a/docs/docs.logflare.com/docs/self-hosting/index.md b/docs/docs.logflare.com/docs/self-hosting/index.md index ff2227493d..77acda45cf 100644 --- a/docs/docs.logflare.com/docs/self-hosting/index.md +++ b/docs/docs.logflare.com/docs/self-hosting/index.md @@ -143,6 +143,14 @@ To enable SSL for the internal Logflare database: All three files must be present for SSL to be enabled. +The default filenames above are resolved relative to the working directory. To +load them from another location (for example a mounted secret volume), override +the paths with environment variables: + +- `DB_SSL_CA_CERT_PATH` - defaults to `db-server-ca.pem` +- `DB_SSL_CLIENT_CERT_PATH` - defaults to `db-client-cert.pem` +- `DB_SSL_CLIENT_KEY_PATH` - defaults to `db-client-key.pem` + ### Configuration Details The SSL connection is configured with: @@ -212,6 +220,20 @@ Thereafter, click on "Add Key" to create a new key. The key will be in a JSON fo You can also obtain the key via the `gcloud` CLI by following the [official documentation](https://cloud.google.com/iam/docs/keys-create-delete). +#### Providing the Service Account Key + +By default Logflare reads the service account key from a `gcloud.json` file in +the working directory on server startup. You can supply the key in two other +ways instead: + +- `GOOGLE_APPLICATION_CREDENTIALS` - path to the service account key file. + Defaults to `gcloud.json`. Use this to load the key from a different location, + such as a mounted secret volume. +- `GOOGLE_APPLICATION_CREDENTIALS_JSON` - the service account key JSON provided + inline as an environment variable. When set (and non-empty), it takes + precedence over the file, so no file needs to be mounted. Useful for + environments where secrets are injected as environment variables. + ## Deployment with Docker Compose Using docker compose is the **recommended method** for self-hosting.