{"id":47733034,"url":"https://github.com/richonn/shieldci","last_synced_at":"2026-04-02T22:00:01.330Z","repository":{"id":347181617,"uuid":"1189030439","full_name":"Richonn/ShieldCI","owner":"Richonn","description":"GitHub Action that auto-generates hardened CI/CD DevSecOps pipelines — lint, tests, Trivy, Gitleaks, SAST and more — and   opens a PR with the generated workflows.","archived":false,"fork":false,"pushed_at":"2026-03-27T00:18:31.000Z","size":68,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T11:19:10.824Z","etag":null,"topics":["automation","ci-cd","devops","devsecops","github-actions","gitleaks","golang","pipeline","sast","security","trivy"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Richonn.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-22T22:34:48.000Z","updated_at":"2026-03-27T00:33:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Richonn/ShieldCI","commit_stats":null,"previous_names":["richonn/shieldci"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/Richonn/ShieldCI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richonn%2FShieldCI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richonn%2FShieldCI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richonn%2FShieldCI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richonn%2FShieldCI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Richonn","download_url":"https://codeload.github.com/Richonn/ShieldCI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richonn%2FShieldCI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31317829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T21:35:00.834Z","status":"ssl_error","status_checked_at":"2026-04-02T21:34:59.806Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["automation","ci-cd","devops","devsecops","github-actions","gitleaks","golang","pipeline","sast","security","trivy"],"created_at":"2026-04-02T22:00:00.527Z","updated_at":"2026-04-02T22:00:01.318Z","avatar_url":"https://github.com/Richonn.png","language":"Go","readme":"# ShieldCI\n\n\u003e GitHub Action that auto-generates hardened CI/CD DevSecOps pipelines and opens a PR with the generated workflows.\n\n[![CI](https://github.com/Richonn/ShieldCI/actions/workflows/ci.yml/badge.svg)](https://github.com/Richonn/ShieldCI/actions/workflows/ci.yml)\n[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/12352/badge)](https://www.bestpractices.dev/projects/12352)\n\n## Quick start\n\n**1. Create a Personal Access Token** with scopes `repo` + `workflow` and store it as a secret (e.g. `GH_TOKEN`) in your repository.\n\n**2. Add the action to your workflow:**\n\n```yaml\n- uses: Richonn/ShieldCI@v1\n  with:\n    github-token: ${{ secrets.GH_TOKEN }}\n```\n\nShieldCI will detect your stack, generate the appropriate workflows, and open a PR.\n\n\u003e **Why a PAT?** GitHub blocks writes to `.github/workflows/` for `GITHUB_TOKEN` by design. A PAT with `workflow` scope is required to create workflow files.\n\n## Inputs\n\n| Input | Required | Default | Description |\n|---|---|---|---|\n| `github-token` | ✅ | — | Token for creating branches and PRs |\n| `language` | ❌ | `auto` | Language override: `node`, `python`, `java`, `go`, `auto` |\n| `docker` | ❌ | `auto` | Docker detection: `true`, `false`, `auto` |\n| `kubernetes` | ❌ | `false` | Include K8s deploy workflow |\n| `enable-trivy` | ❌ | `true` | Add Trivy image scan job |\n| `enable-gitleaks` | ❌ | `true` | Add Gitleaks secret scan job |\n| `enable-sast` | ❌ | `true` | Add SAST job (CodeQL or Semgrep) |\n| `sast-tool` | ❌ | `codeql` | SAST tool: `codeql` or `semgrep` |\n| `branch-name` | ❌ | `shieldci/generated-workflows` | Branch to push generated workflows to |\n| `pr-title` | ❌ | `[ShieldCI] Add CI/CD DevSecOps pipeline` | PR title |\n| `dry-run` | ❌ | `false` | If `true`, print generated workflows to the Job Summary without creating a branch or PR |\n| `max-depth` | ❌ | `3` | Max directory depth for monorepo component detection |\n\n## Outputs\n\n| Output | Description |\n|---|---|\n| `pr-url` | URL of the created pull request |\n| `detected-stack` | Detected stack as JSON |\n| `generated-files` | Comma-separated list of generated file paths |\n\n## Using outputs in downstream steps\n\n```yaml\n- name: Generate pipelines\n  id: shieldci\n  uses: Richonn/ShieldCI@v1\n  with:\n    github-token: ${{ secrets.GH_TOKEN }}\n\n- name: Print detected stack\n  run: |\n    echo \"Stack: ${{ steps.shieldci.outputs.detected-stack }}\"\n    echo \"PR: ${{ steps.shieldci.outputs.pr-url }}\"\n\n- name: Conditional step based on detected stack\n  if: ${{ fromJson(steps.shieldci.outputs.detected-stack).language == 'go' }}\n  run: echo \"Go project detected — run extra Go-specific steps here\"\n```\n\n\u003e `detected-stack` is a JSON string — use `fromJson()` to access individual fields (`language`, `docker`, `k8s`).\n\n## Supported stacks\n\n| Language | CI | Lint | Test | Build |\n|---|---|---|---|---|\n| Go | ✅ | golangci-lint | go test -race | go build |\n| Node.js | ✅ | eslint | jest | npm/yarn build |\n| Python | ✅ | ruff | pytest | build/poetry |\n| Java | ✅ | — | mvn/gradle | mvn/gradle |\n| Rust | ✅ | cargo clippy | cargo test | cargo build |\n\nDocker and Kubernetes workflows are generated automatically when detected.\n\n## Security tools\n\n- **Gitleaks** — secret detection in git history\n- **Trivy** — container vulnerability scanning with SARIF upload to GitHub Security tab\n- **CodeQL / Semgrep** — static analysis (SAST)\n- **Syft** — SBOM generation (Software Bill of Materials)\n- **OpenSSF Scorecard** — automated security posture scoring (weekly + on push), results uploaded to GitHub Security tab\n- **SLSA provenance** — cryptographic attestation of the build process (level 3), stored in the Rekor transparency log\n\n### Semgrep custom rules\n\nWhen `sast-tool: semgrep` is set and no `.semgrep/` directory exists in the target repo, ShieldCI generates a `.semgrep/rules/example.yml` file with a commented example rule to get you started.\n\nIf `.semgrep/` already exists, ShieldCI uses your existing rules (`--config=.semgrep/`) instead of the default community ruleset (`--config=auto`).\n\n## Dry-run mode\n\nSet `dry-run: \"true\"` to preview the generated workflows in the GitHub Actions Job Summary without touching your repository:\n\n```yaml\n- uses: Richonn/ShieldCI@v1\n  with:\n    github-token: ${{ secrets.GH_TOKEN }}\n    dry-run: \"true\"\n```\n\nThe Job Summary will display each generated workflow file as a fenced YAML block. No branch or PR is created.\n\n## Versioning\n\nShieldCI uses a floating major tag (`v1`) that always points to the latest release in the `v1.x.x` series. This means `Richonn/ShieldCI@v1` automatically picks up new features and fixes without any change on your side.\n\nThe floating tag is updated automatically via a GitHub Actions workflow on every new release.\n\nIf you need reproducibility, pin to a specific version:\n\n```yaml\n- uses: Richonn/ShieldCI@v1.1.1\n```\n\n## Image signing with Cosign\n\nWhen a `Dockerfile` is detected, ShieldCI generates a Docker workflow that automatically signs the built image using [Cosign](https://github.com/sigstore/cosign) in keyless mode via GitHub Actions OIDC.\n\nNo keys or secrets to manage — the signature is tied to the GitHub Actions identity and stored in the public [Rekor](https://rekor.sigstore.dev) transparency log.\n\nThe image is pushed to `ghcr.io/\u003cowner\u003e/\u003crepo\u003e:\u003csha\u003e` and signed immediately after the build. Anyone can verify the signature with:\n\n```sh\ncosign verify ghcr.io/\u003cowner\u003e/\u003crepo\u003e:\u003csha\u003e \\\n  --certificate-identity-regexp=\"https://github.com/\u003cowner\u003e/\u003crepo\u003e\" \\\n  --certificate-oidc-issuer=\"https://token.actions.githubusercontent.com\"\n```\n\n## SBOM generation\n\nShieldCI generates two SBOM workflows via [Syft](https://github.com/anchore/syft):\n\n- **`sbom.yml`** — always generated, analyses the repository source and dependencies\n- **`sbom-docker.yml`** — generated when a `Dockerfile` is detected, builds the image and generates a SBOM from it\n\nSBOM files are uploaded as artifacts and available from the Actions run summary.\n\n## Monorepo support\n\nShieldCI automatically detects monorepos by scanning subdirectories up to a configurable depth. A separate workflow is generated per detected component, named `\u003ccomponent\u003e-ci.yml`, `\u003ccomponent\u003e-lint.yml`, etc.\n\n**Supported monorepo layouts:**\n\n```\nmy-monorepo/\n├── backend-services/\n│   ├── user-service/       # Go component → user-service-ci.yml\n│   └── media-service/      # Rust component → media-service-ci.yml\n└── tools/\n    └── inspector/          # Python component → inspector-ci.yml\n```\n\nThe following directories are automatically excluded from scanning: `node_modules`, `vendor`, `dist`, `build`, `target`, `docs`, `scripts`, and others.\n\nAdjust scan depth with `max-depth` (default: `3`):\n\n```yaml\n- uses: Richonn/ShieldCI@v1\n  with:\n    github-token: ${{ secrets.GH_TOKEN }}\n    max-depth: '4'\n```\n\n## Roadmap\n\n- [x] Rust support\n- [x] `dry-run` mode\n- [x] Pinned action SHAs in generated workflows\n- [x] Semgrep custom rules support\n- [x] SBOM via Syft\n- [x] Monorepo support\n- [x] Image signing with Cosign (keyless via OIDC)\n- [x] SLSA provenance via `slsa-github-generator` (level 3)\n- [x] Build caching in generated workflows (Go modules, pip/poetry, npm/yarn, maven/gradle)\n- [x] Multi-version matrix testing in generated workflows (Go, Rust, Java, Node, Python)\n- [x] OpenSSF Scorecard integration\n- [x] Concurrency groups in generated workflows (`cancel-in-progress`)\n- [x] Go fuzz tests (`detect`, `generate`)\n- [x] Workflow permission hardening (least privilege, job-level write scopes)\n- [x] Dockerfile base image SHA pinning\n- [x] Security policy (`SECURITY.md`)\n- [x] Multi-arch Docker builds (`linux/amd64`, `linux/arm64`)\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichonn%2Fshieldci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frichonn%2Fshieldci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichonn%2Fshieldci/lists"}