Skip to content

ci(DPA2-6761): add the weekday dependency audit - #149

Draft
rharutyunyan wants to merge 6 commits into
mainfrom
feature/DPA2-6761_weekday-caller
Draft

rharutyunyan wants to merge 6 commits into
mainfrom
feature/DPA2-6761_weekday-caller

Conversation

@rharutyunyan

@rharutyunyan rharutyunyan commented Oct 20, 2026 •

Copy link
Copy Markdown

Context

Pull requests in this repository scan the whole dependency tree on every push, so a new advisory on a package that is already on the default branch fails every open pull request, including ones that never touched dependencies. DPA2-6761 replaces those gates with one weekday job: it scans the default branch with Trivy and a Cursor agent keeps a single fix pull request from feature/DPA2-6761_dependency-audit.

What changes

  • Adds .github/workflows/dependency-audit.yaml: runs 35 1 * * 1-5 (UTC, Monday to Friday) and on workflow_dispatch, on ubuntu-latest against main. It is an inlined copy of the shared job from 1inch/workflows#59, because this repository cannot call that private reusable workflow. The scan, the prompt and the agent setup are identical to it, and the copy is generated from the shared file rather than hand-written.

  • Passes secrets.CURSOR_API_KEY, which is the organization secret, so this repository holds no credential of its own. There is no PAT: the fix branch and its pull request belong to the Cursor GitHub App.

  • This repository had no pull-request vulnerability gate, so it only gains the weekday job.

The fix agent now runs through the Cursor SDK

The shared job used to start the fix agent with the Cursor CLI, which leaves no handle on the run afterwards: every repository's spend lands in one undifferentiated invoice line. It now creates a Cursor cloud agent with @cursor/sdk, and cloud.metadata tags that agent for its whole lifetime:

Tag Value
repository this repository
usecase dependency-update
workflow dependency-audit
base_branch / fix_branch what was scanned / where the fix goes
runner the runner input
run_id / run_attempt / server_url the GitHub Actions run

Usage and billing exports carry cloud_agent_id, so this repository's spend can be joined to its use case. The agent id is printed to the job summary so a run can be traced back.

The mechanical work — bump the parent dependency, regenerate the lockfile, re-scan the directory — goes to a dependency-fixer subagent pinned to DeepSeek Flash. The scan already names the package, the version and the lockfile, so that loop does not need a frontier model; the parent agent stays on the account default so the plan, the verification and the pull request body stay coherent.

The key difference from the CLI flow: a clean repository no longer spends anything. No fixable critical or high finding means no agent is created at all.

Before merging

  1. CURSOR_API_KEY exists as an organization secret (DevOps owns it); without it the weekday run fails with a named error. There is no second secret to publish.
  2. No branch protection rule still requires a removed check (security-audit, dependabot-audit or Trivy Security Scan). The rulesets readable with write access require none; classic branch protection needs an admin to confirm.
  3. The Cursor GitHub App can clone this repository: the agent runs in its own cloud VM and clones through that App, not through GITHUB_TOKEN.

How it was verified

  • actionlint 1.7.7 on the inlined workflow: clean.
  • The inlined file is generated from the shared workflow, and the embedded runner was extracted through the same heredoc the workflow uses and passes node --check (466 lines).
  • The repository's unit tests for the shared workflow pass (34 of them, covering the metadata tags, the pinned subagent, findings compaction, the payload cap and the verdict parser).
  • After merge: run Dependency Audit once from the Actions tab and confirm it ends green with no findings or opens one pull request from feature/DPA2-6761_dependency-audit.

Notes for reviewers

  • The DeepSeek slug is unverified against the live catalog. deepseek-v41-flash-1017-high follows the grok-4.7-high shape the workflow used before. If it is wrong the job fails at Agent.create() with a clear error and nothing is pushed. The first real dispatch confirms it.
  • The agent VM must be able to clone this repository. The Cursor GitHub App handles that, and nothing in CI can assert it — the first dispatch is what proves it.
  • The model is pinned in the shared workflow and is not an input, so a caller cannot change it.

Note

Medium Risk
Introduces scheduled CI that can push dependency changes and open/update a long-lived fix branch via an external agent and org API key, though scope is limited to lockfiles and the workflow explicitly avoids editing other areas.

Overview
Adds a weekday Dependency Audit workflow (Mon–Fri UTC, plus manual dispatch) that scans main with Trivy, filters accepted advisories from package.json pnpm audit config, and skips the agent entirely when there are no fixable CRITICAL/HIGH findings.

When findings exist, a new composite action dependency-audit-agent spins up a Cursor cloud agent via @cursor/sdk (replacing an undifferentiated CLI flow), tags it with cloud.metadata for per-repo billing, and delegates lockfile bumps to a dependency-fixer subagent on a pinned cheap model. Findings are passed as action inputs → agent env vars; git push and PR creation go through the Cursor GitHub App (GITHUB_TOKEN is only used to set title/body on a new PR). The job fails if the agent does not finish, returns no JSON verdict, or reports unresolved CRITICAL/HIGH items.

The workflow file is an inlined copy of a private shared workflow so repos that cannot workflow_call it still ship the same logic; the action is vendored alongside for the same reason.

Reviewed by Cursor Bugbot for commit 65021a0. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds the weekday dependency-audit job, which scans the default branch with Trivy and keeps one fix pull request.
@claude

claude Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

1 similar comment
@claude

claude Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Claude encountered an error —— View job


I'll analyze this and get back to you.

The shared workflow now creates a Cursor cloud agent with @cursor/sdk instead of
starting the Cursor CLI, so each run is tagged with the repository, use case and
ticket and its spend can be attributed. The fix work itself goes to a DeepSeek
Flash subagent.

CURSOR_API_KEY is now the organization secret, so this repository needs no copy
of its own.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread .github/workflows/dependency-audit.yaml Resolved
Comment thread .github/workflows/dependency-audit.yaml Resolved
Comment thread .github/workflows/dependency-audit.yaml Resolved
The shared workflow now creates a Cursor cloud agent with @cursor/sdk instead of
starting the Cursor CLI, so each run is tagged with the repository, use case and
ticket and its spend can be attributed. The fix work itself goes to a DeepSeek
Flash subagent.

CURSOR_API_KEY is now the organization secret, so this repository needs no copy
of its own.
The shared workflow now creates a Cursor cloud agent with @cursor/sdk instead of
starting the Cursor CLI, so each run is tagged with the repository, use case and
ticket and its spend can be attributed. The fix work itself goes to a DeepSeek
Flash subagent.

The fix pull request is opened by the Cursor GitHub App, so AUDIT_PAT is gone and
CURSOR_API_KEY (organization-scoped) is the only secret this repository needs.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread .github/workflows/dependency-audit.yaml Resolved
Comment thread .github/workflows/dependency-audit.yaml Outdated
// the PR is what keeps it to one: `gh pr create` cannot see that a PR from the branch
// already exists when the head is identical, and would fail or open a second one.
autoCreatePR: true,
openAsCursorGithubApp: true,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDK not bound to named fix PR

Medium Severity

Agent.create always starts from main with autoCreatePR: true and never receives BRANCH or the URL from existing_pr. Cursor’s default is a new cursor/... branch and a PR when the run ends, so the single feature/DPA2-6761_weekday-caller pull request is not enforced by the SDK.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c8844af. Configure here.

The shared workflow now creates a Cursor cloud agent with @cursor/sdk instead of
starting the Cursor CLI, so each run is tagged with the repository, use case and
ticket and its spend can be attributed. The fix work itself goes to a DeepSeek
Flash subagent.

The fix pull request is opened by the Cursor GitHub App, so AUDIT_PAT is gone and
CURSOR_API_KEY (organization-scoped) is the only secret this repository needs.
The job takes no Jira ticket: it runs on a weekday schedule.
The shared workflow now creates a Cursor cloud agent with @cursor/sdk instead of
starting the Cursor CLI, so each run is tagged with the repository, use case and
ticket and its spend can be attributed. The fix work itself goes to a DeepSeek
Flash subagent.

The fix pull request is opened by the Cursor GitHub App, so AUDIT_PAT is gone and
CURSOR_API_KEY (organization-scoped) is the only secret this repository needs.
The job takes no Jira ticket: it runs on a weekday schedule.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 65021a0. Configure here.

}

// Fail before spending anything on a malformed findings payload.
parseArrayInput(findings.FINDINGS_CRITICAL_HIGH);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preflight never rejects malformed findings

Low Severity

The new preflight claims to abort on a malformed findings-critical-high payload before creating a cloud agent, but parseArrayInput never throws and its result is discarded. Invalid JSON still reaches Agent.create(), so a bad payload still spends on a billed run. The helper also keeps only strings, so it cannot validate the object array the scan actually emits.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 65021a0. Configure here.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants