From 8b2c79e70fbc04bc2ab5c58a80e6679aed717299 Mon Sep 17 00:00:00 2001 From: Mick Grove Date: Fri, 18 Jul 2025 15:26:18 -0700 Subject: [PATCH] Updating GitHub Action to generate Docker image. Added rules for Diffbot, ai21, baseten. Fixed supabase rule. Added 'alg' to JWT validation output --- .github/workflows/release-docker.yml | 14 ++++-- CHANGELOG.md | 5 +++ Cargo.toml | 2 +- data/rules/ai21.yml | 44 +++++++++++++++++++ data/rules/baseten.yml | 42 ++++++++++++++++++ data/rules/diffbot.yml | 35 +++++++++++++++ .../rules/{supabasetoken.yml => supabase.yml} | 3 +- src/validation/jwt.rs | 3 +- 8 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 data/rules/ai21.yml create mode 100644 data/rules/baseten.yml create mode 100644 data/rules/diffbot.yml rename data/rules/{supabasetoken.yml => supabase.yml} (95%) diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index dcd1ea9..baee4c1 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -1,8 +1,8 @@ # .github/workflows/release-docker.yml name: Publish Docker image on: - push: - tags: ["v*.*.*"] # every semantic-version tag + release: + types: [published] permissions: contents: read packages: write @@ -18,7 +18,13 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - + - name: Prepare release tag + id: tag + run: | + TAG=${RELEASE_TAG#v} + echo "tag=$TAG" >>"$GITHUB_OUTPUT" + env: + RELEASE_TAG: ${{ github.event.release.tag_name }} - uses: docker/build-push-action@v5 with: context: . @@ -27,4 +33,4 @@ jobs: push: true tags: | ghcr.io/mongodb/kingfisher:latest - ghcr.io/mongodb/kingfisher:${{ github.ref_name }} + ghcr.io/mongodb/kingfisher:${{ steps.tag.outputs.tag }} diff --git a/CHANGELOG.md b/CHANGELOG.md index d385891..81b32a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. +## [1.23.0] +- Updating GitHub Action to generate Docker image +- Added rules for Diffbot, ai21, baseten +- Fixed supabase rule + ## [1.22.0] - Added rules for Google Gemini AI, Cohere, Stability.ai, Replicate, Runway, Clarifai - Upgraded dependencies diff --git a/Cargo.toml b/Cargo.toml index 4bf7e3d..3d6bed2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ publish = false [package] name = "kingfisher" -version = "1.22.0" +version = "1.23.0" edition.workspace = true rust-version.workspace = true license.workspace = true diff --git a/data/rules/ai21.yml b/data/rules/ai21.yml new file mode 100644 index 0000000..7a400eb --- /dev/null +++ b/data/rules/ai21.yml @@ -0,0 +1,44 @@ +rules: + - name: AI21 Studio API Key + id: kingfisher.ai21studio.1 + pattern: | + (?xi) + \b + ai21 + (?:.|[\n\r]){0,32}? + \b + ( + [0-9a-f]{8} + - + [0-9a-f]{4} + - + [0-9a-f]{4} + - + [0-9a-f]{4} + - + [0-9a-f]{12} + ) + \b + min_entropy: 3.2 + confidence: medium + examples: + - ai21 = 90cd6930-a9ae-4f15-8da0-dc1bbcd814b9 + - 'ai21_key: befa7ec1-1129-4713-8e92-bb53d1a4f632' + - ai21_token = ec2e14e9-0309-459b-ba76-1e59e1f42b87 + references: + - https://docs.ai21.com/reference/authentication + - https://docs.ai21.com/reference/manage-library-ref/list-library-files + + validation: + type: Http + content: + request: + method: GET + url: https://api.ai21.com/studio/v1/library/files + headers: + Authorization: Bearer {{ TOKEN }} + Accept: application/json + response_matcher: + - report_response: true + - type: StatusMatch + status: [200] \ No newline at end of file diff --git a/data/rules/baseten.yml b/data/rules/baseten.yml new file mode 100644 index 0000000..17d2285 --- /dev/null +++ b/data/rules/baseten.yml @@ -0,0 +1,42 @@ +rules: + - name: Baseten API Key + id: kingfisher.baseten.1 + pattern: | + (?x) + \b + ( + [A-Za-z0-9]{8} + \. + [A-Za-z0-9]{32} + ) + \b + min_entropy: 3.4 + confidence: medium + examples: + - WSsDXzCD.uOcxAp7k82IvCKyY36TnpVbP4ZszP1qw + - crXCQC3W.CgCGGY1b9IfJan5TppW0Z07C9oMN2DmR + - h2wFkhFC.3WFVwVcxGFr4Qup0gyhvIuONwQxEpL0A + - XqbIpj04.x73j1zLUOEgGIKROqVbxsmggPdL8JvAY + references: + - https://docs.baseten.co/examples/vllm + - https://docs.baseten.co/reference/management-api/api-keys/lists-the-users-api-keys + - https://docs.baseten.co/reference/training-api/overview#authentication + - https://docs.baseten.co/reference/management-api/api-keys/creates-an-api-key + validation: + type: Http + content: + request: + method: GET + url: https://api.baseten.co/v1/api_keys + headers: + Authorization: Api-Key {{ TOKEN }} + response_matcher: + - report_response: true + - type: StatusMatch + status: [200] + - type: JsonValid + - type: WordMatch + match_all_words: true + words: + - '"name"' + - '"type"' diff --git a/data/rules/diffbot.yml b/data/rules/diffbot.yml new file mode 100644 index 0000000..05e989b --- /dev/null +++ b/data/rules/diffbot.yml @@ -0,0 +1,35 @@ +rules: + - name: Diffbot API Key + id: kingfisher.diffbot.1 + pattern: | + (?xi) + \b + diffbot + (?:.|[\n\r]){0,32}? + \b + ( + [0-9a-z]{32} + ) + \b + min_entropy: 3.0 + examples: + - diffbot_key = a7424adbafc4624e61482d0f60e43016 + references: + - https://docs.diffbot.com/reference/account + validation: + type: Http + content: + request: + method: GET + url: >- + https://api.diffbot.com/v4/account?token={{ TOKEN }} + response_matcher: + - report_response: true + - type: StatusMatch + status: [200] + - type: JsonValid + - type: WordMatch + match_all_words: true + words: + - '"name"' + - '"email"' \ No newline at end of file diff --git a/data/rules/supabasetoken.yml b/data/rules/supabase.yml similarity index 95% rename from data/rules/supabasetoken.yml rename to data/rules/supabase.yml index d244d3b..6cb4abb 100644 --- a/data/rules/supabasetoken.yml +++ b/data/rules/supabase.yml @@ -4,9 +4,8 @@ rules: pattern: | (?xi) \b - sbp_ ( - [a-z0-9_-]{40} + sbp_[a-z0-9_-]{40} ) \b min_entropy: 3.5 diff --git a/src/validation/jwt.rs b/src/validation/jwt.rs index 59cac9d..327f0d2 100644 --- a/src/validation/jwt.rs +++ b/src/validation/jwt.rs @@ -75,6 +75,7 @@ pub async fn validate_jwt(token: &str) -> Result<(bool, String)> { if let Some(iss) = claims.iss.clone() { // parse header now (kid, alg) let header = decode_header(token).map_err(|e| anyhow!("decode header: {e}"))?; + let alg = header.alg; // build discovery URL and fetch it (redirects disabled) let config_url = format!("{}/.well-known/openid-configuration", iss.trim_end_matches('/')); @@ -161,7 +162,7 @@ pub async fn validate_jwt(token: &str) -> Result<(bool, String)> { return Ok(( true, - format!("JWT valid (iss: {issuer}, aud: {:?})", extract_aud_strings(&claims)), + format!("JWT valid (alg: {:?}, iss: {issuer}, aud: {:?})", alg, extract_aud_strings(&claims)), )); }