Tutorial 25

August 4, 2026 · View on GitHub

A practical guide to hardening agent deployments using the Agent Governance Toolkit's built-in security tooling. This tutorial covers secret scanning, dependency review, static analysis, fuzz testing, supply chain security, and branch protection — everything you need to secure a production agent system.

Scope: CI/CD security, dependency management, code analysis, fuzzing Frameworks: Gitleaks, Dependabot, CodeQL, ClusterFuzzLite, OpenSSF Scorecard Audience: Platform engineers and security teams deploying governed agents


What You'll Learn

SectionTopic
Security OverviewDefence-in-depth for agent systems
Secret ScanningPrevent secrets from entering the repository
Dependency ReviewAutomated CVE scanning across 13 ecosystems
CodeQL AnalysisStatic analysis for Python and TypeScript
Fuzz Testing7 fuzz targets for parser and policy code
OpenSSF ScorecardAutomated security scoring
SBOM GenerationSPDX and CycloneDX software bills of materials
Branch ProtectionEnforcing CI gates
RecommendationsProduction deployment checklist

Prerequisites


Security Overview

The Agent Governance Toolkit uses a defence-in-depth approach with multiple overlapping security layers:

  ┌─────────────────────────────────────────────────────┐
  │                   Branch Protection                 │
  │  ┌───────────────────────────────────────────────┐  │
  │  │              CI Security Gates                │  │
  │  │  ┌─────────────────────────────────────────┐  │  │
  │  │  │         Static Analysis (CodeQL)        │  │  │
  │  │  │  ┌───────────────────────────────────┐  │  │  │
  │  │  │  │     Dependency Review (Dependabot) │  │  │  │
  │  │  │  │  ┌─────────────────────────────┐  │  │  │  │
  │  │  │  │  │  Secret Scanning (Gitleaks) │  │  │  │  │
  │  │  │  │  │  ┌───────────────────────┐  │  │  │  │  │
  │  │  │  │  │  │   Fuzz Testing        │  │  │  │  │  │
  │  │  │  │  │  └───────────────────────┘  │  │  │  │  │
  │  │  │  │  └─────────────────────────────┘  │  │  │  │
  │  │  │  └───────────────────────────────────┘  │  │  │
  │  │  └─────────────────────────────────────────┘  │  │
  │  └───────────────────────────────────────────────┘  │
  └─────────────────────────────────────────────────────┘

Secret Scanning with Gitleaks

Gitleaks detects hardcoded secrets (API keys, tokens, passwords) before they reach the repository.

How It Works

The toolkit includes a Gitleaks configuration that scans every commit for:

  • API keys and tokens
  • Connection strings
  • Private keys
  • Cloud credentials (AWS, Azure, GCP)

CI Integration

# .github/workflows/gitleaks.yml
name: Gitleaks Secret Scan
on: [push, pull_request]

jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Local Pre-Commit Hook

Run Gitleaks locally before pushing:

# Install Gitleaks
brew install gitleaks  # macOS
# or download from https://github.com/gitleaks/gitleaks/releases

# Scan the repo
gitleaks detect --source . --verbose

# Scan only staged changes (pre-commit)
gitleaks protect --staged --verbose

Allowlisting False Positives

Use the .gitleaksignore file for known false positives:

# .gitleaksignore
# Test fixtures with fake credentials
tests/fixtures/mock-credentials.json

Best practice: Never add real secrets to the allowlist. Use environment variables or a secret manager instead.


Dependency Review and Dependabot

The toolkit uses Dependabot to monitor dependencies across 13 ecosystems:

EcosystemConfig FileScope
Python (pip)agent-governance-python/requirements/*.txtCore packages
Python (pip)*/requirements.txtPer-package
Node.js (npm)*/package.jsonTypeScript package
.NET (NuGet)*.csproj.NET package
Rust (Cargo)Cargo.tomlRust crate
Go (modules)go.modGo module
GitHub Actions.github/workflows/*.ymlCI/CD
DockerDockerfileContainer images

Dependabot Configuration

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: pip
    directory: "/"
    schedule:
      interval: weekly
    labels:
      - "dependencies"
      - "security"
    open-pull-requests-limit: 10

  - package-ecosystem: npm
    directory: "/agent-governance-typescript"
    schedule:
      interval: weekly

  - package-ecosystem: github-actions
    directory: "/"
    schedule:
      interval: weekly

Dependency Confusion Prevention

The toolkit includes a script that checks for dependency confusion attacks:

python scripts/check_dependency_confusion.py

This verifies that internal package names don't conflict with public registries.

Weekly Security Audit

A weekly workflow runs comprehensive dependency checks:

# Runs every Monday at 08:00 UTC
on:
  schedule:
    - cron: '0 8 * * 1'

It checks for:

  • Known CVEs in dependencies (via safety and pip-audit)
  • Dependency confusion risks
  • Weak cryptography usage (hashlib.md5, hashlib.sha1)
  • Unsafe pickle usage in non-test code

CodeQL Analysis

CodeQL performs deep static analysis to find security vulnerabilities in Python and TypeScript code.

Detected Vulnerability Classes

LanguageVulnerabilities
PythonSQL injection, command injection, path traversal, SSRF, XSS, unsafe deserialization
TypeScriptPrototype pollution, ReDoS, XSS, injection, insecure randomness

CI Integration

# .github/workflows/codeql.yml
name: CodeQL Analysis
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'  # weekly

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    strategy:
      matrix:
        language: [python, javascript]
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
      - uses: github/codeql-action/analyze@v3

Custom Queries

For agent-specific vulnerabilities, add custom CodeQL queries:

// queries/unsafe-tool-call.ql
import python

from Call call, Attribute attr
where
  attr = call.getFunc().(Attribute) and
  attr.getName() = "execute" and
  not exists(call.getArg(0).(StringLiteral))
select call, "Dynamic tool execution without static action name"

Fuzz Testing with ClusterFuzzLite

The toolkit includes 7 fuzz targets that test parser and policy code with randomised inputs.

Fuzz Targets

TargetComponentPurpose
fuzz_policy_parserPolicy engineMalformed YAML policy files
fuzz_mcp_scannerMCP securityMalicious tool descriptions
fuzz_prompt_injectionPrompt guardAdversarial prompt inputs
fuzz_trust_scoringTrust managerEdge-case trust calculations
fuzz_audit_chainAudit loggerHash-chain integrity under stress
fuzz_identityAgent identityMalformed DID and key inputs
fuzz_context_budgetBudget schedulerExtreme allocation patterns

Running Fuzz Tests Locally

# Install the fuzzer
pip install atheris  # Python fuzzer

# Run a specific target
python -m pytest tests/fuzz/test_fuzz_policy.py -x --timeout=60

CI Integration with ClusterFuzzLite

# .github/workflows/fuzz.yml
name: ClusterFuzzLite
on:
  pull_request:
    branches: [main]

jobs:
  fuzz:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: google/clusterfuzzlite/actions/build_fuzzers@v1
        with:
          language: python
      - uses: google/clusterfuzzlite/actions/run_fuzzers@v1
        with:
          fuzz-seconds: 300
          mode: code-change

OpenSSF Scorecard

The OpenSSF Scorecard automatically scores the repository's security posture across multiple dimensions.

Scorecard Checks

CheckWhat It Verifies
Binary-ArtifactsNo checked-in binaries
Branch-ProtectionRequired reviews, status checks
Code-ReviewAll changes go through review
Dangerous-WorkflowNo pull_request_target with secrets
Dependency-Update-ToolDependabot or Renovate configured
FuzzingFuzz testing in CI
LicenseOSI-approved licence present
MaintainedRecent commits and issue responses
Pinned-DependenciesActions pinned to SHA
SASTStatic analysis (CodeQL) enabled
Security-PolicySECURITY.md present
Signed-ReleasesRelease artifacts are signed
Token-PermissionsMinimal GitHub token permissions
VulnerabilitiesNo known CVEs in dependencies

CI Integration

# .github/workflows/scorecard.yml
name: OpenSSF Scorecard
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 6 * * 1'

jobs:
  scorecard:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: ossf/scorecard-action@v2
        with:
          results_file: scorecard-results.sarif
          publish_results: true
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: scorecard-results.sarif

SBOM Generation

Software Bills of Materials (SBOMs) list every component in the software supply chain. The toolkit generates both SPDX and CycloneDX formats.

Automated SBOM Workflow

# .github/workflows/sbom.yml (simplified)
name: SBOM Generation
on:
  release:
    types: [published]

jobs:
  sbom:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      id-token: write
      attestations: write
    steps:
      - uses: actions/checkout@v4

      # Generate SPDX SBOM
      - uses: anchore/sbom-action@v0
        with:
          output-file: sbom.spdx.json
          format: spdx-json

      # Generate CycloneDX SBOM
      - uses: anchore/sbom-action@v0
        with:
          output-file: sbom.cdx.json
          format: cyclonedx-json

      # Attest SBOM to the release
      - uses: actions/attest-sbom@v2
        with:
          subject-path: sbom.spdx.json

For more details on SBOM signing and verification, see Tutorial 26 — SBOM and Signing.


Branch Protection and Required Status Checks

SettingValueReason
Require pull request reviews1+ reviewersCode review before merge
Dismiss stale reviewsEnabledRe-review after changes
Require status checksEnabledCI must pass
Require branches up to dateEnabledNo stale merges
Require signed commitsRecommendedCommit integrity
Include administratorsEnabledNo bypass

Required Status Checks

Configure these as required status checks for pull requests:

✅ ci / lint
✅ ci / test-python
✅ ci / test-typescript
✅ ci / test-dotnet
✅ ci / security-scan
✅ gitleaks / scan
✅ codeql / analyze (python)
✅ codeql / analyze (javascript)

Setting Up via GitHub CLI

# Enable branch protection
gh api repos/{owner}/{repo}/branches/main/protection \
  --method PUT \
  --field required_pull_request_reviews='{"required_approving_review_count":1}' \
  --field required_status_checks='{"strict":true,"contexts":["ci / test-python","ci / security-scan"]}' \
  --field enforce_admins=true

Recommendations for Production

Deployment Checklist

  • Secrets: All secrets in a secret manager (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault) — never in environment variables or config files
  • Gitleaks: Running on every push and pull request
  • Dependabot: Configured for all package ecosystems
  • CodeQL: Running on push to main and weekly schedule
  • Fuzz testing: Running on pull requests
  • SBOM: Generated on every release
  • Branch protection: Enabled with required reviews and status checks
  • Scorecard: Running weekly with results published

Security Scanning Script

The toolkit includes a built-in security scanner for plugin directories:

# Scan all packages with minimum severity of "high"
python scripts/security_scan.py . \
  --exclude-tests \
  --min-severity high \
  --format text

The scanner checks for:

  • Secrets via detect-secrets
  • Python CVEs via pip-audit
  • Node vulnerabilities via npm audit
  • Dangerous code patterns via bandit
  • Risky code snippets in markdown skill files

Severity levels and blocking behaviour:

SeverityAction
criticalBlocks merge
highBlocks merge
mediumWarning only
lowInformational

Security Exemptions

For known false positives, create a .security-exemptions.json:

{
  "version": "1.0",
  "exemptions": [
    {
      "tool": "detect-secrets",
      "category": "High Entropy String",
      "file": "tests/fixtures/mock-data.json",
      "reason": "Test fixture with fake data",
      "approved_by": "security-team",
      "ticket": "SEC-1234",
      "temporary": true,
      "expires": "2025-12-31"
    }
  ]
}

Cross-Reference

ConceptTutorial
Audit trailsTutorial 04 — Audit & Compliance
MCP security scanningTutorial 07 — MCP Security Gateway
Compliance verificationTutorial 18 — Compliance Verification
SBOM and signingTutorial 26 — SBOM and Signing
MCP scan CLITutorial 27 — MCP Scan CLI
Plugin marketplace securityTutorial 10 — Plugin Marketplace
Shift-left governanceTutorial 45 — Shift-Left Governance

Next Steps

  • Run the Scorecard locally to see your current security posture:
    scorecard --repo=github.com/your-org/your-repo
    
  • Enable Dependabot for all package ecosystems in your repository
  • Add fuzz targets for any custom parser or policy code
  • Configure branch protection with the recommended settings above
  • Read Tutorial 26 (SBOM and Signing) for supply chain security