Sign In

@openai/codex-security

Package Overview
Dependencies
Maintainers
17
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openai/codex-security - npm Package Compare versions

Comparing version
0.1.2
to
0.1.3
+1
-1
_bundled_plugin/scripts/deep_scan_workbench.py

@@ -242,3 +242,3 @@ """Persist deterministic Codex Security Deep Scan orchestration state."""

raise SystemExit(f"{label} must be an existing path inside the scan directory.") from exc
if resolved != supplied.absolute():
if os.path.normcase(resolved) != os.path.normcase(supplied.absolute()):
raise SystemExit(f"{label} must be a canonical non-symlink path.")

@@ -245,0 +245,0 @@ if kind == "file" and not resolved.is_file():

@@ -98,14 +98,13 @@ import { execFile as execFileCallback } from "node:child_process";

async function selectGitHubOwner(github, prompt, signal) {
const { data } = await github.request("GET /user/orgs", {
per_page: 100,
request: { signal },
});
const organizations = data.map(({ login }) => login).sort();
if (organizations.length > 1) {
return await prompt.select("Which account or organization should we scan?", organizations.map((owner) => ({ label: owner, value: owner })));
const [orgs, user] = await Promise.all([
github.request("GET /user/orgs", { per_page: 100, request: { signal } }),
github.request("GET /user", { request: { signal } }),
]);
const personal = user.data.login;
const owners = [personal, ...orgs.data.map(({ login }) => login)].sort();
if (owners.length > 1) {
return await prompt.select("Which account or organization should we scan?", owners.map((owner) => ({ label: owner, value: owner })));
}
const owner = organizations[0] ??
(await github.request("GET /user", { request: { signal } })).data.login;
prompt.write(`\nFinding repositories in ${owner}.\n`);
return owner;
prompt.write(`\nFinding repositories in ${personal}.\n`);
return personal;
}

@@ -112,0 +111,0 @@ async function selectGitHubRepositories(repositories, prompt) {

@@ -1,1 +0,1 @@

{"version":3,"file":"bulk-scan-discovery.js","sourceRoot":"","sources":["../src/bulk-scan-discovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as execFileCallback } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { lstat, mkdir, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { stdin } from \"node:process\";\nimport { Writable } from \"node:stream\";\nimport { promisify } from \"node:util\";\nimport { confirm, input, search } from \"@inquirer/prompts\";\nimport { Octokit } from \"@octokit/core\";\nimport Papa from \"papaparse\";\nimport { resolveTrustedExecutable } from \"./trusted-executable.js\";\n\nconst execFile = promisify(execFileCallback);\nconst GITHUB_REPOSITORIES_QUERY = `\n query($owner: String!, $cursor: String) {\n repositoryOwner(login: $owner) {\n repositories(\n first: 100\n after: $cursor\n isArchived: false\n isFork: false\n orderBy: { field: PUSHED_AT, direction: DESC }\n ) {\n nodes {\n nameWithOwner\n pushedAt\n defaultBranchRef { target { oid } }\n }\n pageInfo { hasNextPage endCursor }\n }\n }\n }\n`;\n\ninterface GitHubRepository {\n fullName: string;\n url: string;\n revision: string;\n}\n\ninterface GitHubRepositoriesResponse {\n repositoryOwner: {\n repositories: {\n nodes: Array<{\n nameWithOwner: string;\n pushedAt: string;\n defaultBranchRef: { target: { oid: string } } | null;\n }>;\n pageInfo: { hasNextPage: boolean; endCursor: string | null };\n };\n } | null;\n}\n\nexport interface BulkScanPrompt {\n isInteractive(): boolean;\n write(value: string): void;\n confirm(question: string, defaultValue?: boolean): Promise<boolean>;\n input(question: string, defaultValue?: string): Promise<string>;\n select<Value extends string>(\n question: string,\n options: readonly { label: string; value: Value }[],\n ): Promise<Value>;\n}\n\nexport interface BulkScanDiscoveryDependencies {\n prompt: BulkScanPrompt;\n now(): number;\n currentDirectory(): string;\n githubHost?: string;\n createGitHub(host: string, signal?: AbortSignal): Promise<Octokit>;\n}\n\nexport interface BulkScanWizardResult {\n inputPath: string;\n outputDir: string;\n githubHost: string;\n}\n\ninterface PromptOutput {\n write(value: string): unknown;\n readonly isTTY?: boolean;\n}\n\nexport function createBulkScanDiscoveryDependencies(options: {\n output: PromptOutput;\n now(): number;\n currentDirectory(): string;\n}): BulkScanDiscoveryDependencies {\n return {\n prompt: createTerminalPrompt(options.output),\n now: options.now,\n currentDirectory: options.currentDirectory,\n ...(process.env[\"GH_HOST\"]?.trim()\n ? { githubHost: process.env[\"GH_HOST\"].trim() }\n : {}),\n createGitHub: async (host, signal) => {\n const trusted = await resolveTrustedExecutable(\n \"gh\",\n process.env,\n options.currentDirectory(),\n );\n if (trusted === null) {\n throw new Error(\n \"GitHub CLI is required. Install gh and sign in first.\",\n );\n }\n\n let token: string;\n try {\n const { stdout } = await execFile(\n trusted.executable,\n [\"auth\", \"token\", \"--hostname\", host],\n { env: trusted.environment, signal },\n );\n token = stdout.trim();\n } catch {\n signal?.throwIfAborted();\n throw new Error(\n \"GitHub sign-in is required. Run 'gh auth login' first.\",\n );\n }\n return new Octokit({\n auth: token,\n ...(host === \"github.com\" ? {} : { baseUrl: `https://${host}/api/v3` }),\n });\n },\n };\n}\n\nexport async function runBulkScanWizard(\n dependencies: BulkScanDiscoveryDependencies,\n signal?: AbortSignal,\n): Promise<BulkScanWizardResult | null> {\n const { prompt } = dependencies;\n if (!prompt.isInteractive()) {\n throw new Error(\n \"Interactive repository selection requires a terminal. Provide a CSV with 'codex-security bulk-scan repositories.csv --output-dir ./security-scans'.\",\n );\n }\n signal?.throwIfAborted();\n\n const githubHost = dependencies.githubHost ?? \"github.com\";\n const github = await dependencies.createGitHub(githubHost, signal);\n const owner = await selectGitHubOwner(github, prompt, signal);\n prompt.write(\"\\nFinding active repositories...\\n\");\n const discovered = await discoverGitHubRepositories(\n github,\n githubHost,\n owner,\n dependencies.now() - 90 * 86_400_000,\n signal,\n );\n if (discovered.length === 0) {\n prompt.write(\"\\nNo repositories matched your selection.\\n\");\n return null;\n }\n\n prompt.write(`\\nFound ${discovered.length} repositories.\\n`);\n const repositories = await selectGitHubRepositories(discovered, prompt);\n\n const outputDir = resolve(\n dependencies.currentDirectory(),\n await prompt.input(\n \"Where should scan results be saved?\",\n \"./security-scans\",\n ),\n );\n const inputPath = join(outputDir, \"repositories.csv\");\n await validateWizardOutput(outputDir);\n prompt.write(\n `\\nReady to scan ${repositories.length} repositories?\\n` +\n `Results: ${outputDir}\\nRepository list: ${inputPath}\\n`,\n );\n if (!(await prompt.confirm(\"Start scanning?\"))) {\n prompt.write(\"\\nScan canceled.\\n\");\n return null;\n }\n signal?.throwIfAborted();\n\n await mkdir(outputDir, { recursive: true, mode: 0o700 });\n await writeFile(\n inputPath,\n `${Papa.unparse(\n repositories.map(({ fullName, url, revision }) => ({\n id: repositoryId(fullName),\n repository: url,\n revision,\n })),\n )}\\n`,\n { flag: \"wx\", mode: 0o600, ...(signal === undefined ? {} : { signal }) },\n );\n return { inputPath, outputDir, githubHost };\n}\n\nasync function selectGitHubOwner(\n github: Octokit,\n prompt: BulkScanPrompt,\n signal?: AbortSignal,\n): Promise<string> {\n const { data } = await github.request(\"GET /user/orgs\", {\n per_page: 100,\n request: { signal },\n });\n const organizations = data.map(({ login }) => login).sort();\n if (organizations.length > 1) {\n return await prompt.select(\n \"Which account or organization should we scan?\",\n organizations.map((owner) => ({ label: owner, value: owner })),\n );\n }\n const owner =\n organizations[0] ??\n (await github.request(\"GET /user\", { request: { signal } })).data.login;\n prompt.write(`\\nFinding repositories in ${owner}.\\n`);\n return owner;\n}\n\nasync function selectGitHubRepositories(\n repositories: GitHubRepository[],\n prompt: BulkScanPrompt,\n): Promise<GitHubRepository[]> {\n const selected = new Set<string>();\n while (selected.size < repositories.length) {\n const choice = await prompt.select(\n \"Select repositories to scan (type to filter)\",\n [\n {\n label: selected.size\n ? `Done (${selected.size} selected)`\n : `All ${repositories.length} repositories`,\n value: \"\",\n },\n ...repositories\n .filter(({ fullName }) => !selected.has(fullName))\n .map(({ fullName }) => ({ label: fullName, value: fullName })),\n ],\n );\n if (!choice) break;\n selected.add(choice);\n }\n return selected.size\n ? repositories.filter(({ fullName }) => selected.has(fullName))\n : repositories;\n}\n\nasync function discoverGitHubRepositories(\n github: Octokit,\n host: string,\n owner: string,\n cutoff: number,\n signal?: AbortSignal,\n): Promise<GitHubRepository[]> {\n const repositories: GitHubRepository[] = [];\n let cursor: string | null = null;\n\n do {\n signal?.throwIfAborted();\n const result: GitHubRepositoriesResponse = await github.graphql(\n GITHUB_REPOSITORIES_QUERY,\n { owner, cursor, request: { signal } },\n );\n const connection = result.repositoryOwner?.repositories;\n if (connection === undefined) {\n throw new Error(\"GitHub could not list repositories for this account.\");\n }\n\n for (const repository of connection.nodes) {\n if (Date.parse(repository.pushedAt) < cutoff) return repositories;\n if (repository.defaultBranchRef === null) continue;\n repositories.push({\n fullName: repository.nameWithOwner,\n url: `https://${host}/${repository.nameWithOwner}.git`,\n revision: repository.defaultBranchRef.target.oid.toLowerCase(),\n });\n }\n cursor = connection.pageInfo.hasNextPage\n ? connection.pageInfo.endCursor\n : null;\n } while (cursor !== null);\n\n return repositories;\n}\n\nfunction repositoryId(fullName: string): string {\n const id = fullName.replace(\"/\", \"--\");\n if (id.length <= 128) return id;\n const hash = createHash(\"sha256\").update(fullName).digest(\"hex\").slice(0, 16);\n return `${id.slice(0, 111)}-${hash}`;\n}\n\nasync function validateWizardOutput(outputDir: string): Promise<void> {\n let metadata;\n try {\n metadata = await lstat(outputDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n if (!metadata.isDirectory()) {\n throw new Error(\"The scan output must be a real directory.\");\n }\n\n for (const name of [\"repositories.csv\", \"manifest.json\"]) {\n try {\n await lstat(join(outputDir, name));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n throw error;\n }\n throw new Error(\n \"The selected output directory already contains a repository list or scan. Choose a new directory or resume the existing scan.\",\n );\n }\n}\n\nfunction createTerminalPrompt(output: PromptOutput): BulkScanPrompt {\n const context = () => ({\n input: stdin,\n output: new Writable({\n write(chunk: Buffer, _encoding, callback) {\n output.write(chunk.toString(\"utf8\"));\n callback();\n },\n }),\n });\n\n return {\n isInteractive: () => stdin.isTTY === true && output.isTTY === true,\n write: (value) => {\n output.write(value);\n },\n confirm: (message, defaultValue = false) =>\n confirm({ message, default: defaultValue }, context()),\n input: (message, defaultValue) =>\n input({ message, default: defaultValue }, context()),\n select: (message, options) =>\n search(\n {\n message,\n source: (term) =>\n options\n .filter(({ label }) =>\n label.toLowerCase().includes(term?.toLowerCase() ?? \"\"),\n )\n .map(({ label, value }) => ({ name: label, value })),\n },\n context(),\n ),\n };\n}\n"]}
{"version":3,"file":"bulk-scan-discovery.js","sourceRoot":"","sources":["../src/bulk-scan-discovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile as execFileCallback } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { lstat, mkdir, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport { stdin } from \"node:process\";\nimport { Writable } from \"node:stream\";\nimport { promisify } from \"node:util\";\nimport { confirm, input, search } from \"@inquirer/prompts\";\nimport { Octokit } from \"@octokit/core\";\nimport Papa from \"papaparse\";\nimport { resolveTrustedExecutable } from \"./trusted-executable.js\";\n\nconst execFile = promisify(execFileCallback);\nconst GITHUB_REPOSITORIES_QUERY = `\n query($owner: String!, $cursor: String) {\n repositoryOwner(login: $owner) {\n repositories(\n first: 100\n after: $cursor\n isArchived: false\n isFork: false\n orderBy: { field: PUSHED_AT, direction: DESC }\n ) {\n nodes {\n nameWithOwner\n pushedAt\n defaultBranchRef { target { oid } }\n }\n pageInfo { hasNextPage endCursor }\n }\n }\n }\n`;\n\ninterface GitHubRepository {\n fullName: string;\n url: string;\n revision: string;\n}\n\ninterface GitHubRepositoriesResponse {\n repositoryOwner: {\n repositories: {\n nodes: Array<{\n nameWithOwner: string;\n pushedAt: string;\n defaultBranchRef: { target: { oid: string } } | null;\n }>;\n pageInfo: { hasNextPage: boolean; endCursor: string | null };\n };\n } | null;\n}\n\nexport interface BulkScanPrompt {\n isInteractive(): boolean;\n write(value: string): void;\n confirm(question: string, defaultValue?: boolean): Promise<boolean>;\n input(question: string, defaultValue?: string): Promise<string>;\n select<Value extends string>(\n question: string,\n options: readonly { label: string; value: Value }[],\n ): Promise<Value>;\n}\n\nexport interface BulkScanDiscoveryDependencies {\n prompt: BulkScanPrompt;\n now(): number;\n currentDirectory(): string;\n githubHost?: string;\n createGitHub(host: string, signal?: AbortSignal): Promise<Octokit>;\n}\n\nexport interface BulkScanWizardResult {\n inputPath: string;\n outputDir: string;\n githubHost: string;\n}\n\ninterface PromptOutput {\n write(value: string): unknown;\n readonly isTTY?: boolean;\n}\n\nexport function createBulkScanDiscoveryDependencies(options: {\n output: PromptOutput;\n now(): number;\n currentDirectory(): string;\n}): BulkScanDiscoveryDependencies {\n return {\n prompt: createTerminalPrompt(options.output),\n now: options.now,\n currentDirectory: options.currentDirectory,\n ...(process.env[\"GH_HOST\"]?.trim()\n ? { githubHost: process.env[\"GH_HOST\"].trim() }\n : {}),\n createGitHub: async (host, signal) => {\n const trusted = await resolveTrustedExecutable(\n \"gh\",\n process.env,\n options.currentDirectory(),\n );\n if (trusted === null) {\n throw new Error(\n \"GitHub CLI is required. Install gh and sign in first.\",\n );\n }\n\n let token: string;\n try {\n const { stdout } = await execFile(\n trusted.executable,\n [\"auth\", \"token\", \"--hostname\", host],\n { env: trusted.environment, signal },\n );\n token = stdout.trim();\n } catch {\n signal?.throwIfAborted();\n throw new Error(\n \"GitHub sign-in is required. Run 'gh auth login' first.\",\n );\n }\n return new Octokit({\n auth: token,\n ...(host === \"github.com\" ? {} : { baseUrl: `https://${host}/api/v3` }),\n });\n },\n };\n}\n\nexport async function runBulkScanWizard(\n dependencies: BulkScanDiscoveryDependencies,\n signal?: AbortSignal,\n): Promise<BulkScanWizardResult | null> {\n const { prompt } = dependencies;\n if (!prompt.isInteractive()) {\n throw new Error(\n \"Interactive repository selection requires a terminal. Provide a CSV with 'codex-security bulk-scan repositories.csv --output-dir ./security-scans'.\",\n );\n }\n signal?.throwIfAborted();\n\n const githubHost = dependencies.githubHost ?? \"github.com\";\n const github = await dependencies.createGitHub(githubHost, signal);\n const owner = await selectGitHubOwner(github, prompt, signal);\n prompt.write(\"\\nFinding active repositories...\\n\");\n const discovered = await discoverGitHubRepositories(\n github,\n githubHost,\n owner,\n dependencies.now() - 90 * 86_400_000,\n signal,\n );\n if (discovered.length === 0) {\n prompt.write(\"\\nNo repositories matched your selection.\\n\");\n return null;\n }\n\n prompt.write(`\\nFound ${discovered.length} repositories.\\n`);\n const repositories = await selectGitHubRepositories(discovered, prompt);\n\n const outputDir = resolve(\n dependencies.currentDirectory(),\n await prompt.input(\n \"Where should scan results be saved?\",\n \"./security-scans\",\n ),\n );\n const inputPath = join(outputDir, \"repositories.csv\");\n await validateWizardOutput(outputDir);\n prompt.write(\n `\\nReady to scan ${repositories.length} repositories?\\n` +\n `Results: ${outputDir}\\nRepository list: ${inputPath}\\n`,\n );\n if (!(await prompt.confirm(\"Start scanning?\"))) {\n prompt.write(\"\\nScan canceled.\\n\");\n return null;\n }\n signal?.throwIfAborted();\n\n await mkdir(outputDir, { recursive: true, mode: 0o700 });\n await writeFile(\n inputPath,\n `${Papa.unparse(\n repositories.map(({ fullName, url, revision }) => ({\n id: repositoryId(fullName),\n repository: url,\n revision,\n })),\n )}\\n`,\n { flag: \"wx\", mode: 0o600, ...(signal === undefined ? {} : { signal }) },\n );\n return { inputPath, outputDir, githubHost };\n}\n\nasync function selectGitHubOwner(\n github: Octokit,\n prompt: BulkScanPrompt,\n signal?: AbortSignal,\n): Promise<string> {\n const [orgs, user] = await Promise.all([\n github.request(\"GET /user/orgs\", { per_page: 100, request: { signal } }),\n github.request(\"GET /user\", { request: { signal } }),\n ]);\n const personal = user.data.login;\n const owners = [personal, ...orgs.data.map(({ login }) => login)].sort();\n if (owners.length > 1) {\n return await prompt.select(\n \"Which account or organization should we scan?\",\n owners.map((owner) => ({ label: owner, value: owner })),\n );\n }\n prompt.write(`\\nFinding repositories in ${personal}.\\n`);\n return personal;\n}\n\nasync function selectGitHubRepositories(\n repositories: GitHubRepository[],\n prompt: BulkScanPrompt,\n): Promise<GitHubRepository[]> {\n const selected = new Set<string>();\n while (selected.size < repositories.length) {\n const choice = await prompt.select(\n \"Select repositories to scan (type to filter)\",\n [\n {\n label: selected.size\n ? `Done (${selected.size} selected)`\n : `All ${repositories.length} repositories`,\n value: \"\",\n },\n ...repositories\n .filter(({ fullName }) => !selected.has(fullName))\n .map(({ fullName }) => ({ label: fullName, value: fullName })),\n ],\n );\n if (!choice) break;\n selected.add(choice);\n }\n return selected.size\n ? repositories.filter(({ fullName }) => selected.has(fullName))\n : repositories;\n}\n\nasync function discoverGitHubRepositories(\n github: Octokit,\n host: string,\n owner: string,\n cutoff: number,\n signal?: AbortSignal,\n): Promise<GitHubRepository[]> {\n const repositories: GitHubRepository[] = [];\n let cursor: string | null = null;\n\n do {\n signal?.throwIfAborted();\n const result: GitHubRepositoriesResponse = await github.graphql(\n GITHUB_REPOSITORIES_QUERY,\n { owner, cursor, request: { signal } },\n );\n const connection = result.repositoryOwner?.repositories;\n if (connection === undefined) {\n throw new Error(\"GitHub could not list repositories for this account.\");\n }\n\n for (const repository of connection.nodes) {\n if (Date.parse(repository.pushedAt) < cutoff) return repositories;\n if (repository.defaultBranchRef === null) continue;\n repositories.push({\n fullName: repository.nameWithOwner,\n url: `https://${host}/${repository.nameWithOwner}.git`,\n revision: repository.defaultBranchRef.target.oid.toLowerCase(),\n });\n }\n cursor = connection.pageInfo.hasNextPage\n ? connection.pageInfo.endCursor\n : null;\n } while (cursor !== null);\n\n return repositories;\n}\n\nfunction repositoryId(fullName: string): string {\n const id = fullName.replace(\"/\", \"--\");\n if (id.length <= 128) return id;\n const hash = createHash(\"sha256\").update(fullName).digest(\"hex\").slice(0, 16);\n return `${id.slice(0, 111)}-${hash}`;\n}\n\nasync function validateWizardOutput(outputDir: string): Promise<void> {\n let metadata;\n try {\n metadata = await lstat(outputDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n }\n if (!metadata.isDirectory()) {\n throw new Error(\"The scan output must be a real directory.\");\n }\n\n for (const name of [\"repositories.csv\", \"manifest.json\"]) {\n try {\n await lstat(join(outputDir, name));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue;\n throw error;\n }\n throw new Error(\n \"The selected output directory already contains a repository list or scan. Choose a new directory or resume the existing scan.\",\n );\n }\n}\n\nfunction createTerminalPrompt(output: PromptOutput): BulkScanPrompt {\n const context = () => ({\n input: stdin,\n output: new Writable({\n write(chunk: Buffer, _encoding, callback) {\n output.write(chunk.toString(\"utf8\"));\n callback();\n },\n }),\n });\n\n return {\n isInteractive: () => stdin.isTTY === true && output.isTTY === true,\n write: (value) => {\n output.write(value);\n },\n confirm: (message, defaultValue = false) =>\n confirm({ message, default: defaultValue }, context()),\n input: (message, defaultValue) =>\n input({ message, default: defaultValue }, context()),\n select: (message, options) =>\n search(\n {\n message,\n source: (term) =>\n options\n .filter(({ label }) =>\n label.toLowerCase().includes(term?.toLowerCase() ?? \"\"),\n )\n .map(({ label, value }) => ({ name: label, value })),\n },\n context(),\n ),\n };\n}\n"]}

@@ -1,1 +0,1 @@

{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAC7D,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,SAAS,EAAE,GAAG,UAAU,CAAC;AACjE,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,UAAU,CAYrD,CAAC;AAIF,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC3B,sBAAsB,CAiBxB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAC7D,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,SAAS,EAAE,GAAG,UAAU,CAAC;AACjE,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,UAAU,CAgBrD,CAAC;AAIF,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC3B,sBAAsB,CAiBxB;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}

@@ -18,2 +18,6 @@ import { randomUUID } from "node:crypto";

},
// Named filesystem profiles need an active Windows sandbox backend.
windows: {
sandbox: "unelevated",
},
};

@@ -20,0 +24,0 @@ deepFreezeJson(DEFAULT_CODEX_CONFIG);

@@ -1,1 +0,1 @@

{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, open, rename, unlink } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { stringify } from \"smol-toml\";\nimport { ConfigurationError } from \"./errors.js\";\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonValue[] | JsonObject;\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\nexport interface CodexSecurityConfig {\n pluginPath?: string;\n codexOverrides?: JsonObject;\n pythonPath?: string;\n}\n\nexport interface ScanModelConfiguration {\n model: string;\n reasoningEffort: string;\n}\n\nexport const DEFAULT_CODEX_CONFIG: Readonly<JsonObject> = {\n cli_auth_credentials_store: \"file\",\n model: \"gpt-5.6-sol\",\n model_reasoning_effort: \"xhigh\",\n features: {\n plugins: true,\n goals: true,\n multi_agent_v2: {\n enabled: true,\n max_concurrent_threads_per_session: 9,\n },\n },\n};\n\ndeepFreezeJson(DEFAULT_CODEX_CONFIG);\n\nexport function scanModelConfiguration(\n config: Readonly<JsonObject>,\n): ScanModelConfiguration {\n const model = config[\"model\"];\n if (typeof model !== \"string\" || model.trim().length === 0) {\n throw new ConfigurationError(\n \"The configured Codex model must be a nonempty string.\",\n );\n }\n const reasoningEffort = config[\"model_reasoning_effort\"];\n if (\n typeof reasoningEffort !== \"string\" ||\n reasoningEffort.trim().length === 0\n ) {\n throw new ConfigurationError(\n \"The configured Codex reasoning effort must be a nonempty string.\",\n );\n }\n return { model, reasoningEffort };\n}\n\nexport async function mergedCodexConfig(\n config: CodexSecurityConfig,\n): Promise<JsonObject> {\n if (config.codexOverrides !== undefined && !isObject(config.codexOverrides)) {\n throw new ConfigurationError(\"codexOverrides must be an object.\");\n }\n validateOverrideKeys(config.codexOverrides ?? {});\n const overrides = cloneJson(config.codexOverrides ?? {});\n validateOverrides(overrides);\n validateNativeMultiAgentV2Overrides(overrides);\n return deepMerge(cloneJson(DEFAULT_CODEX_CONFIG), overrides);\n}\n\nexport async function writeCodexConfig(\n path: string,\n config: JsonObject,\n): Promise<void> {\n const parent = dirname(path);\n await mkdir(parent, { recursive: true, mode: 0o700 });\n let contents: string;\n try {\n contents = stringify(config);\n } catch (error) {\n throw new ConfigurationError(\"Invalid Codex configuration.\", {\n cause: error,\n });\n }\n const temporary = join(parent, `.${randomUUID()}.config.toml.tmp`);\n let created = false;\n try {\n const handle = await open(temporary, \"wx\", 0o600);\n created = true;\n try {\n await handle.chmod(0o600);\n await handle.writeFile(contents, \"utf8\");\n await handle.sync();\n } finally {\n await handle.close();\n }\n await rename(temporary, path);\n created = false;\n } finally {\n if (created) {\n await unlink(temporary).catch(() => undefined);\n }\n }\n}\n\nfunction validateOverrideKeys(value: JsonValue): void {\n if (Array.isArray(value)) {\n for (const item of value) validateOverrideKeys(item);\n return;\n }\n if (!isObject(value)) return;\n for (const [key, item] of Object.entries(value)) {\n if ([\"__proto__\", \"constructor\", \"prototype\"].includes(key)) {\n throw new ConfigurationError(`Invalid Codex override key: ${key}.`);\n }\n validateOverrideKeys(item);\n }\n}\n\nfunction validateOverrides(overrides: JsonObject): void {\n if (\"plugins\" in overrides || \"marketplaces\" in overrides) {\n throw new ConfigurationError(\n \"Codex Security owns plugin loading configuration.\",\n );\n }\n const features = overrides[\"features\"];\n if (\"features\" in overrides && !isObject(features)) {\n throw new ConfigurationError(\n \"Codex override features must be a TOML table.\",\n );\n }\n if (isObject(features) && \"plugins\" in features) {\n throw new ConfigurationError(\n \"Codex Security owns plugin loading configuration.\",\n );\n }\n const profiles = overrides[\"profiles\"];\n if (profiles === undefined) {\n return;\n }\n if (!isObject(profiles)) {\n throw new ConfigurationError(\n \"Codex override profiles must be TOML tables.\",\n );\n }\n for (const [name, profile] of Object.entries(profiles)) {\n if (!isObject(profile)) {\n throw new ConfigurationError(\n `Codex override profile ${name} must be a TOML table.`,\n );\n }\n const profileFeatures = profile[\"features\"];\n if (profileFeatures !== undefined && !isObject(profileFeatures)) {\n throw new ConfigurationError(\n `Codex override profile ${name} features must be a TOML table.`,\n );\n }\n if (isObject(profileFeatures) && \"plugins\" in profileFeatures) {\n throw new ConfigurationError(\n `Codex Security owns plugin loading configuration in profile ${name}.`,\n );\n }\n }\n}\n\nfunction validateNativeMultiAgentV2Overrides(overrides: JsonObject): void {\n const agents = overrides[\"agents\"];\n if (isObject(agents) && \"max_threads\" in agents) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"agents.max_threads is a legacy v1 setting. Use \" +\n \"features.multi_agent_v2.max_concurrent_threads_per_session instead.\",\n );\n }\n if (\"features\" in overrides) {\n const features = overrides[\"features\"];\n if (!isObject(features)) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"features must remain a table containing features.multi_agent_v2.\",\n );\n }\n if (\"multi_agent_v2\" in features) {\n const multiAgentV2 = features[\"multi_agent_v2\"];\n if (!isObject(multiAgentV2)) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"features.multi_agent_v2 must remain a table with enabled = true.\",\n );\n }\n if (\"enabled\" in multiAgentV2 && multiAgentV2[\"enabled\"] !== true) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"features.multi_agent_v2.enabled cannot be disabled.\",\n );\n }\n }\n }\n\n const profiles = overrides[\"profiles\"];\n if (!isObject(profiles)) {\n return;\n }\n for (const [name, profile] of Object.entries(profiles)) {\n if (!isObject(profile)) {\n continue;\n }\n const profileAgents = profile[\"agents\"];\n if (isObject(profileAgents) && \"max_threads\" in profileAgents) {\n throw new ConfigurationError(\n `The selected Codex Security plugin requires native multi-agent v2; profile ${name} agents.max_threads is a legacy v1 setting.`,\n );\n }\n const profileFeatures = profile[\"features\"];\n if (!isObject(profileFeatures) || !(\"multi_agent_v2\" in profileFeatures)) {\n continue;\n }\n const profileV2 = profileFeatures[\"multi_agent_v2\"];\n if (\n !isObject(profileV2) ||\n (\"enabled\" in profileV2 && profileV2[\"enabled\"] !== true)\n ) {\n throw new ConfigurationError(\n `The selected Codex Security plugin requires native multi-agent v2; profile ${name} features.multi_agent_v2 cannot be disabled.`,\n );\n }\n }\n}\n\nfunction deepMerge(base: JsonObject, overrides: JsonObject): JsonObject {\n for (const [key, value] of Object.entries(overrides)) {\n const existing = Object.hasOwn(base, key) ? base[key] : undefined;\n base[key] =\n isObject(value) && isObject(existing)\n ? deepMerge({ ...existing }, value)\n : cloneJson(value);\n }\n return base;\n}\n\nfunction cloneJson<T extends JsonValue>(value: T): T {\n return structuredClone(value);\n}\n\nfunction deepFreezeJson(value: JsonValue): void {\n if (typeof value !== \"object\" || value === null || Object.isFrozen(value)) {\n return;\n }\n for (const item of Array.isArray(value) ? value : Object.values(value)) {\n deepFreezeJson(item);\n }\n Object.freeze(value);\n}\n\nfunction isObject(value: unknown): value is Record<string, JsonValue> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n"]}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, open, rename, unlink } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { stringify } from \"smol-toml\";\nimport { ConfigurationError } from \"./errors.js\";\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonValue[] | JsonObject;\nexport interface JsonObject {\n [key: string]: JsonValue;\n}\n\nexport interface CodexSecurityConfig {\n pluginPath?: string;\n codexOverrides?: JsonObject;\n pythonPath?: string;\n}\n\nexport interface ScanModelConfiguration {\n model: string;\n reasoningEffort: string;\n}\n\nexport const DEFAULT_CODEX_CONFIG: Readonly<JsonObject> = {\n cli_auth_credentials_store: \"file\",\n model: \"gpt-5.6-sol\",\n model_reasoning_effort: \"xhigh\",\n features: {\n plugins: true,\n goals: true,\n multi_agent_v2: {\n enabled: true,\n max_concurrent_threads_per_session: 9,\n },\n },\n // Named filesystem profiles need an active Windows sandbox backend.\n windows: {\n sandbox: \"unelevated\",\n },\n};\n\ndeepFreezeJson(DEFAULT_CODEX_CONFIG);\n\nexport function scanModelConfiguration(\n config: Readonly<JsonObject>,\n): ScanModelConfiguration {\n const model = config[\"model\"];\n if (typeof model !== \"string\" || model.trim().length === 0) {\n throw new ConfigurationError(\n \"The configured Codex model must be a nonempty string.\",\n );\n }\n const reasoningEffort = config[\"model_reasoning_effort\"];\n if (\n typeof reasoningEffort !== \"string\" ||\n reasoningEffort.trim().length === 0\n ) {\n throw new ConfigurationError(\n \"The configured Codex reasoning effort must be a nonempty string.\",\n );\n }\n return { model, reasoningEffort };\n}\n\nexport async function mergedCodexConfig(\n config: CodexSecurityConfig,\n): Promise<JsonObject> {\n if (config.codexOverrides !== undefined && !isObject(config.codexOverrides)) {\n throw new ConfigurationError(\"codexOverrides must be an object.\");\n }\n validateOverrideKeys(config.codexOverrides ?? {});\n const overrides = cloneJson(config.codexOverrides ?? {});\n validateOverrides(overrides);\n validateNativeMultiAgentV2Overrides(overrides);\n return deepMerge(cloneJson(DEFAULT_CODEX_CONFIG), overrides);\n}\n\nexport async function writeCodexConfig(\n path: string,\n config: JsonObject,\n): Promise<void> {\n const parent = dirname(path);\n await mkdir(parent, { recursive: true, mode: 0o700 });\n let contents: string;\n try {\n contents = stringify(config);\n } catch (error) {\n throw new ConfigurationError(\"Invalid Codex configuration.\", {\n cause: error,\n });\n }\n const temporary = join(parent, `.${randomUUID()}.config.toml.tmp`);\n let created = false;\n try {\n const handle = await open(temporary, \"wx\", 0o600);\n created = true;\n try {\n await handle.chmod(0o600);\n await handle.writeFile(contents, \"utf8\");\n await handle.sync();\n } finally {\n await handle.close();\n }\n await rename(temporary, path);\n created = false;\n } finally {\n if (created) {\n await unlink(temporary).catch(() => undefined);\n }\n }\n}\n\nfunction validateOverrideKeys(value: JsonValue): void {\n if (Array.isArray(value)) {\n for (const item of value) validateOverrideKeys(item);\n return;\n }\n if (!isObject(value)) return;\n for (const [key, item] of Object.entries(value)) {\n if ([\"__proto__\", \"constructor\", \"prototype\"].includes(key)) {\n throw new ConfigurationError(`Invalid Codex override key: ${key}.`);\n }\n validateOverrideKeys(item);\n }\n}\n\nfunction validateOverrides(overrides: JsonObject): void {\n if (\"plugins\" in overrides || \"marketplaces\" in overrides) {\n throw new ConfigurationError(\n \"Codex Security owns plugin loading configuration.\",\n );\n }\n const features = overrides[\"features\"];\n if (\"features\" in overrides && !isObject(features)) {\n throw new ConfigurationError(\n \"Codex override features must be a TOML table.\",\n );\n }\n if (isObject(features) && \"plugins\" in features) {\n throw new ConfigurationError(\n \"Codex Security owns plugin loading configuration.\",\n );\n }\n const profiles = overrides[\"profiles\"];\n if (profiles === undefined) {\n return;\n }\n if (!isObject(profiles)) {\n throw new ConfigurationError(\n \"Codex override profiles must be TOML tables.\",\n );\n }\n for (const [name, profile] of Object.entries(profiles)) {\n if (!isObject(profile)) {\n throw new ConfigurationError(\n `Codex override profile ${name} must be a TOML table.`,\n );\n }\n const profileFeatures = profile[\"features\"];\n if (profileFeatures !== undefined && !isObject(profileFeatures)) {\n throw new ConfigurationError(\n `Codex override profile ${name} features must be a TOML table.`,\n );\n }\n if (isObject(profileFeatures) && \"plugins\" in profileFeatures) {\n throw new ConfigurationError(\n `Codex Security owns plugin loading configuration in profile ${name}.`,\n );\n }\n }\n}\n\nfunction validateNativeMultiAgentV2Overrides(overrides: JsonObject): void {\n const agents = overrides[\"agents\"];\n if (isObject(agents) && \"max_threads\" in agents) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"agents.max_threads is a legacy v1 setting. Use \" +\n \"features.multi_agent_v2.max_concurrent_threads_per_session instead.\",\n );\n }\n if (\"features\" in overrides) {\n const features = overrides[\"features\"];\n if (!isObject(features)) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"features must remain a table containing features.multi_agent_v2.\",\n );\n }\n if (\"multi_agent_v2\" in features) {\n const multiAgentV2 = features[\"multi_agent_v2\"];\n if (!isObject(multiAgentV2)) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"features.multi_agent_v2 must remain a table with enabled = true.\",\n );\n }\n if (\"enabled\" in multiAgentV2 && multiAgentV2[\"enabled\"] !== true) {\n throw new ConfigurationError(\n \"The selected Codex Security plugin requires native multi-agent v2; \" +\n \"features.multi_agent_v2.enabled cannot be disabled.\",\n );\n }\n }\n }\n\n const profiles = overrides[\"profiles\"];\n if (!isObject(profiles)) {\n return;\n }\n for (const [name, profile] of Object.entries(profiles)) {\n if (!isObject(profile)) {\n continue;\n }\n const profileAgents = profile[\"agents\"];\n if (isObject(profileAgents) && \"max_threads\" in profileAgents) {\n throw new ConfigurationError(\n `The selected Codex Security plugin requires native multi-agent v2; profile ${name} agents.max_threads is a legacy v1 setting.`,\n );\n }\n const profileFeatures = profile[\"features\"];\n if (!isObject(profileFeatures) || !(\"multi_agent_v2\" in profileFeatures)) {\n continue;\n }\n const profileV2 = profileFeatures[\"multi_agent_v2\"];\n if (\n !isObject(profileV2) ||\n (\"enabled\" in profileV2 && profileV2[\"enabled\"] !== true)\n ) {\n throw new ConfigurationError(\n `The selected Codex Security plugin requires native multi-agent v2; profile ${name} features.multi_agent_v2 cannot be disabled.`,\n );\n }\n }\n}\n\nfunction deepMerge(base: JsonObject, overrides: JsonObject): JsonObject {\n for (const [key, value] of Object.entries(overrides)) {\n const existing = Object.hasOwn(base, key) ? base[key] : undefined;\n base[key] =\n isObject(value) && isObject(existing)\n ? deepMerge({ ...existing }, value)\n : cloneJson(value);\n }\n return base;\n}\n\nfunction cloneJson<T extends JsonValue>(value: T): T {\n return structuredClone(value);\n}\n\nfunction deepFreezeJson(value: JsonValue): void {\n if (typeof value !== \"object\" || value === null || Object.isFrozen(value)) {\n return;\n }\n for (const item of Array.isArray(value) ? value : Object.values(value)) {\n deepFreezeJson(item);\n }\n Object.freeze(value);\n}\n\nfunction isObject(value: unknown): value is Record<string, JsonValue> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n"]}
{
"name": "@openai/codex-security",
"version": "0.1.2",
"version": "0.1.3",
"description": "TypeScript SDK and CLI for Codex Security",

@@ -62,3 +62,3 @@ "license": "Apache-2.0",

},
"gitHead": "1e03c89ad22d2df5ae65b146be1483b3608572a9",
"gitHead": "f89633aeee1e73dc6406edf76657b49a8b51a43b",
"scripts": {

@@ -65,0 +65,0 @@ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",

@@ -200,2 +200,5 @@ # `@openai/codex-security`

These overrides do not change the scan's approval policy or filesystem
permissions. See [Local security model](#local-security-model).
Scan progress identifies the requested paths and reports actual ranking,

@@ -348,2 +351,26 @@ file-review, validation, and attack-path phases as they become available.

## Local security model
Codex Security runs with your local operating-system permissions. Scan only
repositories you trust and either own or are authorized to assess. Your
repository, Git installation, configured tools, and other scans under the
same account are not separate security principals.
Every scan uses the `codex_security_scan` filesystem profile and
`approvalPolicy: "never"`. It can read the local filesystem and write to
workspace roots and the selected scan state directory. Scans do not request
interactive approval. Setting `approval_policy`, `sandbox_mode`, or permissions
through `--codex` or SDK `codexOverrides` does not replace these controls or
make them more restrictive. Independently enforced host and network
restrictions still apply.
Scan and workbench subprocesses can inherit your environment, including
unrelated API tokens and cloud credentials. Start a scan with only the
credentials it needs.
The scanner must stay within the target and output paths you authorize and
must not disclose private data beyond the operation you requested. Its results
must accurately report the scan mode, reviewed files, and exclusions. Consult
the security policy for the full threat model and private reporting process.
## Documentation and security

@@ -350,0 +377,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display