feat(launcher): admin policy to hide coding-agent launcher tiles#288
Merged
Conversation
Adds a denylist that lets admins hide JupyterLab launcher tiles for coding-agent CLIs (Claude Code, opencode, Pi, GitHub Copilot CLI, Codex) even when the corresponding binary is on PATH. Mirrors the disabled_providers / allow_enabling_providers_with_env / NBI_ENABLED_* shape so the mental model carries. The shape: - disabled_coding_agent_launchers (List traitlet, valid IDs claude-code, opencode, pi, github-copilot-cli, codex) - allow_enabling_coding_agent_launchers_with_env (Bool traitlet) - NBI_ENABLED_CODING_AGENT_LAUNCHERS (per-pod re-enable CSV env) The github-copilot-cli ID is deliberately distinct from github-copilot (the disabled_providers value for the Copilot LLM provider) so an admin can disable one surface without touching the other. Startup validates unknown IDs and fails the extension load loudly per the same loud-fail convention as _resolve_bool_with_env. Frontend gate fails closed: a missing or malformed capabilities field hides the tile rather than silently bypassing the denylist. The Claude Code command palette entry is gated on the same policy to keep parity with the register_agent_cli_launcher path. Six-agent review applied: - Extracted compute_effective_disabled_launchers and validate_coding_agent_launcher_ids to util.py so tests pin the real production logic (test-architect). - Fixed Claude Code command-palette bypass (security; the bespoke command's isVisible only checked CLI availability, unlike the four CLIs that go through registerAgentCliLauncher). - Made the frontend gate fail closed on missing / malformed capabilities (security; the previous "fail open" relied on isClaudeCliAvailable also defaulting false, which is a fragile defense). - Flipped the env-var substring test to actually distinguish token-match from substring-match. - Tightened admin-guide hot-reload sentence to reflect that traitlet edits need a server restart. - Documented NBI_CLAUDE_MODE_POLICY interaction and the per-pod re-enable trust model in the admin guide. Skipped: the duplicated NBI_ENABLED_PROVIDERS whitespace-handling bug in the older is_provider_enabled_in_env helper. Real bug but unrelated to this PR's surface; worth a follow-up.
mbektas
approved these changes
May 17, 2026
Collaborator
|
@pjdoland can you resolve the conflicts? |
…auncher-policy # Conflicts: # docs/admin-guide.md
Collaborator
Author
|
Merge conflicts are resolved. |
pjdoland
added a commit
to pjdoland/notebook-intelligence
that referenced
this pull request
May 22, 2026
Promotes the [Unreleased] CHANGELOG snapshot to [5.0.0] - 2026-05-22 and expands it to cover everything merged into upstream/main after PR plmbr#287's docs refresh. Bumps package.json to 5.0.0. CHANGELOG additions cover the post-plmbr#287 surface: - Settings tabs: plugin marketplace picker (plmbr#284), plugin marketplace details + Update button (plmbr#303), per-workspace MCP disable (plmbr#286), JSON-paste path in Add MCP server (plmbr#285). - Launchers: hide-with-policy (plmbr#288), brand icons for Codex / opencode (plmbr#325, plmbr#333), per-launch directory picker (plmbr#332). - Chat sidebar and agentic UX: workspace @-mention in Claude mode (plmbr#327), reload-open-files-on-disk (plmbr#330), steered system prompt away from over-eager notebook creation (plmbr#336). - Skills: multi-manifest support (plmbr#321), tracks-upstream for user- imported skills (plmbr#322), HTTP kill switch for the reconciler (plmbr#291). - Accessibility: full sub-section covering plmbr#305-plmbr#320. - Security: shell-tool sandbox (plmbr#290), Claude UI-bridge sandbox (plmbr#323), 0o600 on encrypted token (plmbr#293), env-secret scrubbing (plmbr#295), MCP config shape validation (plmbr#299), XSS allowlist (plmbr#296), Copilot WS auth + origin (plmbr#301), GHE host detection (plmbr#292), fastmcp -> mcp SDK swap (plmbr#324). - Fixed: session listing unification (plmbr#310), session preview unwrap (plmbr#331), down-area runtime throw (plmbr#330 follow-up), WS message-handler leak (plmbr#294). - Removed: fastmcp dependency, history.jsonl session gate. Adds a Migration note covering the five behavior changes operators should review before upgrading from 4.x: fastmcp swap, path sandboxes, history.jsonl gate removal, workspace @-mention pointer shape, and the Copilot WebSocket auth/origin tightening. Two reviewer rounds (six personas each) applied: - Round 1 caught security overclaims (plmbr#293, plmbr#299, plmbr#323), the plmbr#284/plmbr#303 mis-attribution, missing migration note, 3 em dashes, and the stale `fastmcp==2.x.*` recommendation in the admin guide. - Round 2 caught the missing plmbr#301 migration bullet, missing version- matrix 5.0.x row, missing README TOC entry, and a couple of style nits (sub-heading overpromise, orphan bullet). Skipped (deferred to future PRs): - README first-run tour mention. - Admin guide HTTP kill-switch row in Failure-modes table. - Terminal drag-drop trust-model precision update after plmbr#327. - Cipher description nit in plmbr#293 (Fernet AES-128-CBC+HMAC, not AES-GCM).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an admin denylist that hides JupyterLab launcher tiles for coding-agent CLIs (Claude Code, opencode, Pi, GitHub Copilot CLI, Codex) even when the corresponding binary is on `PATH`. Mirrors the existing `disabled_providers` / `allow_enabling_providers_with_env` / `NBI_ENABLED_*` shape so the mental model carries from one denylist to the next.
Closes the audit gap from the post-4.8.0 features review: the five coding-agent launcher tiles were the only new user-facing surface without an admin gate. An enterprise admin can now:
The shape
The `github-copilot-cli` ID is deliberately distinct from `github-copilot` (the `disabled_providers` value for the Copilot LLM provider). The tile and the provider are independent surfaces; hiding one does not affect the other.
Security posture
A six-agent review surfaced three security-relevant items, all addressed:
Testing
After the review, the test helpers `compute_effective_disabled_launchers` and `validate_coding_agent_launcher_ids` were extracted from the handler / setup paths into `util.py`, so the tests now pin the real production logic instead of an inline re-implementation.
Risks / follow-ups
Picked up out of the post-4.8.0 feature audit; closes that gap for the coding-agent launcher surface specifically.