Skip to main content

Repository Risk Scanner

Use the Repository Risk Scanner to review source repositories for software supply-chain risk before your team trusts a merge, a release, or a third-party code drop.

If a term is unfamiliar, open the Glossary.

What this page is for​

This workflow helps you answer questions such as:

  • Is this repository safe enough to review further?
  • Did this change introduce risky install, CI, or release behavior?
  • Are the dependencies and lockfiles trustworthy enough for release?
  • Do the shipped artifacts appear linked back to reviewed source and provenance?
  • Should our team pass, review, or fail this repository in CI?

This is useful for:

  • workspace admins
  • engineering managers
  • AppSec reviewers
  • security analysts
  • platform teams reviewing third-party or internal repositories

What Dralvia reviews​

When you upload a repository ZIP, Dralvia can review several layers at once.

Repository context​

If you provide it, Dralvia stores:

  • provider
  • owner or organization
  • repository name
  • branch, tag, or ref
  • commit SHA
  • pull request or change request

This is helpful because later rescans, exports, and drift reviews stay attached to the same software review unit instead of becoming anonymous ZIP uploads.

Project and workspace grouping​

If the ZIP contains a monorepo, Dralvia groups the results by real projects or workspaces. That makes it easier to see:

  • which project is affected
  • which ecosystem it belongs to
  • where the highest-risk paths actually sit

Automation and execution paths​

Dralvia reviews:

  • install hooks
  • postinstall behavior
  • build steps
  • release scripts
  • GitHub Actions
  • GitLab CI
  • Docker build steps
  • Git hooks
  • shell-heavy bootstrap logic

Three checks catch attacks that hide from a normal code review:

  • Workflow injection. A GitHub Actions step that pastes text an outsider controls (an issue title, a pull request body or branch name, a commit message) straight into a command with ${{ }}. Anyone who opens an issue or pull request can then run code in the pipeline. Passing the value through an environment variable is the safe form and is not reported.
  • Untrusted pull request code run with secrets. A workflow triggered by pull_request_target or workflow_run that checks out the pull request's own code, which then runs with the repository's secrets and write token. When the job is limited to the project's own branches or to a bot, the finding is still shown, as medium, and names that condition, because a condition can be edited away. Measured on 1,060 real workflows (GitHub's starter workflows and 27 large open-source projects): no false matches; the two matches were both this pattern, and both limited this way.
  • Hidden code. Long runs of characters that display as nothing (the GlassWorm technique, which hides a program inside an apparently empty string) and text-direction controls that make code display differently from how it runs (Trojan Source). Measured on 52,527 files of popular npm and PyPI packages: no matches. Emoji, right-to-left text and regular expressions that list these characters are not reported.

Known worm indicators are named, and they block the CI gate:

  • The Shai-Hulud worm family (September 2025, November 2025 "Sha1-Hulud: The Second Coming", and the 2026 waves). It steals npm, GitHub and cloud credentials and publishes itself into every package the victim maintains. Reported as critical: the setup_bun.js and bun_environment.js loader pair, an install script that starts it, a job on the worm's SHA1HULUD runner, a workflow named after the worm, and the campaign's own strings and servers in code. Treat every credential on machines and pipelines that installed or opened such code as stolen. Security write-ups that quote the indicators (Markdown, text, HTML) are not reported.
  • A workflow that serializes every secret at once (toJSON(secrets)), which is how the worm's "Code Formatter" workflows stole them. Reported as high. None of 874 real workflows does this; pass each job only the secrets it needs.

AI coding assistant and editor configuration​

A repository can tell an AI coding assistant what to do and what to run. Opening it in Claude Code, Gemini CLI, Cursor or VS Code reads these files, so they are reviewed like install scripts:

  • Hidden text in the assistant's instructions. Invisible characters in .cursorrules, .windsurfrules, AGENTS.md, CLAUDE.md, GEMINI.md, .github/copilot-instructions.md, .github/instructions/*.instructions.md, .cursor/rules/ and the other assistant folders. Reviewers do not see them; the assistant reads them (the Rules File Backdoor technique). Invisible "tag" characters, which spell out a hidden sentence, are critical and the sentence is shown decoded; zero-width and text-direction characters are high. Emoji are not reported.
  • Commands the assistant runs on its own: hooks, the status line and helper commands in .claude/settings.json, .gemini/settings.json and .cursor/hooks.json. Many projects use these for formatters and setup scripts, so the commands are listed as a low finding for you to check. A command that downloads or decodes code is high (the 2026 Shai-Hulud waves hid in a Claude Code SessionStart hook), and settings that start every MCP server the repository lists without asking (enableAllProjectMcpServers) are medium.
  • The assistant's traffic sent elsewhere: an env entry such as ANTHROPIC_BASE_URL pointing at a host that is not the provider's own, which would send your API key there (CVE-2026-21852). Reported as high. Local addresses are not reported.
  • An MCP server that downloads or decodes code when the assistant starts it (.mcp.json, .cursor/mcp.json, .vscode/mcp.json). Reported as high. A pinned package started with npx or a local script is not.

Measured on the 1,000 most-starred GitHub repositories updated since June 2026 (2,426 assistant and editor files): 44 list their own commands (low), 5 auto-approve MCP servers (medium), and none matched any of the other checks.

Dependency and lockfile trust​

Dralvia reviews:

  • dependency graphs by project
  • shared dependencies across projects
  • floating ranges
  • rewritten sources
  • vendored or local dependencies
  • missing lockfile coverage
  • integrity drift

Lockfile integrity is checked by reading the hashes recorded in the lockfile and reporting whether every locked entry is pinned to a hash (verified), only some are (mixed), or none are (missing). This covers npm (package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock), Python (Pipfile.lock, poetry.lock, uv.lock), Go (go.sum), and Rust (Cargo.lock).

When controlled enrichment is available, Dralvia can also add:

  • known-vulnerability advisory matches for pinned dependencies across npm, Python (PyPI), Go, Rust (crates.io), and Java (Maven), sourced from the public OSV advisory database
  • versions published as malware (OSV MAL- records, for example [email protected] from the September 2025 npm compromise). These are reported as critical and block the CI gate, ahead of any other advisory. Remove the version, pin a clean one, and treat any machine or pipeline that installed it as compromised.
  • publisher or maintainer drift

The offline first pass stays useful on its own. Advisory matches only need an exact pinned version, so floating ranges and unpinned dependencies are reported by the dependency and lockfile trust checks instead.

Secret detection and validation​

Dralvia scans committed files for exposed credentials. There are two detection paths:

  • Known-format detectors match the exact shape of a credential type (for example private keys, AWS keys, GitHub, GitLab, Slack, Stripe, Google API keys, npm and PyPI tokens). These are reported with high confidence.
  • A generic key and value detector catches other assignments to names such as api_key, apiKey, token, secret or password. It understands key = value, key: value, "key": "value", key := value and 'key' => 'value'.

The generic detector only reports a value, never a name that points at one:

  • In programming-language files (Python, JavaScript and TypeScript, Java, Kotlin, Go, Rust, Ruby, PHP, C#, Swift, C and C++, Terraform and others) a credential can only be written as a string literal. An unquoted right-hand side is code, so api_key=os.environ.get("API_KEY"), apiKey: process.env.API_KEY, self.token = token and the type hint api_key: Optional[str] = None are not reported. API_KEY = "…", token = b'…' and apiKey = `…` are.
  • In configuration, shell and documentation files (.env, YAML, INI, .properties, shell scripts, Markdown, text) unquoted values are still checked, because API_KEY=abc123… is a real literal there. Dotted names (process.env.API_KEY, var.db_password) and values followed by ( or [ are treated as references.
  • Templates and interpolations (f"key_{suffix}", `${token}`), placeholders written as constant names (CHANGE_THIS_TO_YOUR_API_KEY), single words, and hyphenated words (workspace-admin) are not reported.
  • A remaining candidate must look random (Shannon entropy) and mix at least two of lower-case letters, upper-case letters and digits.

Every secret finding carries a confidence level and the validation method that confirmed it, and the result summary groups secrets by type, severity, and confidence. Dralvia never stores or shows the secret value itself, only a salted hash, the file, and the line.

Known limits of the generic detector:

  • A credential in a code comment written without quotes (# api_key=…) is not reported. Known-format credentials are still found anywhere.
  • The name must end with the keyword: DATABASE_API_KEY and client_secret are checked; SECRET_KEY is not, unless the value has a known format.
  • Quoted test fixtures that look random (for example password: "TenantAdmin!42") are reported. The scanner cannot know a value is fake. Suppress them with a reason.

IP address references​

Dralvia reports a file that hard-codes an IP address as suspicious_ip (low severity). The finding names the first address, its line, and how many distinct addresses the file contains.

A dotted number counts as an address only when all of these hold:

  • it is a whole token with four octets from 0 to 255, not part of a longer number (1.3.6.1.4.1 OIDs, 1.2.3.4.5) and not glued to a word (v1.2.3.4)
  • it is not in a version or clause position: "version": "1.2.3.4", AssemblyVersion("1.0.0.0"), <Version>, pkg==1.2.3.4, Chrome/120.0.6099.109, section 4.4.2.2, §4.2.10.2
  • it is not SVG geometry. Values of d, points, viewBox, transform and pathData are ignored in SVG files, JSX, compiled bundles and escaped JSON, because compact path syntax writes 1.5 .5 .5 as 1.5.5.5. A <script> inside an SVG is still checked.
  • it can name a host. Loopback (127.0.0.1), 0.0.0.0/8, multicast, reserved ranges and netmasks (255.255.255.0), and the documentation ranges 192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24 are ignored.

Private network ranges and link-local addresses are still reported. A hard-coded internal host, or a cloud metadata address, is worth a look in a repository.

Provenance and release linkage​

Dralvia reviews provenance files and release trust signals, then compares them with:

  • release workflows
  • committed release artifacts
  • attested subjects in provenance records

This helps your team tell whether a release output appears traceable back to reviewed source, or whether the release chain is still weak or incomplete.

What you will see in the result​

A completed scan can include these sections:

  • risk score and risk level
  • findings
  • projects and workspaces
  • findings by family
  • dependency graph by project
  • execution paths and release chains
  • workflow and IaC risk packs
  • binary and generated artifact review
  • provenance
  • controlled enrichment
  • release artifact linkage
  • merge and release recommendation
  • engineering handoff
  • AppSec handoff

What the recommendation means​

The repo scanner can return a CI-style recommendation:

  • pending The scan is still running. No verdict, risk score, or gate decision exists yet, so nothing should be treated as passed or failed.
  • pass Use this when the scan did not find a current reason to block trust.
  • review Use this when a human should review before merge or release.
  • fail Use this when blocking issues were found and the repository should not be promoted until they are fixed or explicitly accepted through your review process.

While a scan is running, the result page shows a "Repository review in progress" state. The risk score, findings count, and gate decision appear only when the scan reaches its final state.

This recommendation is there to reduce guesswork. It is meant to help engineering and security teams act faster without manually translating every raw finding into a release decision.

Step-by-step​

  1. Sign in to the Dralvia workspace.
  2. Open Repository Risk Scanner.
  3. Upload a .zip of the repository you want to review.
  4. Add repository context if you want drift tracking and clearer exports:
    • provider
    • owner or org
    • repo name
    • branch, tag, or ref
    • commit SHA
    • pull request or change request
  5. Choose the review profile your team wants to use for CI gate behavior, if available.
  6. Start the scan.
  7. If nothing has been submitted yet, the page shows an explicit empty state instead of an empty result area. Once the review starts, the platform switches to a shared processing state.
  8. Wait for the scan to complete and review the result sections in order:
    • verdict, risk score, and gate recommendation
    • top reasons
    • trust / provenance summary
    • recommended next step
    • highest-risk findings
    • affected projects
    • dependency and provenance sections
    • release artifact linkage
  9. Export what your downstream process needs:
    • JSON
    • SARIF
    • SBOM
    • provenance
    • gate output
    • ticket summary
    • signed manifest, when available

The export manifest carries an artifacts_merkle_root: a tamper-evident anchor computed from the per-artifact SHA-256 digests. You can recompute it yourself from the manifest's artifact list, with no Dralvia secret, to confirm that no exported artifact was altered, added, or removed. It sits alongside the manifest's Dralvia signature.

How to read the most important sections​

Findings​

This is the direct issue list. Start here if you want the fastest view of what triggered the result.

Verdict-first summary​

Use the first screen to get the fastest operational read:

  • verdict headline and risk score
  • top reasons
  • trust and provenance chips
  • recommended next step
  • processing snapshot

This summary is presentation-only. It does not remove the deeper repo, dependency, provenance, release-linkage, or finding sections lower on the page.

If the backend returns degraded or unknown coverage, the first screen now also shows a partial-result banner. Treat that as a bounded review, not as a fully clean final answer.

Projects and workspaces​

Use this when a monorepo contains many parts and you need to know which project actually carries the risk.

Dependency graph by project​

Use this to understand the dependency surface, especially when multiple projects share packages or ecosystems.

Execution paths and release chains​

Use this to find install, build, CI, and release paths that could execute automatically or affect what gets shipped.

Controlled enrichment​

Use this to review package advisories and publisher drift when Dralvia was able to enrich the scan with outside registry intelligence.

Release artifact linkage​

Use this when your question is:

Can I trust that the shipped artifact is tied back to the source I reviewed?

This section is especially important if your team uses signed provenance or release workflows and wants more than a simple “provenance file exists” answer.

Engineering handoff and AppSec handoff​

Use these when you want a quick next-step summary without reading the full raw result first.

The ticket summary also carries an evidence handoff block. It links the EvidencePack (Dralvia's exportable evidence report) for the scan (when one exists) and the export pointers for SARIF, SBOM, the gate, the CI gate, and the export manifest. So when you export only the ticket summary and paste it into an issue, engineering and AppSec can still jump straight to the durable evidence and signed artifacts.

API​

Main routes:

  • POST /repo/scan/upload
  • GET /repo/scan/<id>
  • GET /repo/scan/<id>/ci-gate

CI gate endpoint​

GET /repo/scan/<id>/ci-gate returns just the canonical gate verdict for a stored scan, so a CI job does not have to parse the full scan detail or the EvidencePack. The response includes:

  • decision: pass, review, fail, or pending while the scan is still running
  • should_block_merge and requires_security_review
  • profile, available_profiles, and summary
  • the blocking and warning findings, and recommended actions

Add ?profile=advisory, ?profile=balanced, or ?profile=fail_closed to evaluate the same scan under a chosen policy without changing the profile recorded at scan time. Use this in a pipeline step that maps decision to a pass or fail exit, and pick fail_closed when degraded or unknown scans should also block the merge.

Depending on the scan result and your permissions, you may also use export routes for:

  • SARIF
  • SBOM
  • provenance
  • suppression
  • CI gate
  • ticket summary
  • manifest

Your workspace session normally sends the right context automatically in the product UI. For direct API use, keep requests workspace-scoped and authenticated.

Verified remediation (rescan to close)​

A finding's review state (pending, confirmed_risk, needs_followup, accepted_noise) is a claim your team makes. Rescanning the same repository turns that claim into proof.

POST /repo/scan/<id>/reconcile compares the scan against the previous scan of the same repository (matched by its stable repository identity) and reclassifies each finding from the delta:

  • Fixed → verified_remediated. A finding that was live in the previous scan and is gone from this one is proven fixed. This status is system-set — the manual review endpoints cannot assign it, so "verified" always means a rescan earned it.
  • Still present → unchanged. A finding that is still in the current scan keeps its review state.
  • Regressed → reopened. A finding you previously proved fixed (verified_remediated) that reappears in the current scan is a regression: the fix was reverted. It is reopened (also system-set) with evidence.
  • Suppressed / accepted → left alone. A suppressed finding that disappears is not auto-closed, and one that reappears is not reopened — you accepted it on purpose.

The response reports verified (fixed) and reopened (regressed) fingerprint lists with counts, plus a diff block (previous_finding_count, current_finding_count, gone_fingerprints, regressed_fingerprints) as the evidence behind each transition. Each transition also appends a dated event (verified_remediated or reopened, with the previous and current scan ids) to the finding's review history.

Reconcile is idempotent: running it again finds nothing new to close or reopen. If the repository has no prior scan, or no stable repository identity, reconcile returns a safe no-op rather than guessing.

Rate limits and billing​

Current workspace-facing behavior:

  • evaluation-lane workspaces: 3 repo scans per 24 hours
  • if the limit is exceeded, the API returns 429 with a billing warning
  • PAYG workspaces are metered and see billing warnings in the product

If your team expects sustained CI usage, monitor usage and request a quota review before you hit routine limits.

Practical advice before uploading​

  • include your workflow files such as .github/workflows/*.yml or .gitlab-ci.yml
  • include the parts of the repo that define release behavior
  • do not remove suspicious scripts just to make the scan faster
  • if release trust matters, keep release artifacts and provenance files in the archive so Dralvia can compare them
  • provide provider, repo, ref, and commit metadata when you can

Troubleshooting​

The result is taking longer than expected​

Large monorepos, richer dependency graphs, and deeper provenance or enrichment review can take longer than tiny ZIP uploads. Wait for the scan to finish before assuming the result is empty or broken. While the scan runs, the page shows an in-progress state instead of a verdict.

The scan failed​

A failed scan shows a plain-language message and one of these error codes:

  • invalid_archive The upload could not be read as a valid repository ZIP. Re-create the archive and upload it again.
  • scan_data_unavailable The scan lost access to the uploaded archive while running. Upload the archive again to start a new scan.
  • repo_scan_failed The scan stopped before a result was produced. Run the scan again.

If the same failure repeats, contact support with your workspace ID and scan ID.

A scan stayed in progress and then failed​

If a scan stops reporting progress, we restart it automatically. A scan is restarted at most five times; after that it is marked failed, and the message says how many attempts were made. We stop rather than retry forever, so that a scan which cannot finish shows you a result instead of staying in progress indefinitely. Upload the archive again to start a new scan.

I do not understand why the scan says review​

Start from these sections in this order:

  1. merge and release recommendation
  2. blockers and warnings
  3. execution paths and release chains
  4. controlled enrichment
  5. release artifact linkage

That order usually explains the result faster than reading the full finding list top to bottom.

I expected a clean result, but Dralvia found risk​

That does not always mean the repository is malicious. It can also mean:

  • unsafe release automation
  • overpowered CI workflows
  • weak lockfile discipline
  • provenance that exists but does not link back clearly
  • package metadata drift that needs human review

I need to escalate this internally​

Capture:

  • workspace ID
  • scan ID

Who this is for​

  • Workspace admins and engineering managers reviewing third-party or internal repositories.
  • AppSec reviewers and security analysts who need release or merge guidance.
  • Platform teams that want CI-ready repository trust decisions.

Role-based start here​

  • Engineering manager: start with Step-by-step, then read FAQ and Next best actions.
  • AppSec reviewer: start with Before you start, then focus on API and automation and Troubleshooting.
  • Security analyst: start with Day-2 operations, then inspect the key result sections.

Before you start​

  1. Confirm you have the right repository ZIP and relevant workflow or provenance files.
  2. Confirm you can provide provider, repo, ref, and commit metadata if drift tracking matters.
  3. Confirm the workspace still has scan quota available for the review window.

Day-2 operations​

  1. Re-scan after important dependency, CI, or release changes.
  2. Compare current results with prior drift or release-linkage output.
  3. Export findings and provenance evidence when a human approval gate is required.

Self-check playbook​

  1. Confirm the uploaded archive contains the real workflow, release, and lockfile paths.
  2. Confirm the repository metadata matches the code snapshot you intended to review.
  3. Confirm your team is reading the recommendation together with the highest-risk finding families.
  4. Retry or rescan when a previous upload was incomplete or used the wrong ref.

What each button does​

  • Upload or Start scan: submits the repository archive for review.
  • Refresh: reloads scan progress or the latest completed result.
  • Export actions: download SARIF, SBOM, provenance, manifest, or ticket-handoff outputs when available.

API and automation​

  • POST /repo/scan/upload
  • GET /repo/scan/<id>
  • related export routes for SARIF, SBOM, provenance, suppression, CI gate, ticket summary, and manifest

Next best actions​

Related guides:

  • Pre-sign review

  • EvidencePack verification

  • TicketBridge handoff

  • If the result is review, start with execution paths, release chains, and provenance next.

  • If the result is fail, block promotion until the highest-risk findings are fixed or explicitly accepted.

  • If the result is pass, preserve the scan ID and exports for release evidence next.

FAQ​

Why did a repository get review instead of fail?​

Review means a human should check the result before promotion, but the current evidence was not strong enough to hard-block automatically.

Does a clean provenance file guarantee a clean result?​

No. Dralvia also evaluates CI behavior, release linkage, lockfiles, dependencies, and execution paths.

Next steps​

  1. Export the result format your downstream process needs.
  2. Hand off engineering and AppSec remediation items.
  3. Re-scan after remediation or before release promotion.
  • UTC time
  • repo context fields you provided
  • the exact gate decision
  • the export or screenshot you want reviewed

API error quick reference​

ErrorMeaningWhat to do now
401 UnauthorizedSession token is missing, expired, or invalid.Sign out and back in, then retry once.
403 ForbiddenYour role is authenticated but not allowed to use this action.Ask your workspace admin to grant the required permission.
404 Not FoundThe scan, route, or export was not found in the current workspace context.Confirm workspace context and scan ID, then retry.
429 Too Many RequestsYour rate limit or quota window was exceeded.Wait for cooldown, then retry with backoff.
500 Internal Server ErrorThe backend failed unexpectedly.Retry after a short wait. If it repeats, escalate with scan ID and UTC time.

Failed scans also carry a result-level error code (invalid_archive, scan_data_unavailable, or repo_scan_failed) with a plain-language message; see the Troubleshooting section above.

Best next actions after a scan​

After you review the result, pick the next step that matches your team:

  • engineering team: use the ticket summary and fix guidance
  • AppSec team: start from blockers, workflow packs, and provenance
  • CI owner: use the gate output and policy profile
  • audit or compliance owner: use the provenance export, signed manifest, and EvidencePack when available

Known limits and rate limits​

  • Plan quotas apply: scan, render, report, repository, and API-key limits follow your plan tier. See Pricing & Plans for the enforced defaults.
  • API requests are rate limited per workspace. A 429 Too Many Requests response means a rate or quota window was exceeded; wait for the reset window, then retry once and reduce burst volume.
  • Free Evaluation has the tightest limits and is subject to anti-abuse controls. Paid plans raise the limits; Enterprise sets custom limits by contract.