Authenticate C2PA registry-sync GitHub API calls to fix CI rate-limiting

scripts/sync_c2pa_soft_bindings.py --check hits api.github.com to resolve
the latest upstream commit SHA, unauthenticated. That endpoint's 60/hour
rate limit is per source IP, which GitHub Actions runners exhaust fast
since many workflows share the runner IP pool -- this was failing the
lint job with "403: rate limit exceeded" on every push regardless of
whether the change touched anything related.

Send an Authorization: Bearer header built from GITHUB_TOKEN/GH_TOKEN
when set, scoped to api.github.com only (raw.githubusercontent.com is a
separate, much higher-limit CDN and doesn't need it). Wire the workflow's
own GITHUB_TOKEN secret into that step's env so CI actually has one to
send, raising the limit to 5000/hour.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Victor KuznetsovandClaude Sonnet 5 committed 2026-09-22 08:11:48 -07:00
1 parent be8f24c7cb
commit e3bbe88155
3 files changed
+49 -1

No files matched your search

+13 -1
View File
@@ -7,6 +7,7 @@ import argparse
import hashlib
import json
import logging
import os
import re
import sys
from dataclasses import dataclass
@@ -54,7 +55,18 @@ class RegistryRow:
def _read_bytes(source: str) -> bytes:
parsed = urlparse(source)
if parsed.scheme in {"http", "https"}:
request = Request(source, headers={"User-Agent": "remove-ai-watermarks-c2pa-registry-sync"})
headers = {"User-Agent": "remove-ai-watermarks-c2pa-registry-sync"}
# api.github.com rate-limits unauthenticated requests to 60/hour PER SOURCE IP,
# which CI runners exhaust fast since many workflows across many repos share
# GitHub's runner IP pool -- a 403 "rate limit exceeded" here is that, not an
# outage. A GITHUB_TOKEN (Actions injects one into every run; export it as an
# env var to reach this process) raises the same endpoint to 5000/hour.
# raw.githubusercontent.com is a separate, much higher-limit CDN and does not
# need this.
token = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
if token and parsed.hostname == "api.github.com":
headers["Authorization"] = f"Bearer {token}"
request = Request(source, headers=headers)
with urlopen(request, timeout=30) as response:
return response.read()
return Path(source).read_bytes()