247 Strangers Have Root Access to Your Production

247 Strangers Have Root Access to Your Production

Your organization probably has a detailed vendor approval process. Procurement forms. Security questionnaires. Legal reviews. Contract negotiations that span months.

And then your developers add npm install some-random-package to the build script, pulling in 247 transitive dependencies from strangers on the internet, and nobody blinks.

That’s the supply chain security paradox. ISO/IEC 27001 Control A.15 demands rigorous supplier relationship management—but most organizations treat their dependency tree as if it doesn’t exist. The SolarWinds breach, the Log4Shell vulnerability, and countless package hijacking incidents prove this oversight isn’t theoretical. Your dependencies are your suppliers, and they’re the ones with root access.

GitHub Dependabot, dependency review actions, and Software Bill of Materials (SBOM) generation aren’t trendy DevOps tools. They’re the technical implementation of what ISO 27001 actually requires in A.15.1.1 (Information security policy for supplier relationships), A.15.1.3 (Information and communication technology supply chain), and A.15.2.1 (Monitoring and review of supplier services). Here’s how to implement them properly—and why treating this as optional is compliance theater.

The Fatal Approach: Trust Without Verification

Let me show you what most organizations actually do when it comes to dependency management. This is disturbingly common:

# .github/workflows/ci.yml - The "we have CI at home" version
name: CI

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'
      
      - name: Restore dependencies
        run: dotnet restore
      
      - name: Build
        run: dotnet build --no-restore
      
      - name: Test
        run: dotnet test --no-build

Looks reasonable? It’s not. Here’s what’s happening behind the scenes:

No dependency vulnerability scanning. The pipeline blindly restores whatever’s in your lock file. If a package has a critical CVE published yesterday, this build will still succeed. The automated security update emails from GitHub? Developers ignore those. They’re busy shipping features.

No review of new dependencies. Pull requests that add 15 new packages go through the same review process as typo fixes. Reviewers check the code logic but ignore that the developer just gave a package maintainer they’ve never heard of the ability to exfiltrate environment variables during the build.

No Software Bill of Materials. When you need to answer “do we use this vulnerable component?” you grep through lock files manually and hope transitive dependencies aren’t hiding something. Auditors ask for your supplier list, and you hand them a procurement spreadsheet that doesn’t mention the 847 npm packages running in production.

Automatic merging without context. Some teams enable Dependabot but configure it to auto-merge. Congratulations, you’ve automated the process of giving strangers write access to production with zero review:

# .github/dependabot.yml - The "what could go wrong?" configuration
version: 2
updates:
  - package-ecosystem: "nuget"
    directory: "/"
    schedule:
      interval: "weekly"
    # Auto-merge enabled elsewhere, no version constraints, no review required

No package source verification. Your nuget.config allows any source. Developers occasionally switch to alternative feeds “temporarily” to test something. Those sources stick around. Nobody verifies package signatures because .NET doesn’t enforce it by default.

No incident response integration. Your IR plan has sections for ransomware and DDoS attacks but nothing for supply chain compromises. When a widely-used package is hijacked, you spend three days figuring out if you’re affected instead of checking an SBOM and responding in minutes.

This isn’t negligence—it’s the default state. And it violates every principle ISO 27001 A.15 tries to enforce.

ISO 27001 A.15: What the Standard Actually Requires

Let’s map the standard to reality. ISO 27001’s supplier relationship controls aren’t written with NuGet in mind, but the requirements are unambiguous:

A.15.1.1: Information Security Policy for Supplier Relationships

“Information security requirements for mitigating the risks associated with supplier’s access to the organization’s assets shall be agreed with the supplier and documented.”

Translation: You need a defined approval process for dependencies. Adding a new package isn’t just a developer decision—it’s introducing a new supplier relationship. That means:

  • Security review before introduction: New dependencies require explicit approval with documented risk assessment.
  • Approved sources only: Package feeds must be controlled and validated.
  • Contractual clarity: Even open-source dependencies have terms (licenses) that need review.

In .NET terms, this means dependency review workflows that block unapproved packages and enforce source restrictions.

A.15.1.3: Information and Communication Technology Supply Chain

“Agreements with suppliers shall include requirements to address the information security risks associated with information and communications technology services and product supply chain.”

Translation: You need to know what’s in your supply chain. Not just direct dependencies—transitive ones too. And you need mechanisms to respond when components are compromised.

This is where SBOMs become mandatory, not nice-to-have. The standard explicitly requires supply chain visibility.

A.15.2.1: Monitoring and Review of Supplier Services

“Organizations shall regularly monitor, review and audit supplier service delivery.”

Translation: It’s not enough to approve dependencies once. You need continuous monitoring for vulnerabilities, license changes, and maintenance status.

Dependabot security updates and dependency freshness checks aren’t automation luxuries—they’re compliance requirements.

The Correct Approach: Defense in Depth for Dependencies

Here’s how to implement supply chain security that actually satisfies ISO 27001 controls and prevents breaches. This isn’t theoretical—it’s based on configurations running in production environments that pass ISO audits.

Step 1: Configure Dependabot for Security Updates

Dependabot is GitHub’s built-in tool for monitoring dependencies. Configure it properly:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "nuget"
    directory: "/"
    schedule:
      interval: "daily"
    open-pull-requests-limit: 10
    target-branch: "main"
    groups:
      production-dependencies:
        patterns: ["*"]
        update-types: ["minor", "patch"]
    labels: ["dependencies", "security"]
    versioning-strategy: increase

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    labels: ["dependencies", "github-actions"]

Why this works: Daily security scans ensure vulnerabilities are detected within 24 hours. Grouping minor updates reduces notification fatigue. Separate GitHub Actions updates prevent action supply chain attacks (yes, those happen too).

Step 2: Implement Dependency Review Action

Block PRs that introduce known vulnerabilities before they merge:

# .github/workflows/dependency-review.yml
name: Dependency Review

on:
  pull_request:
    branches: [main, develop]

permissions:
  contents: read
  pull-requests: write

jobs:
  dependency-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/dependency-review-action@v4
        with:
          fail-on-severity: moderate
          deny-licenses: GPL-2.0, GPL-3.0, AGPL-3.0
          warn-on-stale-maintainers: true
          comment-summary-in-pr: always

Why this matters: This implements A.15.1.1’s requirement for security assessment before supplier introduction. Developers get instant feedback in the PR. Security teams have audit trails of what was blocked and why.

Step 3: Generate and Publish SBOMs

Software Bill of Materials makes your dependency tree visible and queryable:

# .github/workflows/sbom.yml
name: Generate SBOM

on:
  push:
    branches: [main]
  release:
    types: [published]

permissions:
  contents: write
  id-token: write

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'
      - run: dotnet restore
      - name: Generate SBOM
        run: |
          dotnet tool install --global Microsoft.Sbom.DotNetTool
          sbom-tool generate -b ./bin/sbom -bc . \
            -pn "YourProject" -pv "1.0.0" -ps "YourOrganization"
      - uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: ./bin/sbom/_manifest/spdx_2.2/manifest.spdx.json
          retention-days: 90

Why this is critical: When CVE-2024-XXXXX drops, you query your SBOM inventory instead of manually searching codebases. Attestation provides cryptographic proof the SBOM hasn’t been tampered with. This satisfies A.15.1.3’s supply chain visibility requirement.

Step 4: Package Approval Workflow

Require security team approval for new dependencies:

# .github/workflows/package-approval.yml
name: Package Approval

on:
  pull_request:
    paths:
      - '**/packages.lock.json'
      - '**/*.csproj'
      - '**/package.json'

permissions:
  contents: read
  pull-requests: write

jobs:
  detect-new-packages:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Detect new dependencies
        id: detect
        run: |
          git diff origin/${{ github.base_ref }}...HEAD --name-only | \
            grep -E 'lock\.json' > changed.txt || true
          [ -s changed.txt ] && echo "new_deps=true" >> $GITHUB_OUTPUT
      - name: Request security review
        if: steps.detect.outputs.new_deps == 'true'
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.pulls.requestReviewers({
              ...context.repo, pull_number: context.issue.number,
              team_reviewers: ['security-team']
            });

Why this works: A.15.1.1 requires documented supplier approval. This workflow creates an audit trail: who approved what dependency, when, and based on what criteria. Compliance evidence that actually exists when auditors ask.

Step 5: Continuous Dependency Health Monitoring

Monitor dependency freshness and vulnerability status:

# .github/workflows/dependency-health.yml
name: Dependency Health Check

on:
  schedule:
    - cron: '0 6 * * 1'
  workflow_dispatch:

permissions:
  contents: read
  issues: write

jobs:
  health-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '9.0.x'
      - name: Check vulnerabilities
        id: vuln
        run: |
          dotnet list package --vulnerable --include-transitive > vuln.txt
          grep -q ">" vuln.txt && echo "found=true" >> $GITHUB_OUTPUT || true
      - name: Create issue
        if: steps.vuln.outputs.found == 'true'
        uses: actions/github-script@v7
        with:
          script: |
            const vuln = require('fs').readFileSync('vuln.txt', 'utf8');
            github.rest.issues.create({
              ...context.repo,
              title: 'Vulnerable Dependencies Detected',
              body: '```\n' + vuln + '\n```\nSLA: 7 days for critical.',
              labels: ['security', 'dependencies']
            });

Why this is essential: A.15.2.1 requires ongoing monitoring of supplier services. This workflow provides weekly health checks, automatic issue creation for vulnerabilities, and documented SLAs for remediation.

Mapping Implementation to ISO Controls

Here’s the explicit compliance mapping auditors need:

ISO 27001 ControlImplementationEvidence
A.15.1.1 - Security policy for suppliersPackage approval workflow requiring security reviewGitHub PR approval logs, review checklists, team assignments
A.15.1.3 - ICT supply chain securitySBOM generation, dependency review action blocking vulnerabilitiesSBOM artifacts, dependency-review workflow logs, blocked PR records
A.15.2.1 - Monitoring supplier servicesDependabot security updates, weekly health checks, vulnerability SLA trackingDependabot PR history, health check workflow runs, issue resolution times

Your ISMS documentation should reference these workflows as technical controls. Include workflow YAML files as appendices. Point auditors to GitHub Actions logs as evidence of continuous monitoring.

The Hard Parts Nobody Talks About

Implementing this correctly requires addressing several organizational challenges:

Alert fatigue is real. Dependabot can generate dozens of PRs weekly. Teams that don’t group updates or prioritize security-only PRs end up ignoring all of them. Configure update grouping. Separate security updates (urgent) from version updates (scheduled).

Breaking changes break builds. Major version updates aren’t just security patches—they introduce breaking changes. Your approval workflow should distinguish between patch updates (can be automated) and major updates (require testing). Don’t auto-merge everything blindly.

False positives happen. Not every CVE applies to your usage pattern. Vulnerability scanners flag issues in dependencies you don’t use. Document exceptions explicitly with justification. Auditors understand risk acceptance—they don’t understand ignored alerts.

License compliance isn’t just security. Pulling in GPL dependencies into proprietary software creates legal risk. The dependency review action’s license blocking prevents this, but somebody needs to maintain the deny-list based on your organization’s license policy.

SBOMs need governance. Generating an SBOM is the easy part. The hard part is: who reviews it? Who’s responsible when a component shows up in a breach announcement? Your incident response plan needs SBOM query procedures documented.

When Compliance Meets Reality

ISO 27001 certification doesn’t require specific tools—it requires demonstrable controls. GitHub Dependabot isn’t mandatory. But you need something that achieves the same outcomes: documented approval processes, supply chain visibility, continuous monitoring, and vulnerability response SLAs.

The alternative—manual dependency reviews and spreadsheet tracking—technically satisfies the standard but fails in practice. I’ve seen organizations attempt manual SBOM maintenance. It becomes outdated within a week and worthless for incident response.

Automation isn’t laziness. It’s the only practical way to implement supplier relationship controls at the scale of modern software dependencies. A typical .NET microservice has 200+ transitive dependencies. Managing those relationships manually is compliance theater, not security.

Practical Implementation Timeline

If you’re starting from zero, here’s a realistic rollout:

Week 1: Enable Dependabot for security updates only. Don’t auto-merge anything yet. Just observe what gets flagged.

Week 2: Implement dependency review action on new PRs. Set fail-on-severity: high initially to avoid blocking everything immediately.

Week 3: Configure SBOM generation for main branch builds. Start collecting SBOMs but don’t enforce anything yet.

Week 4: Add package approval workflow. Route new dependencies to security team review. Document approval criteria.

Week 5: Enable weekly dependency health checks. Create issues for vulnerabilities automatically but give teams time to establish remediation workflows.

Week 6: Lower dependency review threshold to moderate. At this point, you should have enough data to tune false positive handling.

Don’t try to implement everything simultaneously. Gradual rollout lets teams adapt and provides time to tune configurations based on real usage patterns.

The Bottom Line

ISO 27001 Control A.15 treats supplier relationships as security-critical. Your dependency tree is a supplier relationship. Hundreds of them, actually.

GitHub Dependabot, dependency review actions, and SBOM generation aren’t optional DevOps add-ons. They’re the technical implementation of what the standard requires: documented approval processes (A.15.1.1), supply chain visibility (A.15.1.3), and continuous monitoring (A.15.2.1).

Organizations that ignore supply chain security aren’t just risking breaches—they’re in violation of their own ISMS requirements. The next time your auditor asks about supplier management controls, showing them your procurement process isn’t enough. They need to see how you manage the suppliers running in production: your dependencies.

The fatal approach treats dependencies as an afterthought. The correct approach treats them as the critical third-party relationships they actually are—with approval workflows, continuous monitoring, vulnerability SLAs, and documented evidence that survives audit scrutiny.

Your dependency manager is either your weakest link or your best security control. The difference is whether you implement it deliberately or ignore it hopefully.

Comments

VG Wort