Use when classifying Projects as CLI-scanned (local endorctl) vs Cloud-scanned
(agentless SCM integrations) via spec.git.external_installation_id. Tenant-wide
runs emit CSV with installation names from Installation rows. Not for listing
findings or scan pipeline diffs (hand off to sibling skills).
Instalación
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Use when classifying Projects as CLI-scanned (local endorctl) vs Cloud-scanned
(agentless SCM integrations) via spec.git.external_installation_id. Tenant-wide
runs emit CSV with installation names from Installation rows. Not for listing
findings or scan pipeline diffs (hand off to sibling skills).
CLI vs Cloud project classification
Cloud projects are registered through Endor Labs SCM integrations (GitHub app, Bitbucket app, Azure DevOps, and similar). Scans are agentless — Endor Labs pulls source from the connected installation without a local endorctl scan on customer infrastructure.
CLI projects are created and scanned via endorctl (or API ingestion from local/CI runs). They do not carry an SCM app installation id on the Project row.
Scope
In scope
Tenant-wide or single-project classification via the bundled script.
Resolve spec.git.external_installation_id on each Project row.
Resolve the human-readable Installation.meta.name (with spec.login when needed) by matching Installation.spec.external_id to the project installation id.
Emit the standard CSV on every run and summarize results in chat.
Match external_installation_id to Installation.spec.external_id (tenant-wide Installation.list(traverse=True)). Use Installation.meta.name for the CSV installation name column; when spec.login is also set, format as meta.name (login) for disambiguation (common for multiple Azure installations).
Related signals (Cloud only):
Field
Meaning
spec.git.invalid_installation
SCM installation was removed; Endor cannot refresh or rescan this Cloud project
spec.git.http_clone_url
May be set on Cloud projects for clone during agentless scan
Do not infer Cloud vs CLI from repository URL alone — the same repo URL can exist as separate Project rows (different namespaces or registration paths).
SDK helpers:client.Project.is_app(project), is_cli(project), and is_sbom(project) accept a Project model or masked dict row. Map to CSV source (registration): is_app → Cloud Scan, else CLI (skip SBOM rows with is_sbom).
Latest scan execution: The bundled script also looks up the newest ScanResult per project (ScanResult.list_by_project, mask=spec.environment.config.RunBySystem) and maps RunBySystem to latest scan execution (CLI / Cloud Scan / unknown). mixed mode is true when registration and latest scan execution disagree — common when app-registered repos still run endorctl scan in CI.
Per-scan execution (API): Filter spec.environment.config.RunBySystem on ScanResult (KB: CLI vs app-based scans).
CSV schema (required)
Write CSV with exactly these eight columns, in this order, on every run:
Column
Source
project name
Project.meta.name
namespace
Project.tenant_meta.namespace
uuid
Project.uuid
source
Registration: CLI or Cloud Scan only
latest scan execution
Newest ScanResult.spec.environment.config.RunBySystem → CLI, Cloud Scan, or unknown
mixed mode
true when source ≠ latest scan execution (both known)
external_installation_id
Project.spec.git.external_installation_id (empty for CLI)
installation name
Resolved from Installation via spec.external_id; empty for CLI
Header row (literal):
project name,namespace,uuid,source,latest scan execution,mixed mode,external_installation_id,installation name
Exclude SBOM projects (spec.sbom set) from the scan and CSV.
After endorlabs.init(), scripts live under agent-knowledge/workflow-reports/endor-cli-vs-cloud-projects/scripts/ (SDK repo maintainers: agent-knowledge/workflow-reports/…).
Step 2: Summarize in chat (required)
Always report to the user:
Tenant, total projects classified, SBOM excluded count.