feat(sbom): add 'Cloud Run' deployment platform marker (#220) - #249
feat(sbom): add 'Cloud Run' deployment platform marker (#220)#249nikhilpatidar wants to merge 2 commits into
Conversation
Issue NuGuardAI#220 reports that nuguard's GCP discovery is too coarse — the existing 'GCP' marker fires for any GCP-related content (gcloud, Cloud Functions, Vertex AI, generic gcr.io references) without distinguishing Cloud Run, the most common serverless deployment target for AI apps. This change adds a more specific 'Cloud Run' platform marker that fires when the scan finds: * the Knative Cloud Run service API in a YAML manifest (apiVersion: serving.knative.dev/v1), * the official google-github-actions/deploy-cloudrun GitHub Actions step, * any run.googleapis.com annotation, * a *.a.run.app runtime URL inside the file content, or * a file path containing cloudrun. The existing 'GCP' marker continues to fire in parallel — Cloud Run is a strict subset of GCP. Platforms are already deduplicated by _uniq, so a single scan produces at most one 'Cloud Run' and one 'GCP' entry even when multiple triggers match. This is the narrow, regression-pinning slice of NuGuardAI#220 that fits in one PR. Broader cookbook validation across all three clouds remains on the issue tracker. Tests: tests/sbom/test_cloud_run_detection.py (6 tests) pins the new behaviour end-to-end through extract_deployment_context: * Knative Service YAML → 'Cloud Run' + 'GCP' + 'Kubernetes' platforms * Deduplication when multiple triggers fire * GitHub Actions deploy-cloudrun step → 'Cloud Run' + 'GCP' + 'GitHub Actions' platforms * *.a.run.app URLs captured as deployment URLs * File path with 'cloudrun' substring triggers the marker * Plain Kubernetes manifest is NOT marked as 'Cloud Run' (negative test) All 188 tests in tests/sbom/ pass. ruff and mypy clean.
f096e46 to
0c6742b
Compare
KanishkThamman
left a comment
There was a problem hiding this comment.
Additive, no schema impact. One nit inline on a false-positive trigger.
| # GitHub Actions deploy step (issue #220 — these are the two | ||
| # most common ways an AI app ships to Cloud Run). | ||
| if ( | ||
| "serving.knative.dev" in text_lower |
There was a problem hiding this comment.
Nit: Knative Serving is open source and commonly self-hosted on plain GKE/EKS/AKS, so this trigger alone isn't Cloud-Run-specific and could mislabel a self-hosted Knative-on-GKE deployment as "Cloud Run". Worth a negative test case.
There was a problem hiding this comment.
Fixed in 20c00e3. Split the Cloud Run trigger into a weak signal (the Knative service API) and a set of strong signals (deploy-cloudrun GitHub Action, run.googleapis.com annotation, *.a.run.app URL, 'cloudrun' in path). The marker now fires only when a strong signal is present, OR when the Knative service API appears together with a run.googleapis.com / *.a.run.app co-signal.
Added two tests to test_cloud_run_detection.py:
- test_self_hosted_knative_service_is_not_marked_as_cloud_run: bare Knative Service YAML without any co-signal must NOT be marked Cloud Run (the exact regression).
- test_knative_service_with_run_app_url_is_marked_as_cloud_run: Knative Service + a
*.a.run.appURL in a separate file IS marked Cloud Run (pins the co-signal path).
All 6 existing tests still pass — the original positive case already includes run.googleapis.com alongside serving.knative.dev, so it satisfies the new co-signal requirement.
The Cloud Run platform marker fired on any file containing `serving.knative.dev` because that was OR'd with the strong Cloud Run-specific signals. Knative Serving is open source and commonly self-hosted on plain GKE/EKS/AKS, so a bare `serving.knative.dev/v1` Service manifest is not Cloud-Run-specific. A self-hosted Knative-on-GKE deployment would have been mis-labelled as 'Cloud Run'. Fix: split the trigger into a weak signal (the Knative service API) and a set of strong signals (deploy-cloudrun GitHub Action, `run.googleapis.com` annotation, `*.a.run.app` URL, 'cloudrun' in path). Mark as 'Cloud Run' only when: - a strong signal fires, OR - the weak Knative signal fires together with a Cloud Run co-signal (`run.googleapis.com` annotation or `*.a.run.app` URL). Tests: - test_self_hosted_knative_service_is_not_marked_as_cloud_run: bare Knative Service YAML without co-signal must NOT be marked Cloud Run (the regression). - test_knative_service_with_run_app_url_is_marked_as_cloud_run: Knative Service + a `*.a.run.app` URL in a separate file IS marked Cloud Run (pins the co-signal path). - All 6 existing tests still pass — the existing positive case already includes `run.googleapis.com` alongside `serving.knative.dev`, so it satisfies the new requirement.
db9df0a to
20c00e3
Compare
PR Type
What
Adds a more specific
Cloud Rundeployment-platform marker alongsidethe existing coarse
GCPmarker. The marker fires when any of:(
apiVersion: serving.knative.dev/v1),google-github-actions/deploy-cloudrunGitHub Actionsstep appears in a workflow,
run.googleapis.comannotation is present,*.a.run.appruntime URL appears in the file content, orcloudrun.Why
Issue #220 reports that nuguard's GCP discovery is too coarse. The
existing
GCPmarker fires for any GCP-related content (gcloud, CloudFunctions, Vertex AI, generic
gcr.ioreferences) withoutdistinguishing Cloud Run, which is the most common serverless
deployment target for AI apps today. Downstream analyzers and reports
that want to surface Cloud Run-specific concerns (e.g. unauthenticated
invoke URLs, IAM conditions for service-to-service calls) had no
programmatic way to tell those scans apart from generic GCP scans.
Root cause
extract_deployment_contextinnuguard/sbom/core/application_summary.pyhad no Cloud Run-specifictrigger. The coarse
GCPmarker fired ongcloud,cloud run,cloudrun,vertex ai, etc. but those inputs are also common fornon-Cloud-Run GCP services, so a downstream consumer cannot tell which
deployment target is actually in use.
Changes
nuguard/sbom/core/application_summary.py— adds a second platformblock in
extract_deployment_contextthat appendsCloud Runto theplatform list when any of the five triggers above fire.
tests/sbom/test_cloud_run_detection.py— 6 new regression testspinning the contract end-to-end through
extract_deployment_context:Cloud Run+GCP+Kubernetesdeploy-cloudrunstep →Cloud Run+GCP+GitHub Actions*.a.run.appURLs captured asdeployment_urlscloudrunsubstring triggers the markerCloud Run(so we don't over-fire)Tests
tests/sbom/test_cloud_run_detection.py: 6 new tests, all passing.tests/sbom/full suite: 188 tests passing.ruff checkclean.mypyclean on the touched module.Backward compatibility
GCPmarker continues to fire in parallel — Cloud Run is astrict subset of GCP, so downstream consumers reading
GCPkeepworking.
_uniq(...)callon the platform list, so a single scan produces at most one
Cloud Runand oneGCPentry even when multiple triggers match.returned list (
deployment_platforms) gain an additional possibleentry.
What this PR does NOT do (issue #220 remains open)
This PR is the narrow, regression-pinning slice of #220 — adding the
marker and the tests. The following remain on the issue tracker for
follow-up PRs:
Go AI apps on AWS / Azure / GCP) — the request in [Feature]: Extending AI-BOM support #220's "Possible
Solution" list.
K_SERVICE/GOOGLE_CLOUD_PROJECTenv vars (the GitHub ActionsAWS App Service equivalent is implemented for Azure but not yet for
Cloud Run).
cloudbuild.yaml,app.yaml).This PR deliberately does not use the
Closes #220syntax,because GitHub's auto-close behaviour does not understand the
"partial" qualification; the issue should remain open until the
broader cookbook-validation work is done.
Addresses part of #220