Skip to content

Commit f0ee72a

Browse files
NagyViktNagyVikt
andauthored
Harden Scorecard signals around release signing and PR checks (#392)
Add pull_request coverage for CI and CodeQL, exact dependency pins, npm Dependabot coverage, and signed GitHub release assets via Sigstore bundles. Also fix the security advisory link and widen CODEOWNERS so stricter review settings have matching repo metadata. Constraint: Signed-release credit only improves on future or re-run releases because existing tags have no uploaded assets Rejected: Require two reviewers immediately | likely blocks this mostly single-maintainer repo without proving sustainable reviewer capacity Confidence: medium Scope-risk: moderate Directive: If branch protection is tightened after merge, keep required check names aligned with workflow job names before renaming them Tested: node --test test/metadata.test.js Tested: timeout 180 npm test Tested: openspec validate agent-codex-harden-scorecard-best-practices-2026-04-23-18-42 --type change --strict Tested: openspec validate --specs Not-tested: Live GitHub Actions release run producing .sigstore.json assets Not-tested: Live Scorecard rerun after the next signed release and branch-protection update Co-authored-by: NagyVikt <nagy.viktordp@gmail.com>
1 parent 0660f4c commit f0ee72a

13 files changed

Lines changed: 206 additions & 9 deletions

File tree

.github/CODEOWNERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
* @recodeecom
1+
# Default code owners for repository-wide reviews.
2+
* @recodeecom @NagyVikt

.github/dependabot.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
version: 2
22
updates:
3+
- package-ecosystem: npm
4+
directory: /
5+
schedule:
6+
interval: weekly
7+
versioning-strategy: lockfile-only
38
- package-ecosystem: github-actions
49
directory: /
510
schedule:

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
push:
55
branches:
66
- main
7+
pull_request:
8+
branches:
9+
- main
710

811
permissions:
912
contents: read

.github/workflows/codeql.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
push:
55
branches:
66
- main
7+
pull_request:
8+
branches:
9+
- main
710
schedule:
811
- cron: '35 3 * * 1'
912

.github/workflows/release.yml

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Release to npm (provenance)
1+
name: Release to npm (provenance + signed assets)
22

33
on:
44
workflow_dispatch:
@@ -14,6 +14,9 @@ jobs:
1414
if: github.repository == 'recodeee/gitguardex'
1515
runs-on: ubuntu-latest
1616
environment: npm
17+
permissions:
18+
contents: write
19+
id-token: write
1720

1821
steps:
1922
- name: Checkout
@@ -28,6 +31,9 @@ jobs:
2831
registry-url: https://registry.npmjs.org
2932
cache: npm
3033

34+
- name: Install Cosign
35+
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
36+
3137
- name: Install
3238
run: npm ci --ignore-scripts
3339

@@ -55,6 +61,14 @@ jobs:
5561
echo "already_published=false" >> "$GITHUB_OUTPUT"
5662
fi
5763
64+
- name: Pack release tarball
65+
id: pack
66+
run: |
67+
mkdir -p dist
68+
package_file="$(npm pack --pack-destination dist | tail -n 1)"
69+
echo "package_file=${package_file}" >> "$GITHUB_OUTPUT"
70+
echo "package_path=dist/${package_file}" >> "$GITHUB_OUTPUT"
71+
5872
- name: Publish with provenance
5973
if: ${{ steps.registry.outputs.already_published != 'true' }}
6074
run: npm publish --provenance --access public
@@ -65,3 +79,24 @@ jobs:
6579
PACKAGE_NAME: ${{ steps.pkg.outputs.name }}
6680
PACKAGE_VERSION: ${{ steps.pkg.outputs.version }}
6781
run: echo "${PACKAGE_NAME}@${PACKAGE_VERSION} is already on npm; skipping publish."
82+
83+
- name: Generate release checksum
84+
run: |
85+
sha256sum "${{ steps.pack.outputs.package_path }}" > "${{ steps.pack.outputs.package_path }}.sha256"
86+
87+
- name: Sign release tarball with Sigstore
88+
run: |
89+
cosign sign-blob "${{ steps.pack.outputs.package_path }}" \
90+
--bundle "${{ steps.pack.outputs.package_path }}.sigstore.json" \
91+
--yes
92+
93+
- name: Upload signed release assets
94+
env:
95+
GH_TOKEN: ${{ github.token }}
96+
RELEASE_TAG: ${{ github.event.release.tag_name || format('v{0}', steps.pkg.outputs.version) }}
97+
run: |
98+
gh release upload "$RELEASE_TAG" \
99+
"${{ steps.pack.outputs.package_path }}" \
100+
"${{ steps.pack.outputs.package_path }}.sha256" \
101+
"${{ steps.pack.outputs.package_path }}.sigstore.json" \
102+
--clobber

SECURITY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Only the latest published GitGuardex CLI build is supported for security fixes.
88

99
Please report security issues privately by opening a GitHub security advisory:
1010

11-
- https://github.com/recodeecom/multiagent-safety/security/advisories/new
11+
- https://github.com/recodeee/gitguardex/security/advisories/new
1212

1313
If advisories are unavailable, open a private report via GitHub issue contact details and avoid posting exploit details publicly.
1414

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-04-23
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
## Why
2+
3+
- GitGuardex already ships several Scorecard-friendly guardrails, but key supply-chain signals still lag behind the repository's actual intent.
4+
- The release workflow publishes to npm with provenance but leaves GitHub releases without signed assets, so Scorecard cannot award signed-release credit.
5+
- CI and CodeQL do not run on pull requests to `main`, which weakens branch-protection hardening because there are no stable pre-merge checks to require.
6+
- Package metadata and security/reporting metadata still contain avoidable drift such as range-based dependency specifiers and a repo link that points elsewhere.
7+
8+
## What Changes
9+
10+
- Run CI and CodeQL for pull requests targeting `main` so required status checks have real pre-merge coverage.
11+
- Extend the release workflow to build the npm tarball, checksum it, sign it with a Sigstore bundle, and upload those artifacts to the matching GitHub release.
12+
- Expand Dependabot to cover npm packages and pin package dependency specifiers exactly in both `package.json` and `package-lock.json`.
13+
- Correct security-reporting and code-owner metadata needed for stricter GitHub review settings.
14+
15+
## Impact
16+
17+
- Affects GitHub Actions workflows, dependency metadata, and security/review docs only; runtime CLI behavior stays unchanged.
18+
- Signed-release score gains apply to future or re-run releases; historical releases without assets remain unchanged until republished or manually backfilled.
19+
- Branch-protection, maintained, contributors, and code-review scores still depend partly on live GitHub settings, repo age, and human review history outside this diff.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## ADDED Requirements
2+
3+
### Requirement: Pull request checks for protected main
4+
The repository SHALL run CI and CodeQL workflows on pull requests targeting `main` so branch-protection rules can require real pre-merge status checks.
5+
6+
#### Scenario: CI runs on pull requests
7+
- **WHEN** a pull request targets `main`
8+
- **THEN** `.github/workflows/ci.yml` triggers for that pull request
9+
- **AND** the workflow remains enabled for direct pushes to `main`.
10+
11+
#### Scenario: CodeQL runs on pull requests
12+
- **WHEN** a pull request targets `main`
13+
- **THEN** `.github/workflows/codeql.yml` triggers for that pull request
14+
- **AND** the scheduled scan remains enabled.
15+
16+
### Requirement: Signed GitHub release assets
17+
The release workflow SHALL publish signed GitHub release assets for the package tarball in addition to npm provenance.
18+
19+
#### Scenario: Release uploads signed artifacts
20+
- **WHEN** `.github/workflows/release.yml` runs for a published release
21+
- **THEN** it builds the npm tarball, generates a SHA256 checksum, creates a Sigstore bundle for the tarball, and uploads those files to the matching GitHub release
22+
- **AND** the workflow continues to publish to npm with provenance when the version is not already published.
23+
24+
### Requirement: Pinned dependency and update metadata
25+
The repository SHALL keep supply-chain metadata aligned with stricter Scorecard expectations.
26+
27+
#### Scenario: Package specs stay exact
28+
- **WHEN** runtime or dev dependencies are declared in `package.json`
29+
- **THEN** their versions are pinned exactly
30+
- **AND** `package-lock.json` reflects those exact specifiers.
31+
32+
#### Scenario: Automated update coverage includes npm
33+
- **WHEN** Dependabot configuration is evaluated
34+
- **THEN** it schedules updates for both npm dependencies and GitHub Actions.
35+
36+
### Requirement: Security and ownership metadata points at this repository
37+
Repository security and ownership metadata SHALL reference the live GitGuardex repository surfaces.
38+
39+
#### Scenario: Security reporting points at this repo
40+
- **WHEN** maintainers or users read `SECURITY.md`
41+
- **THEN** the private advisory link targets `recodeee/gitguardex`.
42+
43+
#### Scenario: Code owners cover default review paths
44+
- **WHEN** repository-wide ownership is evaluated
45+
- **THEN** `.github/CODEOWNERS` defines default owners for all files.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
## Definition of Done
2+
3+
This change is complete only when **all** of the following are true:
4+
5+
- Every checkbox below is checked.
6+
- The agent branch reaches `MERGED` state on `origin` and the PR URL + state are recorded in the completion handoff.
7+
- If any step blocks (test failure, conflict, ambiguous result), append a `BLOCKED:` line under section 4 explaining the blocker and **STOP**. Do not tick remaining cleanup boxes; do not silently skip the cleanup pipeline.
8+
9+
## Handoff
10+
11+
- Handoff: change=`agent-codex-harden-scorecard-best-practices-2026-04-23-18-42`; branch=`agent/codex/harden-scorecard-best-practices-2026-04-23-18-42`; scope=`Scorecard-facing workflows, dependency metadata, and security/review docs`; action=`finish repo-side hardening, then apply and verify reachable GitHub settings`.
12+
- Copy prompt: Continue `agent-codex-harden-scorecard-best-practices-2026-04-23-18-42` on branch `agent/codex/harden-scorecard-best-practices-2026-04-23-18-42`. Work inside the existing sandbox, review `openspec/changes/agent-codex-harden-scorecard-best-practices-2026-04-23-18-42/tasks.md`, continue from the current state instead of creating a new sandbox, and when the work is done run `gx branch finish --branch agent/codex/harden-scorecard-best-practices-2026-04-23-18-42 --base main --via-pr --wait-for-merge --cleanup`.
13+
14+
## 1. Specification
15+
16+
- [x] 1.1 Finalize proposal scope and acceptance criteria for `agent-codex-harden-scorecard-best-practices-2026-04-23-18-42`.
17+
- [x] 1.2 Define normative requirements in `specs/harden-scorecard-best-practices/spec.md`.
18+
19+
## 2. Implementation
20+
21+
- [x] 2.1 Implement scoped behavior changes.
22+
- [x] 2.2 Add/update focused regression coverage.
23+
24+
## 3. Verification
25+
26+
- [x] 3.1 Run targeted project verification commands.
27+
- [x] 3.2 Run `openspec validate agent-codex-harden-scorecard-best-practices-2026-04-23-18-42 --type change --strict`.
28+
- [x] 3.3 Run `openspec validate --specs`.
29+
30+
## 4. Cleanup (mandatory; run before claiming completion)
31+
32+
- [ ] 4.1 Run the cleanup pipeline: `gx branch finish --branch agent/codex/harden-scorecard-best-practices-2026-04-23-18-42 --base main --via-pr --wait-for-merge --cleanup`. This handles commit -> push -> PR create -> merge wait -> worktree prune in one invocation.
33+
- [ ] 4.2 Record the PR URL and final merge state (`MERGED`) in the completion handoff.
34+
- [ ] 4.3 Confirm the sandbox worktree is gone (`git worktree list` no longer shows the agent path; `git branch -a` shows no surviving local/remote refs for the branch).

0 commit comments

Comments
 (0)