Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# CODEOWNERS for autonolas-subgraph-studio
#
# This file routes review of security- and supply-chain-sensitive files to
# the security reviewer(s). Enforcement requires "Require review from Code
# Owners" in branch protection settings — until that is enabled this file
# is advisory and only nudges GitHub's PR review-request UI.
#
# Owner is an individual until a security team exists; switch to a team
# handle (e.g., @valory-xyz/<team>) once one is created.

# Default owner: any unowned path falls back here.
* @Tanya-atatakai

# Workflows, actions config, repository-level GitHub config.
/.github/ @Tanya-atatakai

# Top-level package metadata + lockfile.
/package.json @Tanya-atatakai
/yarn.lock @Tanya-atatakai

# Node-version pin enforced by Corepack in CI.
/.nvmrc @Tanya-atatakai

# Supply-chain controls: scripts that gate CI + allowlists they consult.
/scripts/ @Tanya-atatakai
/.supply-chain/ @Tanya-atatakai

# Disclosure + threat-model docs.
/SECURITY.md @Tanya-atatakai
/SUPPLY-CHAIN-SECURITY.md @Tanya-atatakai

# AI / contributor onboarding context — changes here shape future agent behavior.
/CLAUDE.md @Tanya-atatakai

# Per-subgraph package metadata + lockfiles. Picks up flat (subgraphs/<name>/)
# and nested (subgraphs/predict/predict-omen/, subgraphs/babydegen/babydegen-optimism/) layouts.
/subgraphs/*/package.json @Tanya-atatakai
/subgraphs/*/yarn.lock @Tanya-atatakai
/subgraphs/*/*/package.json @Tanya-atatakai
/subgraphs/*/*/yarn.lock @Tanya-atatakai
44 changes: 39 additions & 5 deletions .github/workflows/deploy-subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ on:
type: string
default: "subgraph.yaml"

permissions:
contents: read

jobs:
plan:
runs-on: ubuntu-latest
Expand All @@ -40,7 +43,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- name: Validate deployment branch
run: |
Expand All @@ -60,6 +63,30 @@ jobs:
fi
echo "✅ Version format is valid: ${{ inputs.version }}"

- name: Validate folder format
run: |
if [[ ! "${{ inputs.folder }}" =~ ^[a-z0-9][a-z0-9_-]*(/[a-z0-9_-]+)?$ ]]; then
echo "❌ Error: folder must be alphanumeric with dashes/underscores, optionally one nested level (e.g., 'liquidity', 'predict/predict-omen')"
exit 1
fi
echo "✅ Folder format is valid: ${{ inputs.folder }}"

- name: Validate subgraph name format
run: |
if [[ ! "${{ inputs.name }}" =~ ^[a-z0-9][a-z0-9_-]+$ ]]; then
echo "❌ Error: name must match The Graph's slug pattern (lowercase alphanumeric, dashes, underscores)"
exit 1
fi
echo "✅ Name format is valid: ${{ inputs.name }}"

- name: Validate manifest filename
run: |
if [[ ! "${{ inputs.manifest }}" =~ ^subgraph(\.[a-z0-9_-]+)?\.yaml$ ]]; then
echo "❌ Error: manifest must match subgraph[.network].yaml (e.g., subgraph.yaml, subgraph.gnosis.yaml)"
exit 1
fi
echo "✅ Manifest filename is valid: ${{ inputs.manifest }}"

- name: Validate subgraph folder exists
run: |
SUBGRAPH_PATH="subgraphs/${{ inputs.folder }}"
Expand Down Expand Up @@ -91,17 +118,24 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: "24"
node-version-file: .nvmrc
cache: "yarn"

- name: Activate pinned Yarn via Corepack
run: |
corepack enable
corepack prepare yarn@1.22.22 --activate
actual="$(yarn --version)"
[ "$actual" = "1.22.22" ] || { echo "::error::corepack activation failed (got $actual)"; exit 1; }

- name: Install subgraph packages
working-directory: subgraphs/${{ inputs.folder }}
run: yarn install
run: yarn install --frozen-lockfile

- name: Authenticate
working-directory: subgraphs/${{ inputs.folder }}
Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Gitleaks

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: gitleaks-${{ github.ref }}
cancel-in-progress: true

jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
# Full history for `gitleaks detect --log-opts="--all"` on push to main.
# PR runs only need the diff range (resolved below).
fetch-depth: 0

- name: Install gitleaks (pinned + checksum-verified)
# GITLEAKS_SHA256 is the SHA-256 of gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz
# from the upstream gitleaks_${GITLEAKS_VERSION}_checksums.txt file. Without
# this, a poisoned GitHub release would silently install a backdoored gitleaks
# on every CI run. When bumping GITLEAKS_VERSION, fetch the upstream checksum
# in the same commit; reviewers should re-fetch and confirm.
env:
GITLEAKS_VERSION: '8.30.1'
GITLEAKS_SHA256: '551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb'
run: |
set -euo pipefail
TARBALL=/tmp/gitleaks.tar.gz
curl -sSL -o "$TARBALL" \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
echo "${GITLEAKS_SHA256} ${TARBALL}" | sha256sum -c -
tar -xz -C /tmp -f "$TARBALL" gitleaks
sudo install -m 0755 /tmp/gitleaks /usr/local/bin/gitleaks
gitleaks version

- name: Detect secrets
# --redact masks any matched secret in CI logs.
# PR: scan only the diff range to keep PR cycles fast.
# push to main: scan full history to catch any rewrites.
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
gitleaks detect \
--source=. \
--no-banner \
--redact \
--log-opts="origin/${{ github.base_ref }}..HEAD" \
--report-format json \
--report-path /tmp/leaks.json \
-v
else
gitleaks detect \
--source=. \
--no-banner \
--redact \
--log-opts="--all" \
--report-format json \
--report-path /tmp/leaks.json \
-v
fi
116 changes: 116 additions & 0 deletions .github/workflows/supply-chain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
name: Supply Chain

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: supply-chain-${{ github.ref }}
cancel-in-progress: true

jobs:
audit:
name: Dependency audit (root tree)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version-file: .nvmrc

- name: Activate pinned Yarn via Corepack
run: |
corepack enable
corepack prepare yarn@1.22.22 --activate
[ "$(yarn --version)" = "1.22.22" ] || { echo "::error::corepack activation failed"; exit 1; }

# `yarn audit` reads yarn.lock directly; no install needed.
- name: Run audit
run: yarn audit:prod

install-hooks:
name: Install-hook audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version-file: .nvmrc

- name: Activate pinned Yarn via Corepack
run: |
corepack enable
corepack prepare yarn@1.22.22 --activate
[ "$(yarn --version)" = "1.22.22" ] || { echo "::error::corepack activation failed"; exit 1; }

# `--ignore-scripts` so the hooks don't run while we're enumerating them.
- name: Install dependencies (no hooks)
run: yarn install --frozen-lockfile --ignore-scripts

- name: Run install-hook audit
run: yarn audit:install-hooks

lockfile-lint:
name: Lockfile validation
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# 13 paths: root + 12 subgraphs. Mirrors test.yaml's matrix shape;
# every yarn.lock gets linted.
path:
- "."
- "subgraphs/liquidity"
- "subgraphs/liquidity-l2"
- "subgraphs/tokenomics-eth"
- "subgraphs/tokenomics-l2"
- "subgraphs/governance"
- "subgraphs/staking"
- "subgraphs/service-registry"
- "subgraphs/legacy-mech-fees"
- "subgraphs/new-mech-fees"
- "subgraphs/predict/predict-omen"
- "subgraphs/predict/predict-polymarket"
- "subgraphs/babydegen/babydegen-optimism"
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version-file: .nvmrc

# Catches non-registry deps (e.g. codeload.github.com), HTTP-only sources,
# and missing integrity hashes. See SUPPLY-CHAIN-SECURITY.md §6.
- name: Lint ${{ matrix.path }}/yarn.lock
working-directory: ${{ matrix.path }}
run: |
npx --yes lockfile-lint \
--path yarn.lock \
--type yarn \
--validate-https \
--allowed-hosts yarn npm \
--empty-hostname false

# Aggregator that fails iff any of the above fails. Promote this single
# check to required-status in branch protection (rather than each job
# individually) for a stable interface that survives matrix changes.
all-checks-passed:
name: All checks passed
needs: [audit, install-hooks, lockfile-lint]
if: always()
runs-on: ubuntu-latest
steps:
- run: |
if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] || \
[[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]] || \
[[ "${{ contains(needs.*.result, 'skipped') }}" == "true" ]]; then
echo "::error::One or more required jobs did not succeed"
exit 1
fi
echo "All supply-chain checks passed."
18 changes: 14 additions & 4 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
push:
branches: [main]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -55,15 +58,22 @@ jobs:

name: test / ${{ matrix.subgraph }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1

- uses: actions/setup-node@v4
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: "20"
node-version-file: .nvmrc

- name: Activate pinned Yarn via Corepack
run: |
corepack enable
corepack prepare yarn@1.22.22 --activate
actual="$(yarn --version)"
[ "$actual" = "1.22.22" ] || { echo "::error::corepack activation failed (got $actual)"; exit 1; }

- name: Install dependencies
working-directory: ${{ matrix.path }}
run: yarn install --frozen-lockfile || yarn install
run: yarn install --frozen-lockfile

- name: Generate manifests
if: matrix.generate
Expand Down
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,14 @@ generated-l2/

.yarn

.DS_Store
.DS_Store

/.plans

# This repo uses yarn classic; reject lockfiles from other package managers
package-lock.json
pnpm-lock.yaml
bun.lockb

# Local supply-chain audit baselines (Tier 0 / pre-PR recon output)
/audit
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.18.0
Loading