Skip to content

feat(cli): warn at boot when a bypass permission mode is active - #522

Open
RonenMars wants to merge 1 commit into
mainfrom
docs/security-posture-and-prompt
Open

feat(cli): warn at boot when a bypass permission mode is active#522
RonenMars wants to merge 1 commit into
mainfrom
docs/security-posture-and-prompt

Conversation

@RonenMars

Copy link
Copy Markdown
Owner

Part of #473. The README half of that issue is #518 — this PR is only the piece that PR cannot carry, since it is docs-only and [skip-ci].

Why a boot warning

Disclosure is not the weak point. The first-run prompt already offers only acceptEdits and manual, so a bypass mode is never something you reach by tapping through setup. The auto-resume prompt already says agents can start without you present, and defaults to no.

The gap is the flag path. --default-permission-mode bypassPermissions, --claude-flag permissionMode=…, and a hand-edited server.yaml are all set once and then forgotten, and none of them says anything afterwards. Someone who reads a doc, copies a flag, and moves on never sees the README again — but they boot the server every day.

So: one warning at every boot while a bypass mode is active, where the person running it will actually see it.

What changed

effectivePermissionMode(flags, fallback) in src/claude-flags.ts resolves what sessions will really spawn with, mirroring the precedence StreamerServer.spawnFlagOverrides() applies — claudeFlags.permissionMode wins over the --default-permission-mode fallback.

cli/index.ts warns when that mode is dangerous, reusing the existing isDangerousPermissionMode() predicate rather than adding a second definition of "dangerous".

Why the helper is extracted rather than inlined

The failure mode is a warning that stays silent while claude_flags: {"permissionMode":"bypassPermissions"} is what actually reaches argv. Reading only the fallback would do exactly that, and nothing would ever surface it — a warning that fails open is worse than none, because its silence reads as safety.

cli/index.ts calls program.parse() at module scope, so the guard is not testable in place. Extracting the precedence is what makes it assertable.

Verification

npm run lint exits 0. __tests__/claude-flags.test.ts → 28 passed.

Positive control: inverting the precedence (fallback ?? flags?.permissionMode) turned exactly one test red — the precedence case — and restoring it returned 28/28. The assertion is not vacuous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant