Files
OmniRoute/src/lib/api/cliConfigWriteGuard.ts
SB Yoon d46e8d72c9 feat(cli): refuse ephemeral container auto-config writes (#10057)
* feat(cli): refuse ephemeral container auto-config writes

Detect containerized OmniRoute and block CLI/API config writes into
throwaway homes unless a bind mount or explicit opt-in is present, and
honor compose host-profile CLI_CONFIG_HOME mounts outside the container home.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(changelog): name fragment for #10057

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: yansigit <yansigit@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
2026-08-16 00:42:14 -03:00

34 lines
1.3 KiB
TypeScript

import { NextResponse } from "next/server";
import { ensureCliConfigWriteAllowed } from "@/shared/services/cliRuntime";
import { isContainerWriteRefusal } from "@/shared/utils/containerConfigGuard";
/**
* Shared gate for API routes that write a host CLI's config file.
*
* Returns `null` when the write may proceed, otherwise the response to send:
* - 422 + `containerEphemeralTarget` when OmniRoute runs in a container and
* the target is not bind-mounted from the host (the write would vanish),
* - 403 when CLI config writes are switched off entirely.
*
* Clients key off `containerEphemeralTarget` to render the host-CLI guidance
* inline, the same way the Zed import card handles its Docker 422.
*/
export function guardCliConfigWrite(
targetPath: string,
options: { toolLabel?: string; hostCommand?: string } = {}
): NextResponse | null {
const writeError = ensureCliConfigWriteAllowed(targetPath, options);
if (!writeError) return null;
const containerEphemeralTarget = isContainerWriteRefusal(writeError);
return NextResponse.json(
{
error: writeError,
...(containerEphemeralTarget
? { containerEphemeralTarget, hostSetupCommand: options.hostCommand }
: {}),
},
{ status: containerEphemeralTarget ? 422 : 403 }
);
}