{"id":18941462,"url":"https://github.com/mchmarny/sds-demo","last_synced_at":"2025-08-05T10:18:59.418Z","repository":{"id":77051282,"uuid":"564748833","full_name":"mchmarny/sds-demo","owner":"mchmarny","description":"Software Delivery Shield demo illustrating end-to-end solution for secure software supply chain","archived":false,"fork":false,"pushed_at":"2023-07-25T22:11:37.000Z","size":9273,"stargazers_count":5,"open_issues_count":0,"forks_count":14,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-15T22:44:26.987Z","etag":null,"topics":["demo","devops","gcp","sds","security","supply-chain"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mchmarny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-11T12:07:29.000Z","updated_at":"2024-12-22T23:27:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"de157d18-2727-4e93-85da-51ee5ee788f9","html_url":"https://github.com/mchmarny/sds-demo","commit_stats":null,"previous_names":["mchmarny/cloudbuild-demo"],"tags_count":90,"template":false,"template_full_name":null,"purl":"pkg:github/mchmarny/sds-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mchmarny%2Fsds-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mchmarny%2Fsds-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mchmarny%2Fsds-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mchmarny%2Fsds-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mchmarny","download_url":"https://codeload.github.com/mchmarny/sds-demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mchmarny%2Fsds-demo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268876802,"owners_count":24322112,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-05T02:00:12.334Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["demo","devops","gcp","sds","security","supply-chain"],"created_at":"2024-11-08T12:28:09.613Z","updated_at":"2025-08-05T10:18:59.411Z","avatar_url":"https://github.com/mchmarny.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GCP Secure CI/CD Pipeline Demo\n\nThis repo bootstraps a CI/CD pipeline on Google Cloud to demonstrate policy controls for container image provenance, and for GKE authorization based on attestation. What's included:\n\n* Cloud Build pipeline with on tag GitHub repo trigger and SBOM generation\n* Test and Prod GKE clusters configured for Binary Authorization\n* 2 Binary Authorization policies to ensure that images:\n  * Have Cloud Build provenance (been built in GCB)\n  * Meet minimal vulnerability validation policy (been successfully scanned using Kritis)\n* 1 vulnerability signing policy with min fixable and un-fixable settings\n* Artifact Registry registry with SLSA level 3 verification \n* Container analysis with vulnerability scanning and meta-data management \n* Cloud Deploy pipeline with approval-based test to prod promotion\n* GKE security posture dashboard with Configuration concerns\n\n## Requirements \n\n* [gcloud](https://cloud.google.com/sdk/docs/install)\n* [jq](https://stedolan.github.io/jq/download/)\n\n## Setup \n\n### Setup Environment  \n\nStart by forking [this repo](https://github.com/mchmarny/sds-demo) into your GitHub Account. Navigate to https://github.com/mchmarny/sds-demo and click fork.\n\n![](images/fork.png)\n\nNext, clone that repo locally: \n\n```shell\ngit clone git@github.com:\u003cyour-github-username\u003e/sds-demo.git\ncd sds-demo\n```\n\n### Provision Resources \n\nTo deploy this pipeline into your GCP project, you will also need to export the ID of target project:\n\n```shell\nexport PROJECT_ID=\u003cyour-project-id-here\u003e\n```\n\nNext, create the required GCP resources (KMS, Artifact Registry repo, and service account policies):\n\n```shell\nsetup/init\n```\n\nCreate GKE cluster:\n\n```shell\nsetup/clusters\n```\n\nAnd, configure Binary Authorization:\n\n```shell\nsetup/binauthz\n```\n\nNext, trust all Google-provided system images in UI (bottom):\n\nhttps://console.cloud.google.com/security/binary-authorization/policy/edit\n\n* Expand `Additional settings for GKE and Anthos deployments`\n* Check `Trust all Google-provided system images`\n* Click `SAVE POLICY`\n\n\u003e Still have not been able to figure out how to enable this programmatically.\n\nWait for cluster to be created:\n\n\u003e When ready, status will change from `PROVISIONING` to `RUNNING`\n\n```shell\nwatch gcloud container clusters list --filter=\"resourceLabels.demo:build\"\n```\n\n### Configure GCB Trigger \n\n\u003e The OAuth bit can't be scripted, so we have to do this manually.\n\nNavigate to the triggers page\n\nhttps://console.cloud.google.com/cloud-build/triggers\n\n\u003e Make sure to set the region to your region (default: `us-west1`) at the top left of the screen.\n\nGo through the `Connect Repository` flow. The important bits:\n\n* **Select source**: GitHub (Cloud Build GitHub App)\n* Select repository\n  * **GitHub Account**: this is your GitHub Username (should be populated after successful auth)\n  * **Repository**: the newly cloned repo (`your-github-username/sds-demo`)\n* **Create a trigger**: click DONE (we will script that part next)\n\n\n#### Create Trigger\n\nCreate the GCP worker pool and the trigger on tag in the cloned app repo:\n\n\u003e Make sure to replace the `your-github-username` with your GitHub username.\n\n```shell\nsetup/trigger \u003cyour-github-username\u003e\n```\n\nCheck that the trigger has been created: \n\nhttps://console.cloud.google.com/cloud-build/triggers\n\n#### Enable Permissions \n\nFinally, navigate to GCB settings, and enable following permissions: \n\n\u003e This is used in the demo later.\n\n* Kubernetes Engine\n* Cloud KMS\n* Service Accounts\n* Cloud Build\n\nhttps://console.cloud.google.com/cloud-build/settings/service-account\n\n\n## Demo\n\n### Attestation Validation\n\nDeploy sample image that **was not built in GCP**. First, get the configuration with which the demo clusters were configured:\n\n```shell\n. setup/config\n```\n\nNext, get the `test` cluster credentials:\n\n```shell\ngcloud container clusters get-credentials demo-test --region $CLUSTER_ZONE\n```\n\nThen `apply` command will work because Kubernetes is declarative but as we will see in a minute, the workflow will fail to deploy.\n\n```shell\nkubectl apply -f test/non-gcp-built-image.yaml\n```\n\n* Navigate to GKE [workloads](https://console.cloud.google.com/kubernetes/workload/overview), and show how `non-gcp-built-image` failed to deploy due to lack of attestation (use cluster/namespace filters  if needed).\n  * The error should have names of the two attestors that valid deployments need to have in this cluster: `built-by-cloud-build` and `vulnz-attestor`\n* Navigate to Security Policy and show [BinAuth Policy](https://console.cloud.google.com/security/binary-authorization/policy) rules\n  * Vulnerability attestation (scanned and signed with KMS key)\n  * Built in Cloud Build (attested with KMS key signature)\n  * Show dry run and images exempt option on policy as a means to incremental rollout strategy\n\n![](images/app-bad.png)\n\n### Build on Tag (end-to-end demo)\n\n* Show delivery pipeline config `app/clouddeploy.yaml`\n* Make some code change\n  * Make sure you bump version number in `app/.version`\n* Git add, commit, push:\n\n```shell\ngit add --all\ngit commit -m 'demo'\ngit push --all\n```\n\n* Git tag and push, to trigger the GCB pipeline:\n\n```shell\nexport VERSION_TAG=$(cat app/.version)\ngit tag -s -m \"demo\" $VERSION_TAG\ngit push origin $VERSION_TAG\n```\n\n* Navigate to Cloud Build [triggers](https://console.cloud.google.com/cloud-build/triggers)\n  * Push on tag (pattern)\n  * Back in code, review config `app/cloudbuild.yaml`\n  * Review the vulnerability scanner policy `policy/vulnz-signing-policy.yaml`\n\n![](images/trigger.png)\n\n* Navigate to Cloud Build [builds](https://console.cloud.google.com/cloud-build/builds) in UI\n  * Drill on active build \n  * Review steps (show sbom, scan, and attest running concurrently):\n    * test - tests the code one more time\n    * build - builds a docker image\n    * publish - publishes that image to Artifact Registry\n    * sbom - generates Software Bill of Materials for the published image\n    * scan - scans image for culnerabilities (note: this step will fail if scanner finds vulnerabilities with severity higher than the max defined in `policy/vulnz-signing-policy.yaml`)\n    * attest - creates and publishes attestation that this iamge was built in GCB using KMS key\n    * release - deploys the image via Cloud Deploy\n  * On Build Summary, show Build Artifacts \u003e Image security insights ([SLSA Build Level 3](https://slsa.dev/spec/v0.1/levels))\n    * Show `Dependencies` and `Build Provenance` YAMLs\n    ![](images/build.png)\n\n* Navigate to Artifact Registry [list of registries](https://console.cloud.google.com/artifacts)\n  * Drill into `sds-demo/hello`\n  * Show attestation and signature artifacts (`*.att` and `*.sig`)\n  * Navigate to Manifest in `*.sig`, show cosign/signature\n  * Navigate to the image (the one with the `v*` tag) and show Vulnerabilities\n    ![](images/vulns.png)\n  * Show [policy](policy/vulnz-signing-policy.yaml)\n  * Show Kritis Signer step in [cloudbuild.yaml](app/cloudbuild.yaml)\n  * Show in-toto attestation in CLI:\n\n**Retrieve provenance as JSON**:\n\n```shell\ngcloud artifacts docker images describe $digest --show-provenance --format json \u003e provenance.json\n```\n\n**Verify provenance**:\n\n\u003e Using [slsa-verifier](https://github.com/slsa-framework/slsa-verifier#compilation-from-source)\n\n```shell\nslsa-verifier verify-image $digest \\\n  --provenance-path provenance.json \\\n  --source-uri https://github.com/mchmarny/sds-demo \\\n  --builder-id https://cloudbuild.googleapis.com/GoogleHostedWorker@v0.3\n```\n\n\u003e Note, `source-tag` tag is not supported in GCB verification. The `source-uri` and `builder-id` come from `materials.uri` and `builder.id` respectively in the in-toto statement (`provenance_summary.provenance.build.intotoStatement`).\n  * Extract the SBOM attestation (update the key location as needed)\n\n```shell\ncosign verify-attestation --type spdxjson \\\n  --key gcpkms://projects/cloudy-demos/locations/us-west1/keyRings/binauthz/cryptoKeys/binauthz-signer/cryptoKeyVersions/1 \\\n  $digest | jq -r '.payload' | base64 -d | jq .\n```\n\n\u003e Make sure the Cloud Build job completed before proceeding.\n\n* Navigate to Cloud Deploy [pipelines](https://console.cloud.google.com/deploy/delivery-pipelines)\n  * Drill into `deploy-demo-pipeline`\n  * Show 2 environments (test, prod)\n  * Drill into release, rollouts, and targets \n\n![](images/deploy.png)\n\n* Navigate to GKE [workloads](https://console.cloud.google.com/kubernetes/workload/overview)\n  * Drill into `hello` (note `non-gcp-built-image` erred due to lack of attestation)\n  * Navigate to exposed `hello` service at the bottom \n  * Click on endpoint, and show version using `/api/ping` (should be same as the version in `.version` file in the repo)\n\n![](images/app-good.png)\n\n* Back to Cloud Deploy [pipelines](https://console.cloud.google.com/deploy/delivery-pipelines) \n  * Show promotion, review, and approval with manifest diffs and annotation comp (show more)\n\n![](images/approve.png)\n\n* Navigate to Binary Authorization [policy](https://console.cloud.google.com/security/binary-authorization/policy)\n  * Show cluster specific rules, and edit policy\n  * Show Custom exemption rules\n  * Show GKE cluster-specific rules\n\n![](images/binauthz.png)\n\n* Show GKE [Security Posture](https://console.cloud.google.com/kubernetes/security/dashboard)\n  * Show concerns (note: there may not be much, if you are using brand new project for this demo)\n\n![](images/posture.png)\n\n## Cleanup \n\n```shell\nsetup/delete\n```\n\n## Disclaimer\n\nThis is my personal project and it does not represent my employer. While I do my best to ensure that everything works, I take no responsibility for issues caused by this code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmchmarny%2Fsds-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmchmarny%2Fsds-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmchmarny%2Fsds-demo/lists"}