{"record":{"id":"5ba39b5834be4c18","repo":"coleam00/Archon","slug":"untrusted-source-url-for-slug-entry-source","errorCode":null,"errorMessage":"Untrusted source URL for '${slug}': ${entry.sourceUrl}\nOnly github.com sources are permitted.","messagePattern":"Untrusted source URL for '(.+?)': (.+?)\nOnly github\\.com sources are permitted\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/workflow.ts","lineNumber":5151,"sourceCode":"  return res.text();\n}\n\nexport async function workflowInstallCommand(\n  slug: string,\n  cwd: string,\n  force?: boolean\n): Promise<void> {\n  const entries = await fetchMarketplace();\n  const entry = entries.find(e => e.slug === slug);\n\n  if (!entry) {\n    console.error(`Error: Workflow '${slug}' not found in marketplace.`);\n    console.error(\"Run 'archon workflow search' to browse available workflows.\");\n    throw new Error(`Workflow '${slug}' not found`);\n  }\n\n  if (!entry.sourceUrl.startsWith('https://github.com/')) {\n    throw new Error(\n      `Untrusted source URL for '${slug}': ${entry.sourceUrl}\\nOnly github.com sources are permitted.`\n    );\n  }\n\n  if (!/^[a-z0-9-]+$/.test(slug)) {\n    throw new Error(`Invalid slug '${slug}': must be lowercase alphanumeric with hyphens only.`);\n  }\n\n  const { findRepoRoot } = await import('@archon/git');\n  const repoRoot = await findRepoRoot(cwd);\n  if (!repoRoot) {\n    throw new Error('Not in a git repository. Run archon workflow install from within a git repo.');\n  }\n\n  const { existsSync, mkdirSync, writeFileSync } = await import('node:fs');\n  const archonDir = join(repoRoot, '.archon');\n\n  if (isDirectoryUrl(entry.sourceUrl)) {","sourceCodeStart":5133,"sourceCodeEnd":5169,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/cli/src/commands/workflow.ts#L5133-L5169","documentation":"Security guard on the install path: the marketplace entry's `sourceUrl` must start with `https://github.com/` before the command will parse and download from it. Prevents a tampered or malicious marketplace index from making Archon fetch workflow YAML from arbitrary hosts.","triggerScenarios":"`workflowInstallCommand` resolves a slug whose marketplace entry has a `sourceUrl` not beginning with `https://github.com/` — e.g. `https://gitlab.com/...`, `http://` (non-TLS), `https://raw.githubusercontent.com/...`, or a relative/garbage URL.","commonSituations":"Custom/self-hosted marketplace index listing non-GitHub sources; an entry hand-edited to a raw.githubusercontent URL; HTTP URL in a hand-written index; a compromised or third-party index attempting SSRF-style redirection.","solutions":["Change the entry's sourceUrl to a normal `https://github.com/<owner>/<repo>(/tree/<ref>/<path>)` URL","If you genuinely need non-GitHub hosting, that is unsupported — mirror the workflow in a GitHub repo","Verify the marketplace index you point the CLI at is the trusted one","Re-fetch the official marketplace index if a tampered one was configured"],"exampleFix":"// before\n\"sourceUrl\": \"https://raw.githubusercontent.com/acme/workflows/main/review.yaml\"\n// after\n\"sourceUrl\": \"https://github.com/acme/workflows/tree/main/review-dir\"","handlingStrategy":"validation","validationCode":"if (!entry.sourceUrl.startsWith('https://github.com/')) {\n  throw new Error(`Refusing non-GitHub source: ${entry.sourceUrl}`);\n}","typeGuard":"function isGithubSourceUrl(url: string): boolean {\n  try {\n    const u = new URL(url);\n    return u.protocol === 'https:' && u.hostname === 'github.com';\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  await workflowInstallCommand(slug);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Untrusted source URL')) {\n    // inspect the marketplace entry and correct its sourceUrl\n  } else throw e;\n}","preventionTips":["Only use trusted, official marketplace indexes","Audit custom index files for non-github.com sourceUrls before use","Keep entries in canonical `https://github.com/<owner>/<repo>...` form","Treat this error as a possible sign of a tampered index"],"tags":["security","url-validation","marketplace","ssrf-guard"],"backgroundTag":"untrusted-source-url","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}