GI

github-archive

Query the immutable GitHub Archive to perform forensic security investigations and verify repository activity.

Install

mkdir -p .claude/skills/github-archive && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3846" && unzip -o skill.zip -d .claude/skills/github-archive && rm skill.zip

Installs to .claude/skills/github-archive

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Investigate GitHub security incidents using tamper-proof GitHub Archive data via BigQuery. Use when verifying repository activity claims, recovering deleted PRs/branches/tags/repos, attributing actions to actors, or reconstructing attack timelines. Provides immutable forensic evidence of all public GitHub events since 2011.
325 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Queries immutable historical GitHub events
  • Identifies specific actors for repository actions
  • Reconstructs time-series attack data
  • Recovers commit SHAs from deleted repositories
  • Verifies behavioral patterns across multiple repositories

How it works

Queries the public BigQuery dataset containing GitHub event logs that are immutable and historically preserved.

Inputs & outputs

You give it
Target GitHub URL and time range
You get back
Raw SQL query results or event history

When to use github-archive

  • Investigate GitHub security incidents
  • Verify repository activity history
  • Recover deleted PRs or branches
  • Reconstruct attack timelines
  • Detect supply chain reconnaissance

About this skill

GitHub Archive

Purpose: Query immutable GitHub event history via BigQuery to obtain tamper-proof forensic evidence for security investigations.

When to Use This Skill

  • Investigating security incidents involving GitHub repositories
  • Building threat actor attribution profiles
  • Verifying claims about repository activity (media reports, incident reports)
  • Reconstructing attack timelines with definitive timestamps
  • Analyzing automation system compromises
  • Detecting supply chain reconnaissance
  • Cross-repository behavioral analysis
  • Workflow execution verification (legitimate vs API abuse)
  • Pattern-based anomaly detection
  • Recovering deleted content: PRs, issues, branches, tags, entire repositories

GitHub Archive analysis should be your FIRST step in any GitHub-related security investigation. Start with the immutable record, then enrich with additional sources.

Core Principles

ALWAYS PREFER GitHub Archive as forensic evidence over:

  • Local git command outputs (git log, git show) - commits can be backdated/forged
  • Unverified claims from articles or reports - require independent confirmation
  • GitHub web interface screenshots - can be manipulated
  • Single-source evidence - always cross-verify

GitHub Archive IS your ground truth for:

  • Actor attribution (who performed actions)
  • Timeline reconstruction (when events occurred)
  • Event verification (what actually happened)
  • Pattern analysis (behavioral fingerprinting)
  • Cross-repository activity tracking
  • Deleted content recovery (issues, PRs, tags, commit references remain in archive)
  • Repository deletion forensics (commit SHAs persist even after repo deletion and history rewrites)

What Persists After Deletion

Deleted Issues & PRs:

  • Issue creation events (IssuesEvent) remain in archive
  • Issue comments (IssueCommentEvent) remain accessible
  • PR open/close/merge events (PullRequestEvent) persist
  • Forensic Value: Recover deleted evidence of social engineering, reconnaissance, or coordination

Deleted Tags & Branches:

  • CreateEvent records for tag/branch creation persist
  • DeleteEvent records document when deletion occurred
  • Forensic Value: Reconstruct attack staging infrastructure (e.g., malicious payload delivery tags)

Deleted Repositories:

  • All PushEvent records to the repository remain queryable
  • Commit SHAs are permanently recorded in archive
  • Fork relationships (ForkEvent) survive deletion
  • Forensic Value: Access commit metadata even after threat actor deletes evidence

Deleted User Accounts:

  • All activity events remain attributed to deleted username
  • Timeline reconstruction remains possible
  • Limitation: Direct code access lost, but commit SHAs can be searched elsewhere

Quick Start

Investigate if user opened PRs in June 2025:

from google.cloud import bigquery
from google.oauth2 import service_account

# Initialize client (see Setup section for credentials)
credentials = service_account.Credentials.from_service_account_file(
    'path/to/credentials.json',
    scopes=['https://www.googleapis.com/auth/bigquery']
)
client = bigquery.Client(credentials=credentials, project=credentials.project_id)

# Query for PR events
query = """
SELECT
    created_at,
    repo.name,
    JSON_EXTRACT_SCALAR(payload, '$.pull_request.number') as pr_number,
    JSON_EXTRACT_SCALAR(payload, '$.pull_request.title') as pr_title,
    JSON_EXTRACT_SCALAR(payload, '$.action') as action
FROM `githubarchive.day.202506*`
WHERE
    actor.login = 'suspected-actor'
    AND repo.name = 'target/repository'
    AND type = 'PullRequestEvent'
ORDER BY created_at
"""

results = client.query(query)
for row in results:
    print(f"{row.created_at}: PR #{row.pr_number} - {row.action}")
    print(f"  Title: {row.pr_title}")

Expected Output (if PR exists):

2025-06-15 14:23:11 UTC: PR #123 - opened
  Title: Add new feature
2025-06-20 09:45:22 UTC: PR #123 - closed
  Title: Add new feature

Interpretation:

  • No results → Claim disproven (no PR activity found)
  • Results found → Claim verified, proceed with detailed analysis

Setup

Prerequisites

  1. Google Cloud Project:

    • Login to Google Developer Console
    • Create a project and activate BigQuery API
    • Create a service account with BigQuery User role
    • Download JSON credentials file
  2. Install BigQuery Client:

pip install google-cloud-bigquery google-auth

Initialize Client

from google.cloud import bigquery
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file(
    'path/to/credentials.json',
    scopes=['https://www.googleapis.com/auth/bigquery']
)

client = bigquery.Client(
    credentials=credentials,
    project=credentials.project_id
)

Free Tier: Google provides 1 TB of data processed per month free.

Cost Management & Query Optimization

Understanding GitHub Archive Costs

BigQuery charges $6.25 per TiB of data scanned (after the 1 TiB free tier). GitHub Archive tables are large - a single month table can be 50-100 GB, and yearly wildcards can scan multiple TiBs. Unoptimized queries can cost $10-100+, while optimized versions of the same query cost $0.10-1.00.

Key Cost Principle: BigQuery uses columnar storage - you pay for ALL data in the columns you SELECT, not just matching rows. A query with SELECT * on one day of data scans ~3 GB even with LIMIT 10.

ALWAYS Estimate Costs Before Querying

CRITICAL RULE: Run a dry run to estimate costs before executing any query against GitHub Archive production tables.

from google.cloud import bigquery

def estimate_gharchive_cost(query: str) -> dict:
    """Estimate cost before running GitHub Archive query."""
    client = bigquery.Client()

    # Dry run - validates query and returns bytes to scan
    dry_run_config = bigquery.QueryJobConfig(dry_run=True, use_query_cache=False)
    job = client.query(query, job_config=dry_run_config)

    bytes_processed = job.total_bytes_processed
    gb_processed = bytes_processed / (1024**3)
    tib_processed = bytes_processed / (1024**4)
    estimated_cost = tib_processed * 6.25

    return {
        'bytes': bytes_processed,
        'gigabytes': round(gb_processed, 2),
        'tib': round(tib_processed, 4),
        'estimated_cost_usd': round(estimated_cost, 4)
    }

# Example: Always check cost before running
estimate = estimate_gharchive_cost(your_query)
print(f"Cost estimate: {estimate['gigabytes']} GB → ${estimate['estimated_cost_usd']}")

if estimate['estimated_cost_usd'] > 1.0:
    print("⚠️ HIGH COST QUERY - Review optimization before proceeding")

Command-line dry run:

bq query --dry_run --use_legacy_sql=false 'YOUR_QUERY_HERE' 2>&1 | grep "bytes"

When to Ask the User About Costs

ASK USER BEFORE RUNNING if any of these conditions apply:

  1. Estimated cost > $1.00 - Always confirm with user for queries over $1
  2. Wildcard spans > 3 months - Queries like githubarchive.day.2025* scan entire year (~400 GB)
  3. No partition filter - Queries without date/time filters scan entire table range
  4. SELECT * used - Selecting all columns dramatically increases cost
  5. Cross-repository searches - Queries without repo.name filter scan all GitHub activity

Example user confirmation:

Query estimate: 120 GB ($0.75)
Scanning: githubarchive.day.202506* (June 2025, 30 days)
Reason: Cross-repository search for actor 'suspected-user'

This exceeds typical query cost ($0.10-0.30). Proceed? [y/n]

DON'T ASK if:

  • Estimated cost < $0.50 AND query is well-scoped (specific repo + date range)
  • User explicitly requested broad analysis (e.g., "scan all of 2025")

Cost Optimization Techniques for GitHub Archive

1. Select Only Required Columns (50-90% cost reduction)

-- ❌ EXPENSIVE: Scans ALL columns (~3 GB per day)
SELECT * FROM `githubarchive.day.20250615`
WHERE actor.login = 'target-user'

-- ✅ OPTIMIZED: Scans only needed columns (~0.3 GB per day)
SELECT
    type,
    created_at,
    repo.name,
    actor.login,
    JSON_EXTRACT_SCALAR(payload, '$.action') as action
FROM `githubarchive.day.20250615`
WHERE actor.login = 'target-user'

Never use SELECT * in production queries. Always specify exact columns needed.

2. Use Specific Date Ranges (10-100x cost reduction)

-- ❌ EXPENSIVE: Scans entire year (~400 GB)
SELECT ... FROM `githubarchive.day.2025*`
WHERE actor.login = 'target-user'

-- ✅ OPTIMIZED: Scans specific month (~40 GB)
SELECT ... FROM `githubarchive.day.202506*`
WHERE actor.login = 'target-user'

-- ✅ BEST: Scans single day (~3 GB)
SELECT ... FROM `githubarchive.day.20250615`
WHERE actor.login = 'target-user'

Strategy: Start with narrow date ranges (1-7 days), then expand if needed. Use monthly tables (githubarchive.month.202506) for multi-month queries instead of daily wildcards.

3. Filter by Repository Name (5-50x cost reduction)

-- ❌ EXPENSIVE: Scans all GitHub activity
SELECT ... FROM `githubarchive.day.202506*`
WHERE actor.login = 'target-user'

-- ✅ OPTIMIZED: Filter by repo (BigQuery can prune data blocks)
SELECT ... FROM `githubarchive.day.202506*`
WHERE
    repo.name = 'target-org/target-repo'
    AND actor.login = 'target-user'

Rule: Always include repo.name filter when investigating a specific repository.

4. Avoid SELECT * with Wildcards (Critical)

-- ❌ CATASTROPHIC: Can scan 1+ TiB ($6.25+)
SELECT * FROM `githubarchive.day.2025*`
WHERE type = 'PushEvent'

-- ✅ OPTIMIZED: Scans ~50 GB ($0.31)
SELECT
    created_at,
    actor.login,
    repo.name,
    JSON_EXTRACT_SCALAR(payload, '$.ref') as branch
FROM `githubarchive.day.2025*`
WHERE type = 'PushEvent'

5. Use LIMIT Correctly (Does NOT reduce cost on GHArchive)

IMPORTANT: LIMIT does *not


Content truncated.

When not to use it

  • Private repositories not captured in public archives
  • Real-time incident response requiring sub-second updates
  • Non-GitHub related OSINT investigations

Prerequisites

BigQuery account

Limitations

  • Limited to public events
  • High query complexity for specific forensics
  • Requires knowledge of GitHub event schema

How it compares

It uses tamper-proof evidence rather than relying on current repository state which can be modified or deleted.

Compared to similar skills

github-archive side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
github-archive (this skill)14moReviewAdvanced
solidity-security152moNo flagsIntermediate
supabase-rls-policy-generator119moNo flagsAdvanced
backend-security-coder244moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

solidity-security

wshobson

Master smart contract security best practices to prevent common vulnerabilities and implement secure Solidity patterns. Use when writing smart contracts, auditing existing contracts, or implementing security measures for blockchain applications.

15115

supabase-rls-policy-generator

hopeoverture

This skill should be used when the user requests to generate, create, or add Row-Level Security (RLS) policies for Supabase databases in multi-tenant or role-based applications. It generates comprehensive RLS policies using auth.uid(), auth.jwt() claims, and role-based access patterns. Trigger terms include RLS, row level security, supabase security, generate policies, auth policies, multi-tenant security, role-based access, database security policies, supabase permissions, tenant isolation.

11109

backend-security-coder

sickn33

Expert in secure backend coding practices specializing in input validation, authentication, and API security. Use PROACTIVELY for backend security implementations or security code reviews.

2446

sqlmap-database-penetration-testing

davila7

This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing." It provides comprehensive guidance for using SQLMap to detect and exploit SQL injection vulnerabilities.

449

agent-security-manager

ruvnet

Agent skill for security-manager - invoke with $agent-security-manager

337

secure-workflow-guide

trailofbits

Guides through Trail of Bits' 5-step secure development workflow. Runs Slither scans, checks special features (upgradeability/ERC conformance/token integration), generates visual security diagrams, helps document security properties for fuzzing/verification, and reviews manual security areas.

331

Search skills

Search the agent skills registry