From ef82f9462794e5da8b07f80d37d7ac8b22118f6a Mon Sep 17 00:00:00 2001 From: Fauzaan Date: Mon, 13 Jul 2026 08:02:59 +0000 Subject: [PATCH 1/3] fix(auth): inject Google OAuth credentials at build time Remove the hardcoded Google OAuth client ID and client secret from source and inject them at compile time from GitHub Actions secrets (WUKONG_GOOGLE_CLIENT_ID / WUKONG_GOOGLE_CLIENT_SECRET), following the same pattern as WUKONG_HONEYCOMB_API_KEY in the telemetry crate. - prod builds (--features prod) fail at compile time if the secrets are missing, so a release can never ship without credentials - dev builds fall back to empty strings so local builds and tests work without any secrets Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 2 ++ .github/workflows/release.yml | 2 ++ cli/src/auth/google_cloud.rs | 21 ++++++++++++++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fabbbb0c..dcb180b8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,8 @@ env: CARGO_TERM_COLOR: always CICD_INTERMEDIATES_DIR: "_cicd-intermediates" WUKONG_HONEYCOMB_API_KEY: ${{ secrets.WUKONG_HONEYCOMB_API_KEY }} + WUKONG_GOOGLE_CLIENT_ID: ${{ secrets.WUKONG_GOOGLE_CLIENT_ID }} + WUKONG_GOOGLE_CLIENT_SECRET: ${{ secrets.WUKONG_GOOGLE_CLIENT_SECRET }} CI: true jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 272cc05f..a36be075 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,8 @@ env: CARGO_TERM_COLOR: always CICD_INTERMEDIATES_DIR: "_cicd-intermediates" WUKONG_HONEYCOMB_API_KEY: ${{ secrets.WUKONG_HONEYCOMB_API_KEY }} + WUKONG_GOOGLE_CLIENT_ID: ${{ secrets.WUKONG_GOOGLE_CLIENT_ID }} + WUKONG_GOOGLE_CLIENT_SECRET: ${{ secrets.WUKONG_GOOGLE_CLIENT_SECRET }} jobs: tag-name: diff --git a/cli/src/auth/google_cloud.rs b/cli/src/auth/google_cloud.rs index fe8ec1cc..d926e527 100644 --- a/cli/src/auth/google_cloud.rs +++ b/cli/src/auth/google_cloud.rs @@ -49,9 +49,24 @@ impl InstalledFlowDelegate for InstalledFlowBrowserDelegate { } } -const GOOGLE_CLIENT_ID: &str = - "16448589901-ccrhj03hhg6adn9uv8vi2trnpmd62k6n.apps.googleusercontent.com"; -const GOOGLE_CLIENT_SECRET: &str = "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"; +// Injected at compile time from the WUKONG_GOOGLE_CLIENT_ID / WUKONG_GOOGLE_CLIENT_SECRET +// secrets in CI (same pattern as WUKONG_HONEYCOMB_API_KEY in the telemetry crate). +// Prod builds fail if the env vars are missing; dev builds fall back to empty +// (set both locally to test the Google login flow). +#[cfg(feature = "prod")] +const GOOGLE_CLIENT_ID: &str = env!("WUKONG_GOOGLE_CLIENT_ID"); +#[cfg(not(feature = "prod"))] +const GOOGLE_CLIENT_ID: &str = match option_env!("WUKONG_GOOGLE_CLIENT_ID") { + Some(client_id) => client_id, + None => "", +}; +#[cfg(feature = "prod")] +const GOOGLE_CLIENT_SECRET: &str = env!("WUKONG_GOOGLE_CLIENT_SECRET"); +#[cfg(not(feature = "prod"))] +const GOOGLE_CLIENT_SECRET: &str = match option_env!("WUKONG_GOOGLE_CLIENT_SECRET") { + Some(secret) => secret, + None => "", +}; const TOKEN_URI: &str = "https://oauth2.googleapis.com/token"; const AUTH_URI: &str = "https://accounts.google.com/o/oauth2/auth"; const REDIRECT_URI: &str = "http://127.0.0.1/8855"; From d119afc1d4f20b6e28f21e86e080f032e1d8aea9 Mon Sep 17 00:00:00 2001 From: Fauzaan Date: Mon, 13 Jul 2026 08:29:20 +0000 Subject: [PATCH 2/3] fix(auth): pass Google OAuth env vars through cross and guard empty values - Add GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET to Cross.toml passthrough so the Dockerized Linux builds can see them (root cause of the Linux CI failures) - Rename env vars to match the existing GOOGLE_CLIENT_SECRET repo secret naming - Add compile-time asserts: a missing Actions secret expands to an empty string which env!() accepts, so prod builds now fail loudly instead of shipping blank credentials Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- Cross.toml | 8 +++++++- cli/src/auth/google_cloud.rs | 28 +++++++++++++++++++++------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcb180b8..9b67cdbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,8 +10,8 @@ env: CARGO_TERM_COLOR: always CICD_INTERMEDIATES_DIR: "_cicd-intermediates" WUKONG_HONEYCOMB_API_KEY: ${{ secrets.WUKONG_HONEYCOMB_API_KEY }} - WUKONG_GOOGLE_CLIENT_ID: ${{ secrets.WUKONG_GOOGLE_CLIENT_ID }} - WUKONG_GOOGLE_CLIENT_SECRET: ${{ secrets.WUKONG_GOOGLE_CLIENT_SECRET }} + GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} CI: true jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a36be075..ab78fb24 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,8 +9,8 @@ env: CARGO_TERM_COLOR: always CICD_INTERMEDIATES_DIR: "_cicd-intermediates" WUKONG_HONEYCOMB_API_KEY: ${{ secrets.WUKONG_HONEYCOMB_API_KEY }} - WUKONG_GOOGLE_CLIENT_ID: ${{ secrets.WUKONG_GOOGLE_CLIENT_ID }} - WUKONG_GOOGLE_CLIENT_SECRET: ${{ secrets.WUKONG_GOOGLE_CLIENT_SECRET }} + GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} jobs: tag-name: diff --git a/Cross.toml b/Cross.toml index d3678270..8f87e47d 100644 --- a/Cross.toml +++ b/Cross.toml @@ -1,5 +1,11 @@ [build.env] -passthrough = ["WUKONG_HONEYCOMB_API_KEY", "OKTA_CLIENT_ID", "WUKONG_API_URL"] +passthrough = [ + "WUKONG_HONEYCOMB_API_KEY", + "OKTA_CLIENT_ID", + "WUKONG_API_URL", + "GOOGLE_CLIENT_ID", + "GOOGLE_CLIENT_SECRET", +] [target.x86_64-unknown-linux-gnu] pre-build = [ diff --git a/cli/src/auth/google_cloud.rs b/cli/src/auth/google_cloud.rs index d926e527..8bee0287 100644 --- a/cli/src/auth/google_cloud.rs +++ b/cli/src/auth/google_cloud.rs @@ -49,24 +49,38 @@ impl InstalledFlowDelegate for InstalledFlowBrowserDelegate { } } -// Injected at compile time from the WUKONG_GOOGLE_CLIENT_ID / WUKONG_GOOGLE_CLIENT_SECRET +// Injected at compile time from the GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET // secrets in CI (same pattern as WUKONG_HONEYCOMB_API_KEY in the telemetry crate). -// Prod builds fail if the env vars are missing; dev builds fall back to empty -// (set both locally to test the Google login flow). +// Prod builds fail if the env vars are missing or empty; dev builds fall back +// to empty (set both locally to test the Google login flow). #[cfg(feature = "prod")] -const GOOGLE_CLIENT_ID: &str = env!("WUKONG_GOOGLE_CLIENT_ID"); +const GOOGLE_CLIENT_ID: &str = env!("GOOGLE_CLIENT_ID"); #[cfg(not(feature = "prod"))] -const GOOGLE_CLIENT_ID: &str = match option_env!("WUKONG_GOOGLE_CLIENT_ID") { +const GOOGLE_CLIENT_ID: &str = match option_env!("GOOGLE_CLIENT_ID") { Some(client_id) => client_id, None => "", }; #[cfg(feature = "prod")] -const GOOGLE_CLIENT_SECRET: &str = env!("WUKONG_GOOGLE_CLIENT_SECRET"); +const GOOGLE_CLIENT_SECRET: &str = env!("GOOGLE_CLIENT_SECRET"); #[cfg(not(feature = "prod"))] -const GOOGLE_CLIENT_SECRET: &str = match option_env!("WUKONG_GOOGLE_CLIENT_SECRET") { +const GOOGLE_CLIENT_SECRET: &str = match option_env!("GOOGLE_CLIENT_SECRET") { Some(secret) => secret, None => "", }; + +// A missing GitHub Actions secret expands to an empty string rather than an +// undefined env var, which env!() would happily accept. Guard against +// releasing a binary with blank credentials. +#[cfg(feature = "prod")] +const _: () = assert!( + !GOOGLE_CLIENT_ID.is_empty(), + "GOOGLE_CLIENT_ID must not be empty in prod builds" +); +#[cfg(feature = "prod")] +const _: () = assert!( + !GOOGLE_CLIENT_SECRET.is_empty(), + "GOOGLE_CLIENT_SECRET must not be empty in prod builds" +); const TOKEN_URI: &str = "https://oauth2.googleapis.com/token"; const AUTH_URI: &str = "https://accounts.google.com/o/oauth2/auth"; const REDIRECT_URI: &str = "http://127.0.0.1/8855"; From 95dbd99b5e1204a0d90ba8ab6063c9900fec7247 Mon Sep 17 00:00:00 2001 From: Fauzaan Date: Mon, 13 Jul 2026 08:32:20 +0000 Subject: [PATCH 3/3] ci: read GOOGLE_CLIENT_ID from repo variables The client ID is a public identifier, so it lives in Actions variables (vars.GOOGLE_CLIENT_ID) rather than secrets; only the client secret stays in secrets. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b67cdbb..9cc7fe2f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ env: CARGO_TERM_COLOR: always CICD_INTERMEDIATES_DIR: "_cicd-intermediates" WUKONG_HONEYCOMB_API_KEY: ${{ secrets.WUKONG_HONEYCOMB_API_KEY }} - GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + GOOGLE_CLIENT_ID: ${{ vars.GOOGLE_CLIENT_ID }} GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} CI: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ab78fb24..c3799e7e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ env: CARGO_TERM_COLOR: always CICD_INTERMEDIATES_DIR: "_cicd-intermediates" WUKONG_HONEYCOMB_API_KEY: ${{ secrets.WUKONG_HONEYCOMB_API_KEY }} - GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} + GOOGLE_CLIENT_ID: ${{ vars.GOOGLE_CLIENT_ID }} GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }} jobs: