Skip to content

fix(security): drop persisted credentials before dependency lifecycle code - #894

Draft
seonghobae wants to merge 16 commits into
developfrom
fix/security-audit-checkout-credentials
Draft

fix(security): drop persisted credentials before dependency lifecycle code#894
seonghobae wants to merge 16 commits into
developfrom
fix/security-audit-checkout-credentials

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Security boundary

BandScope dependency-lifecycle workflows must not leave checkout credentials persisted in Git configuration while untrusted npm/Python dependency code executes. Protected develop already had a compliant cross-platform build boundary, and canonical #783 owns the equivalent ci.yml hardening; exact-current-code inspection found three BandScope-owned remaining lifecycle paths with default checkout credential persistence: security-audit, release, and bandit.

Protected base snapshot: develop@acdbea6344fe1231c39535b575f4de35e4c607c9.
Exact current head: 475adeba62109e1e34981baed22ce89728211108.
Draft retained.

Test-first repair

The branch adds a repository contract test that extracts the checkout step itself and requires persist-credentials: false for:

  • .github/workflows/security-audit.yml;
  • .github/workflows/release.yml; and
  • .github/workflows/bandit.yml.

The helper deliberately stops at the next workflow step, so a later action's unrelated persist-credentials: false cannot satisfy the checkout contract. A separate regression locks that false-positive boundary.

Exact workflow evidence exposed two formatter-only defects before the substantive contract could be accepted:

  1. predecessor 4116a0d108f719e1a4382bdbe588ce762843f871 failed ci at Ruff import-layout formatting in test_security_audit_workflow_credentials.py; exact job logs were inspected before mutation;
  2. successor 07160db4dd4559d03b9b095395beb2f19a1ee254 passed Ruff check but exact release logs showed ruff format --check src tests would still reformat the multi-line CHECKOUT_MARKER assignment under the repository's 100-column formatter contract.

Current head 475adeba62109e1e34981baed22ce89728211108 contains only the formatter-equivalent test cleanup needed to satisfy both boundaries; the security invariant and production workflow behavior are unchanged by those follow-up commits.

Production repair adds only:

with:
  persist-credentials: false

to the checkout steps in release.yml and bandit.yml. The existing security-audit.yml repair remains. CHANGELOG.md and docs/security/dependency-policy.md describe the lifecycle credential boundary.

Ownership / non-duplication

This PR changes exactly six BandScope-owned files: three dependency-lifecycle workflows, the focused regression, CHANGELOG, and dependency policy. It deliberately does not modify ci.yml, because canonical dependency-security PR #783 already owns the relevant CI checkout-credential hardening together with the coordinated npm/PDF.js/Nanoid/Undici baseline. build-baseline.yml was already compliant. CodeQL lifecycle files remain owned by #780.

No dependency version, root lockfile, vulnerability suppression, review-agent credential, application permission, database, model, network, filesystem, or IPC authority is added or weakened.

Security rationale

actions/checkout supports disabling persisted credentials. Dependency installation and audit steps execute code supplied by dependency ecosystems; those steps do not require authenticated Git writes. Removing the persisted checkout credential therefore reduces ambient authority without weakening repository read access, security gates, or release evidence.

Exact-current-head repository evidence

Evidence here binds only to 475adeba62109e1e34981baed22ce89728211108.

Terminal-success repository workflows are now:

  • ci run 31993437323;
  • build-baseline run 31993437353;
  • release run 31993437330;
  • secret-scan-gate run 31993437361;
  • sbom run 31993437328;
  • bandit run 31993437356; and
  • SAST Semgrep run 31993437327.

Exact-head failures were inspected at job/log level before classification:

  • security-audit run 31993437352, job 95280857480, reaches dependency audit after the checkout-credential hardening and fails only on the protected-base JavaScript set nanoid <3.3.18, pdfjs-dist >=5.6.83 <6.2.108, and undici 7.0.0-7.28.0; later Python/Rust audit stages are skipped and are not counted as success;
  • aggregate Security Scan run 31993437347, trivy-fs job 95280857514, reports the protected-base HIGH CVE-2026-16633 pdfjs-dist finding at package-lock.json:6370 and directs remediation to the shared base.

This branch has no dependency/root-lock delta, so those two failures remain canonical #783-owned inherited protected-base evidence. They are neither suppressed nor duplicated here. A current #867 security-audit log independently still showed persist-credentials: true on protected-base workflow state, confirming this PR repairs a real BandScope-owned lifecycle authority gap rather than papering over the dependency failure.

Current inline review-thread inspection has no unresolved actionable thread. No queued, cancelled, failed inherited-base, predecessor-head, or protected-base result is counted as success.

Dependency / review order

Canonical #783 must establish the protected JavaScript dependency-security baseline. Current central required-workflow repair is read-only .github#1020; it must reach protected central main before fresh central coverage/review evidence can count here. Historical .github#1008 is closed unmerged and transfers no evidence. Reviewer agents must not be redispatched merely to reproduce the unchanged central trusted-uv prerequisite.

There is no qualifying independent non-author last-push approval for this exact head.

Merge gate

Keep Draft and unmerged until the unchanged then-current head has terminal-success repository and central CI, exact owned statement/branch coverage and docstrings where applicable, SAST/security/SBOM/supply-chain/package/release evidence, zero valid unresolved findings, canonical dependency/central prerequisites integrated and regenerated, a qualifying independent non-author last-push approval, and ordinary branch-protection acceptance. Queued, in-progress, skipped-required, failed inherited-base, predecessor-head, protected-base, model-only, self/author, or administrative-bypass evidence is not success.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c9c446c4-00b5-4381-8c33-d6da885262d2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae seonghobae changed the title fix(security): prevent audit checkout credential persistence fix(security): drop persisted credentials before dependency lifecycle code Aug 17, 2026
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.

1 participant