Skip to content
Tech Talk Tavern/
Menu

post · March 1, 2025 · 2 min read

Designing Reusable DevSecOps Workflows in GitHub Actions

By Saleh Elnagar

GitHub#DevSecOps
Share:LinkedInX
Git Workflows illustration for Designing Reusable DevSecOps Workflows in GitHub Actions

Reusable workflows enable security platform teams to codify guardrails once and roll them out to every repository. This article walks through building a multi-stage pipeline where security controls move as code, not documentation.

Architectural Pattern

Producer Repo

Hosts versioned reusable workflows (.github/workflows/*.yml) that encapsulate validation, testing, and deployment steps with security baked in.

Consumer Repos

Call the reusable workflows via uses: org/security-workflows/.github/workflows/sast.yml@v2. Inputs/outputs expose just enough flexibility for app teams.

Central Policy

Organization rules enforce pinned SHAs, protected branches, and required checks so no team can bypass the shared controls.

Example Reusable Workflow

The following workflow performs lint, SAST, and container scanning stages. It runs on hardened, ephemeral runners using OIDC to access cloud registries.

# .github/workflows/container-secure.yml
defaults:
  run:
    shell: bash

on:
  workflow_call:
    inputs:
      language:
        required: true
        type: string
      image-name:
        required: true
        type: string
    secrets:
      aws-role-arn:
        required: true

jobs:
  sast:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        if: inputs.language == 'node'
      - uses: actions/setup-python@v5
        if: inputs.language == 'python'
      - name: Run Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          auditOn: push

  container-build:
    needs: sast
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.aws-role-arn }}
          aws-region: us-east-1
      - name: Login to ECR
        uses: aws-actions/amazon-ecr-login@v2
      - name: Build and Push Image
        run: |
          docker build -t ${{ inputs.image-name }} .
          docker tag ${{ inputs.image-name }} $ECR_REGISTRY/${{ inputs.image-name }}:${{ github.sha }}
          docker push $ECR_REGISTRY/${{ inputs.image-name }}:${{ github.sha }}

  container-scan:
    needs: container-build
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Invoke Trivy Scanner
        uses: aquasecurity/trivy-action@0.24.0
        with:
          image-ref: ${{ needs.container-build.outputs.image-digest }}
          format: 'table'
          exit-code: '1'
          vuln-type: 'os,library'

Versioning and Change Control

Tag each workflow release and enforce @v2-style references. Combine with CODEOWNERS so security engineering approves every change. Consumers can adopt fixes via Dependabot or Renovate automations.

Scaling Observability

Pipe workflow_job and workflow_run events to a SIEM or data warehouse. This enables:

  • Tracking adoption (% of repos consuming reusable workflows).
  • Measuring policy drift (runs without required OIDC permissions).
  • Alerting on suspicious behavior (workflow dispatches outside change window).

Takeaways

Reusable workflows turn DevSecOps from a checklist into a product. Build them with strong defaults, a clear contract, and continuous feedback loops so they evolve alongside your threat model.

Quick AI Summary

Reusable workflows enable security platform teams to codify guardrails once and roll them out to every repository. This article walks through building a multi-stage pipeline where security controls move as code, not documentation.

Original article body above remains unchanged.

Continue Reading

Related Posts

Security Engineering illustration for Automating SAST with GitHub Actions and CodeQL
February 2, 20252 min read

Why CodeQL Belongs in Your DevSecOps Pipeline Static analysis is most effective when it runs where developers work. GitHub Actions provides native integration with CodeQL, enabling you to: Reference Workflow The workflow below scans supported languages on a nightly cadence and for every pull request targeting main. It stores the CodeQL database as an artifact for […]

#DevSecOps
Azure Architecture illustration for Azure Terraform Conventions: How to Design & Enforce a Real-World Naming Strategy
June 7, 202512 min read

Repository: https://github.com/SalehElnagar/azure-terraform-conventions This article walks through how to think about Azure naming conventions and how to turn those decisions into code using the azure-terraform-conventions GitHub repository. That repo contains: The goal is not “just use whatever the repo does”. The goal is: capture your organization’s naming decisions once, codify them with this library, and then […]

#Azure#DevSecOps#IaC
Terraform Infrastructure illustration for Building a Production-Ready Azure VM Terraform Module
September 27, 202521 min read

When I sit down to craft a Terraform module, I ask myself how future me—and the teams inheriting my code—will reason about every decision. I remind myself to start with clarity, keep security opinionated but flexible, and prove the workflow end to end before anyone else runs terraform apply. I literally keep a checklist on […]

#Azure#DevSecOps#IaC

Get New Playbooks Weekly

Join the newsletter for practical Azure, Terraform, and DevSecOps guides. One actionable email per week.

Comments

Enable comments by setting NEXT_PUBLIC_GISCUS_* environment variables.