Skip to content
Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace
FirstSeen — verify before agents execute

A pre-execution trust gate for AI-suggested software resources.

CI Marketplace License Node

Quick start · How it works · Policy · Threat model · Contributing


AI coding agents can invent plausible package names, repository URLs, skills, and actions. An attacker can register those names and wait for an agent to fetch and execute them. FirstSeen inserts a deterministic checkpoint before that happens.

- uses: Abhinav0905/firstseen@v0.1.0
  with:
    path: '.'
    format: sarif
    output: firstseen.sarif
VERDICT  RESOURCE                           SCORE  SIGNAL
───────  ─────────────────────────────────  ─────  ────────
■ BLOCK  github-action:actions/checkout@v4  55     FS004
● PASS   npm:lodash@4.17.21                 100    verified

FirstSeen asks more than “does it exist?” It checks whether a resource is old enough, whether it existed before a chosen trust boundary, whether the requested version or ref exists, and whether executable references are immutable.

Registry metadata is a review signal, not proof that software is safe. FirstSeen complements—not replaces—malware analysis, vulnerability scanning, signatures, code review, and sandboxing.

Why now?

The 2026 HalluSquatting research demonstrated that hallucinated resource identifiers can be predictable and transferable across models, with reported hallucination rates up to 85% in repository cloning scenarios and 100% in some skill-installation scenarios. The authors demonstrated remote tool execution and remote code execution against production agent applications.

This extends an already measured software-supply-chain problem: a USENIX Security 2025 Distinguished Paper generated 576,000 code samples and found average package-hallucination rates of at least 5.2% for commercial models and 21.7% for open-source models, including 205,474 unique nonexistent package names.

FirstSeen turns that research into a small, composable control developers can run locally, in an agent toolchain, or at the pull-request boundary.

What makes FirstSeen different?

  • Temporal provenance. knownBefore flags a resource that appeared after a model, prompt, or review boundary—when simple “exists now” checks can be defeated by squatting.
  • Pre-execution. Scan an AI response, README, agent instruction, shell script, manifest, workflow, or explicit resource before install or execution.
  • Cross-ecosystem. npm, PyPI, crates.io, Go modules, GitHub repositories, GitHub Actions, and Docker Hub images share one policy and report format.
  • Immutable-reference checks. Block mutable GitHub Action refs; optionally require container digests.
  • CI-native evidence. Terminal, JSON, Markdown, standalone HTML, and SARIF 2.1.0 output.
  • Local-first. No account, API key, telemetry, uploaded source, or LLM call. Registry responses are cached locally for six hours.
  • Embeddable. Use the CLI or import the typed TypeScript API.

Quick start

Requires Node.js 20 or newer.

GitHub Action

Install the current release from GitHub Marketplace:

- uses: Abhinav0905/firstseen@v0.1.0
  with:
    path: '.'
    format: sarif
    output: firstseen.sarif
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CLI from source

git clone https://github.com/Abhinav0905/firstseen.git
cd firstseen
npm ci
npm run build

# Scan a repository
node dist/cli.js scan /path/to/repository

# Check references before running an AI-generated command
node dist/cli.js check npm:express@5.1.0 pypi:requests==2.32.4

# Pipe an agent response into the scanner
pbpaste | node dist/cli.js scan -

# Add policy and GitHub workflow files
node dist/cli.js init

The npm distribution is intentionally not advertised until trusted publishing is configured and the package is live on the registry.

Exit code 0 means no finding met the configured failure threshold, 1 means policy failed, and 2 means the CLI itself could not run.

How it works

flowchart LR
  A["Code, config, docs, or agent output"] --> B["Deterministic reference extraction"]
  B --> C["Canonical registry lookup"]
  C --> D["Temporal + immutability policy"]
  D --> E["PASS"]
  D --> F["REVIEW"]
  D --> G["BLOCK"]
  E --> H["Terminal / JSON / Markdown / HTML / SARIF"]
  F --> H
  G --> H
Loading
  1. Extract software references and their file/line locations without executing the input.
  2. Query the canonical registry with bounded timeouts and retries, or use cached evidence offline.
  3. Evaluate existence, age, the knownBefore boundary, version/ref resolution, archive state, and pinning rules.
  4. Emit a stable report for people, automation, or GitHub code scanning.

See Architecture for component and extension details.

Supported resources

Resource Examples detected Evidence source
npm package.json, npm install, npx, pnpm, Yarn npm registry
PyPI requirements files, pyproject.toml, pip, uv, Poetry PyPI JSON API
crates.io Cargo.toml, cargo add crates.io API
Go go.mod Go module proxy
GitHub repository URLs and explicit checks GitHub API
GitHub Actions uses: owner/repo@ref GitHub API + commit resolution
Containers Dockerfile FROM and explicit checks Docker Hub API

The extractor scans common source, configuration, shell, and documentation formats. Files larger than 2 MB, symlinks, binary formats, generated output, and ignored paths are skipped.

Policy

.firstseen.yml is deliberately small:

version: 1
policy:
  minimumAgeDays: 30
  # Optional: a model cutoff, session start, or review boundary.
  knownBefore: '2026-07-01T00:00:00Z'
  requirePinnedActions: true
  requirePinnedContainers: false
  minimumGitHubStars: 0
  onUnverifiable: review # pass | review | block
  failOn: high # info | low | medium | high | critical
  allow:
    - 'npm:@my-company/*'
  ignore:
    - '**/node_modules/**'
    - '**/fixtures/**'

knownBefore is the core HalluSquatting control. If an AI response was generated on July 1 and a referenced repository was created on July 3, “the repository exists” is not enough; FirstSeen emits FS006 and blocks it.

Temporal rules apply only when the canonical provider exposes a reliable creation timestamp. The current Go module proxy provider verifies module and version existence but does not expose project creation time, so FS002 and FS006 are not evaluated for Go modules.

Allow rules are exact or * wildcard resource IDs. Keep them narrow and review them like executable policy. See Rules for every signal and remediation.

GitHub Actions

Use this repository as a composite action:

- uses: Abhinav0905/firstseen@v0.1.0
  with:
    path: '.'
    format: sarif
    output: firstseen.sarif
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Or build the CLI from source and upload SARIF to GitHub code scanning. node dist/cli.js init creates a full workflow you can edit.

Reports

node dist/cli.js scan . --format json --output firstseen.json
node dist/cli.js scan . --format markdown --output firstseen.md
node dist/cli.js scan . --format html --output firstseen.html
node dist/cli.js scan . --format sarif --output firstseen.sarif
node dist/cli.js scan . --offline

The HTML format is a single portable file with no scripts, remote assets, or tracking. SARIF findings include stable rule IDs and physical source locations.

Library API

import {
  createRegistryProviders,
  defaultPolicy,
  parseExplicitReference,
  scanResources,
} from 'firstseen';

const report = await scanResources(
  [parseExplicitReference('npm:lodash@4.17.21')],
  defaultPolicy,
  createRegistryProviders(),
  { cwd: process.cwd() },
);

All public report, policy, resource, evidence, and provider types are exported.

What FirstSeen does not claim

FirstSeen does not determine whether an existing package is benign, whether an old account was compromised, or whether a pinned artifact contains malware. Resource age and popularity can help triage; neither is a security guarantee. Read the threat model before using FirstSeen as a required control.

Research basis

FirstSeen is an independent open-source implementation and is not affiliated with the authors or organizations above.

Contributing

Good first contributions include new fixture cases, parsers for additional manifests, registry providers, and research-backed policy rules. Start with CONTRIBUTING.md and the roadmap.

Please report suspected vulnerabilities privately according to SECURITY.md.

License

Apache-2.0 © 2026 Kumar Abhinav. See LICENSE.

About

Verify AI-suggested packages, repos, Actions, and containers before execution.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages