github

v0.1.9 collector

Collects GitHub organization security posture metrics

Install

epack install collector github

Adds to epack.yaml, resolves dependencies, downloads binary.

Usage

Run all configured collectors and build a pack:

epack collect

Runs all collectors in epack.yaml and outputs an evidence pack.

Configuration

Or add manually to epack.yaml:

collectors:
  github:
    source: https://github.com/locktivity/epack-collector-github

Then run epack install to lock and sync.

GitHub Posture Collector

The GitHub Posture Collector gathers security posture metrics from your GitHub organization.

What It Collects

This collector queries your GitHub organization and aggregates security posture coverage metrics:

  • Scope: The include/exclude patterns and repositories coverage percentage
  • Posture Summary: High-level coverage percentages for branch protection and security features
  • Access Control: Organization-level 2FA enforcement status
  • Branch Protection Rules: Per-rule coverage percentages (PR requirements, reviews, status checks, signed commits, admin enforcement)
  • Security Features: Per-feature coverage percentages (vulnerability alerts, code scanning, secret scanning, push protection, Dependabot)

All metrics are expressed as coverage percentages (0-100) rather than raw counts, making it easy to track and compare security posture over time. The scope is included in the output so receivers can understand exactly what was covered.

Use Cases

  • Third-party risk assessments: Provide evidence of your GitHub security posture to customers and auditors
  • Continuous assurance: Automate evidence collection for ongoing compliance monitoring
  • Security benchmarking: Track security posture improvements over time

How It Works

  1. The collector authenticates to GitHub using either:
    • a GitHub App private key flow, or
    • a GITHUB_TOKEN supplied by the runtime
  2. It queries the GitHub GraphQL API to fetch repository metadata and branch protection rules
  3. It queries the GitHub REST API to fetch security settings (secret scanning, push protection, Dependabot)
  4. Metrics are aggregated into coverage percentages
  5. The output is wrapped in the epack collector protocol envelope and written to stdout

Authentication

GitHub App authentication is recommended for manual setups:
- Not tied to a user account
- Better audit logging
- Higher rate limits
- Recommended by GitHub for org-level integrations

When the collector runs under a managed or brokered runtime, GITHUB_TOKEN may be a short-lived installation token instead of a user PAT.

See Configuration for setup instructions.

Configuration

Authentication

The collector supports two authentication methods. GitHub App is recommended for manual setups because it provides better security and audit capabilities. For managed or brokered runtimes, the collector can also consume a short-lived GITHUB_TOKEN.

GitHub App (Recommended)

GitHub Apps provide the best security posture:
- Not tied to a user account
- Better audit logging
- Higher rate limits
- Recommended by GitHub for org-level integrations

collectors:
  github:
    source: locktivity/epack-collector-github@^0.1
    config:
      organization: myorg
      app_id: 123456
      installation_id: 78901234
    secrets:
      - GITHUB_APP_PRIVATE_KEY

Creating a GitHub App

  1. Go to your organization's Settings > Developer settings > GitHub Apps > New GitHub App
  2. Set the following:
    • GitHub App name: epack-posture-collector (or your preferred name)
    • Homepage URL: Your organization's URL
    • Webhook: Uncheck "Active" (not needed)
  3. Set Permissions:
    • Repository permissions:
      • Administration: Read-only
      • Contents: Read-only
      • Metadata: Read-only
    • Organization permissions:
      • Administration: Read-only
      • Members: Read-only
  4. Set Where can this GitHub App be installed? to "Only on this account"
  5. Click Create GitHub App
  6. Note the App ID from the app settings page
  7. Scroll down and click Generate a private key - save the .pem file
  8. Click Install App and install it on your organization
  9. Note the Installation ID from the URL (e.g., https://github.com/organizations/myorg/settings/installations/78901234)

Providing the Private Key

Set the GITHUB_APP_PRIVATE_KEY secret to the contents of the .pem file:

export GITHUB_APP_PRIVATE_KEY="$(cat /path/to/private-key.pem)"
epack collect

GITHUB_TOKEN (Brokered Token or PAT)

The collector accepts a GITHUB_TOKEN for GitHub API access. In practice this can be:
- a short-lived GitHub installation token injected by a trusted runtime or broker
- a classic PAT for manual setups

Classic PATs still work, but they are not recommended when a short-lived or GitHub App-based flow is available.

collectors:
  github:
    source: locktivity/epack-collector-github@^0.1
    config:
      organization: myorg
    secrets:
      - GITHUB_TOKEN

Create a classic token with these scopes:
- repo - Repository access (or public_repo for public repos only)
- admin:org - (Optional) Read organization settings for 2FA status

Note: Without admin:org, the collector will still work but two_factor_required will be null (unknown) in the output.

Configuration Options

Field Type Required Default Description
organization string Yes - GitHub organization name
app_id int No* - GitHub App ID
installation_id int No* - GitHub App installation ID
include_patterns []string No ["*"] Glob patterns for repositories to include
exclude_patterns []string No [] Glob patterns for repositories to exclude

*Required if using GitHub App authentication

Secrets

Name Required Description
GITHUB_APP_PRIVATE_KEY For App auth GitHub App private key (PEM format)
GITHUB_TOKEN For token auth GitHub API token (short-lived installation token or classic PAT)

Pattern Syntax

The include and exclude patterns use glob syntax:

  • * matches any characters
  • ? matches a single character
  • Exclude patterns take precedence over include patterns

Examples

Archived repositories are skipped automatically and are not assessed for security settings or code scanning status.

# Include all non-archived repos, but exclude deprecated repos by name
include_patterns: ["*"]
exclude_patterns: ["*-deprecated"]

# Only include production repos
include_patterns: ["prod-*", "platform-*"]
exclude_patterns: []

# Exclude test and experimental repos
include_patterns: ["*"]
exclude_patterns: ["test-*", "experiment-*", "sandbox-*"]

Required GitHub App Permissions

For GitHub App authentication, the app needs:

Repository permissions:
- Administration: Read-only (for security settings and security_and_analysis field)
- Contents: Read-only (for repository metadata)
- Metadata: Read-only (always required)
- Code scanning alerts: Read-only (for code scanning status)
- Secret scanning alerts: Read-only (for secret scanning status)
- Dependabot alerts: Read-only (for dependabot status)

Organization permissions:
- Administration: Read-only (for 2FA settings)
- Members: Read-only (for organization membership)

Note on Security Features

Secret scanning and push protection metrics require that these features are enabled for your organization. Some features may require GitHub Advanced Security for private repositories.

Troubleshooting

"organization is required"

The organization field must be set in your config:

config:
  organization: myorg  # Required

"authentication required"

You must provide either:
- GITHUB_TOKEN secret (for brokered token or PAT auth), or
- app_id in config + GITHUB_APP_PRIVATE_KEY secret (for App auth)

"401 Unauthorized"

Your credentials are invalid or expired. For GitHub Apps, ensure the private key matches the app and the app is installed on the organization.

"403 Forbidden"

This can occur for two reasons:

  1. Missing permissions: The authenticated user or app doesn't have the required permissions. See Required GitHub App Permissions above.

  2. GitHub Advanced Security not enabled: For code scanning checks, GitHub returns 403 if Advanced Security is not enabled on the repository. The error message will show: "Advanced Security must be enabled for this repository to use code scanning."

Examples

Basic Usage

Using GitHub App (Recommended)

stream: myorg/github-posture

collectors:
  github:
    source: locktivity/epack-collector-github@^0.1
    config:
      organization: myorg
      app_id: 123456
      installation_id: 78901234
    secrets:
      - GITHUB_APP_PRIVATE_KEY

Then run:

export GITHUB_APP_PRIVATE_KEY="$(cat /path/to/private-key.pem)"
epack collect

See Configuration for GitHub App setup instructions.

Using GITHUB_TOKEN (Brokered Token or PAT)

stream: myorg/github-posture

collectors:
  github:
    source: locktivity/epack-collector-github@^0.1
    config:
      organization: myorg
    secrets:
      - GITHUB_TOKEN

Then run:

export GITHUB_TOKEN=ghp_xxxx
epack collect

GITHUB_TOKEN can be a short-lived installation token injected by the runtime, or a classic PAT for manual use.

Filtering Repositories

Exclude Archived Repositories

collectors:
  github:
    source: locktivity/epack-collector-github@^0.1
    config:
      organization: myorg
      app_id: 123456
      installation_id: 78901234
      exclude_patterns:
        - "*-archived"
        - "*-deprecated"
        - "*-old"
    secrets:
      - GITHUB_APP_PRIVATE_KEY

Only Production Repositories

collectors:
  github:
    source: locktivity/epack-collector-github@^0.1
    config:
      organization: myorg
      app_id: 123456
      installation_id: 78901234
      include_patterns:
        - "prod-*"
        - "platform-*"
        - "service-*"
    secrets:
      - GITHUB_APP_PRIVATE_KEY

Sample Output

{
  "protocol_version": 1,
  "data": {
    "schema_version": "1.0.0",
    "collected_at": "2026-02-23T14:30:00Z",
    "organization": "myorg",
    "scope": {
      "include_patterns": ["*"],
      "exclude_patterns": ["*-archived", "test-*"],
      "repositories_coverage": 79
    },
    "posture": {
      "branch_protection_coverage": 93,
      "security_features_coverage": 72
    },
    "access_control": {
      "two_factor_required": true
    },
    "branch_protection_rules": {
      "pull_request_required": 93,
      "approving_reviews": 89,
      "dismiss_stale_reviews": 84,
      "code_owner_reviews": 33,
      "status_checks": 87,
      "signed_commits": 49,
      "admin_enforcement": 78
    },
    "security_features": {
      "vulnerability_alerts": 95,
      "code_scanning": 78,
      "secret_scanning": 82,
      "secret_scanning_push_protection": 60,
      "dependabot_security_updates": 51
    }
  }
}

All coverage values are percentages (0-100). The security_features_coverage is the average of all five security features.

The scope field records the filters applied during collection. The repositories_coverage percentage indicates what proportion of the organization's repositories were assessed (e.g., 79% means 79% of repos matched the include/exclude filters).

The access_control section provides organization-level security posture:
- two_factor_required: Whether 2FA is enforced for all org members

Note: two_factor_required may be null if the token lacks sufficient permissions (requires admin:org scope for PATs, or Organization Administration permission for GitHub Apps).

SSO Limitation: SSO status is not included in the output because GitHub does not provide a reliable API to detect SAML SSO configuration. The GraphQL samlIdentityProvider field has a known permission bug with GitHub Apps (discussion), and no REST API endpoint returns SSO status.

CI/CD Integration

GitHub Actions (with GitHub App)

name: Collect Evidence

on:
  schedule:
    - cron: "0 0 * * 1"  # Weekly on Monday
  workflow_dispatch:

jobs:
  collect:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install epack
        run: |
          curl -sSL https://github.com/locktivity/epack/releases/latest/download/epack-linux-amd64 -o epack
          chmod +x epack
          sudo mv epack /usr/local/bin/

      - name: Collect evidence
        run: epack collect --frozen
        env:
          GITHUB_APP_PRIVATE_KEY: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}

      - name: Upload pack
        uses: actions/upload-artifact@v4
        with:
          name: evidence-pack
          path: "*.pack"

Store the GitHub App private key as a repository secret named GITHUB_APP_PRIVATE_KEY.

v0.1.9 Latest
2026-04-08

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.8...v0.1.9

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.8
2026-04-03

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.7...v0.1.8

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.7
2026-04-03

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.6...v0.1.7

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.6
2026-03-18

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.5...v0.1.6

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.5
2026-03-17

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.4...v0.1.5

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.4
2026-03-02

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.3...v0.1.4

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.3
2026-02-27

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.2...v0.1.3

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.1
2026-02-27

**Full Changelog**: https://github.com/locktivity/epack-collector-github/compare/v0.1.0...v0.1.1

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64
v0.1.0
2026-02-26

**Full Changelog**: https://github.com/locktivity/epack-collector-github/commits/v0.1.0

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64

Details

Publisher
locktivity
Latest
v0.1.9
Protocol
v1

Platforms

darwin/amd64 darwin/arm64 linux/amd64 linux/arm64

Links