Skip to content

feat(sharing): add MARIMO_RESTRICT_SHARING env var machine-wide#9756

Open
nojaf wants to merge 2 commits into
marimo-team:mainfrom
nojaf:restrict-sharing-env
Open

feat(sharing): add MARIMO_RESTRICT_SHARING env var machine-wide#9756
nojaf wants to merge 2 commits into
marimo-team:mainfrom
nojaf:restrict-sharing-env

Conversation

@nojaf
Copy link
Copy Markdown
Contributor

@nojaf nojaf commented Jun 2, 2026

📝 Summary

This is a follow up to #9578. That PR made the sharing.wasm, sharing.html, and sharing.molab config flags control what sharing affordances the UI surfaces, and added the molab flag. During #9578 the maintainers (@mscolnick via DM) asked that the MARIMO_RESTRICT_SHARING env var be split out into its own PR, so this is that separate change.

What changed

  • marimo/_config/settings.py: add RESTRICT_SHARING to GlobalSettings, reading the MARIMO_RESTRICT_SHARING env var.
  • marimo/_config/manager.py: when the env var is set, EnvConfigManager.get_config() injects sharing = {"wasm": False, "html": False, "molab": False}. EnvConfigManager is the last (highest priority) partial in get_default_config_manager, so this override takes precedence over any per-project or per-user TOML config.
  • tests/_config/test_manager.py: tests that the flag injects the all-false sharing config, that nothing is injected when the flag is off, and that the env override wins over a user config that explicitly enables sharing.

Why we want this

The sharing.* config flags require every project or user to opt in. In our company we run marimo in managed devpod/container environments, and there is no reliable way to ensure every user has the flag set in their own config, since users have admin access to their own environment and can edit config files. MARIMO_RESTRICT_SHARING=1 lets infra admins set the restriction once at the container/pod spec level, outside the user's control, and have every notebook session inherit it without per-project configuration.

Scope and honest framing

This is a UI-hiding/policy control, not a server-side security boundary. #9578 deliberately removed the server-side 403 gates (exporting != sharing), so the sharing config only drives what the UI surfaces (the editor Share dropdown and the molab button baked into exported HTML). This env var hides those affordances machine-wide but does not block a determined user: exported HTML still embeds source and endpoints still serve code. We pair it with network egress filtering (blocking marimo.app, molab.marimo.io, static.marimo.app) for defence in depth. Note also that MARIMO_RESTRICT_SHARING=0 as a command prefix overrides the env var for that process, so it should be set in the devpod/container spec rather than inside the container.

📋 Pre-Review Checklist

  • For large changes, or changes that affect the public API: this change was discussed or approved through an issue, on Discord, or the community discussions (Please provide a link if applicable).
  • Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
  • Video or media evidence is provided for any visual changes (optional).

✅ Merge Checklist

  • I have read the contributor guidelines.
  • Documentation has been updated where applicable, including docstrings for API changes.
  • Tests have been added for the changes made.

//cc @Light2Dark @akshayka, @dmadisetti

enforcement

Injects sharing.wasm/html/molab = false as the highest-priority config
override when the env var is set, so it takes precedence over any
per-project or per-user config. Intended for devpod or container
environments where infra admins set the variable and every notebook
session inherits it without per-project configuration.
Copilot AI review requested due to automatic review settings June 2, 2026 08:05
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Jun 2, 2026 8:19am

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Introduces a global “restrict sharing” setting to disable external sharing options via an environment variable, and verifies the behavior with new tests.

Changes:

  • Add MARIMO_RESTRICT_SHARING (GLOBAL_SETTINGS.RESTRICT_SHARING) to globally disable sharing affordances.
  • Inject a highest-priority config override that forces "sharing": {"wasm": False, "html": False, "molab": False} when enabled.
  • Add tests ensuring the restriction is applied and that it overrides user config.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
tests/_config/test_manager.py Adds test coverage for the new restrict-sharing behavior and precedence over user config.
marimo/_config/settings.py Defines the new global setting RESTRICT_SHARING sourced from MARIMO_RESTRICT_SHARING.
marimo/_config/manager.py Applies the sharing restriction override to config output when the global flag is enabled.

Comment thread tests/_config/test_manager.py Outdated
Comment thread tests/_config/test_manager.py Outdated
Comment thread marimo/_config/settings.py Outdated
Move the sharing restriction out of EnvConfigManager and into a final
clamp at the end of MarimoConfigManager.get_config_overrides(), applied
after all partials are merged. A later with_overrides() appends a
partial after EnvConfigManager, so injecting in a single reader did not
actually guarantee the restriction could not be re-enabled; clamping
post-merge makes it unconditional and covers both get_config() and the
overrides served to the frontend.

Rework the tests to assert on the resolved config (overrides clamp,
precedence over user config, precedence over a later with_overrides, and
untouched config when the flag is off) and make the disabled case
deterministic.
@dmadisetti
Copy link
Copy Markdown
Collaborator

Thanks! I think that a new Restricted/Exfil/Security ConfigManager would be a better fit than hardcoding the override in MarimoConfigManager. Adding it to get_default_config_manager should be sufficient

@dmadisetti dmadisetti self-requested a review June 3, 2026 01:10
@dmadisetti dmadisetti added the enhancement New feature or request label Jun 3, 2026
@nojaf
Copy link
Copy Markdown
Contributor Author

nojaf commented Jun 3, 2026

Thanks @dmadisetti, that makes sense. Happy to pull it out into a dedicated reader (RestrictedConfigManager) wired into get_default_config_manager instead of special-casing it in MarimoConfigManager.

One nuance I want to confirm before I push: the reason it currently lives in get_config_overrides() (the post-merge clamp) rather than in a single reader is that with_overrides() appends its partial after the existing ones, so a reader placed in get_default_config_manager could be re-enabled by a later with_overrides({"sharing": {...: True}}). There's a test pinning that ("a later override cannot re-enable sharing").

Two ways to keep that guarantee with the cleaner reader design:

  1. Add RestrictedConfigManager as a normal partial and have with_overrides() keep it last (re-append it after the new override), so the "cannot be re-enabled" property and test still hold.
  2. Treat it as a plain partial exactly as you described, and accept that a later with_overrides() can re-enable sharing, i.e. drop that guarantee/test, on the grounds that this is a UI-hiding policy control and not a server-side boundary anyway.

Do you have a preference? My lean is (1) since it keeps the machine-wide enforcement intent, but (2) is simpler and matches your comment most literally. Either way I'll move the logic into the new reader.

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants