Skip to content

docs(cache): document the cache signing trust model - #10526

Open
dmadisetti wants to merge 3 commits into
mainfrom
dm/cache-signing-docs
Open

dmadisetti wants to merge 3 commits into
mainfrom
dm/cache-signing-docs

Conversation

@dmadisetti

@dmadisetti dmadisetti commented Aug 12, 2026 •

Copy link
Copy Markdown
Member

📝 Summary

Docs for the cache signing trust model.

Adds a "Cache signing and trust" section to docs/api/caching.md covering the config surface, the
verification postures, and the sharing-between-machines workflow.

Stack

  1. feat(cache): formalize caching config and add signing fields #10523 — config entrypoints + signing fields
  2. refactor(cache): introduce SigningPolicy and rename mode to verification #10524 — SigningPolicy, mode → verification
  3. feat(cache): sanitize signing config from untrusted layers #10525 — config sanitization (untrusted layers)
  4. this PR — docs

@vercel

vercel Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
marimo-docs Ready Ready Preview Sep 22, 2026 11:27pm UTC

Request Review

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 2 files

Architecture diagram
sequenceDiagram
    participant User as User Config
    participant Env as Environment
    participant Proj as Project Config
    participant NB as Notebook Metadata
    participant Marimo as marimo Runtime
    participant Cache as Cache Store
    participant Crypto as Signing/Verification
    
    Note over User,Crypto: Cache Signing Trust Model Architecture
    
    Note over User,Env: Trusted Configuration Sources
    
    User->>Marimo: signing.private_key_path
    User->>Marimo: signing.trusted_signers
    User->>Marimo: cache.verification (off|on|strict)
    Env->>Marimo: cache.verification override
    
    Note over Proj,NB: Untrusted Configuration Sources
    
    Proj->>Marimo: cache.store (allowed)
    Proj--xMarimo: signing (ignored)
    Proj--xMarimo: cache.verification (ignored)
    NB--xMarimo: signing (ignored)
    NB--xMarimo: cache.verification (ignored)
    
    Note over Marimo: Cache Read Flow
    
    Marimo->>Cache: Request cached entry
    Cache-->>Marimo: Return serialized data
    
    alt verification = "on" (default)
        Marimo->>Crypto: Verify signature with trusted key
        Crypto->>Crypto: Check fingerprint whitelist
        alt Trusted & valid signature
            Crypto-->>Marimo: Signature valid
            Marimo->>Marimo: Deserialize with pickle.loads
        else Foreign key or invalid
            Crypto-->>Marimo: Verification failed
            Marimo->>Marimo: Treat as cache miss (recompute)
        end
    else verification = "strict"
        Marimo->>Crypto: Verify signature with trusted key
        Crypto->>Crypto: Check fingerprint whitelist
        alt Trusted & valid signature
            Crypto-->>Marimo: Signature valid
            Marimo->>Marimo: Deserialize with pickle.loads
        else Foreign key or invalid
            Crypto-->>Marimo: Verification failed
            Marimo->>Marimo: Raise exception (fail closed)
        end
    else verification = "off"
        Marimo->>Marimo: Deserialize without verification
        Note over Marimo: Unverified pickle.loads - code execution risk
    end
    
    Note over Marimo: Cache Write Flow
    
    alt verification = "off"
        Marimo->>Cache: Write unsigned entry
    else verification = "on" or "strict"
        Marimo->>Crypto: Sign entry with local Ed25519 key
        Crypto-->>Marimo: Signature attached
        Marimo->>Cache: Write signed entry
    end
    
    Note over Crypto: Missing cryptography package
    alt cryptography not installed
        Note over Marimo,Crypto: verification="on": all reads miss, writes skipped
        Note over Marimo,Crypto: verification="strict": raises
    end
Loading

Re-trigger cubic

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds documentation describing marimo’s cache-signing trust model, including how signing keys are trusted across machines, how cache verification postures behave, and where security-sensitive settings can (and cannot) be configured.

Changes:

  • Add a new “Cache signing and trust” section to the caching API docs, covering trust, sharing workflows, and verification postures.
  • Update configuration docs to clarify that some security-sensitive settings cannot be overridden by repository-traveling config layers (e.g., pyproject.toml, script metadata, project .marimo.toml).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
docs/guides/configuration/index.md Clarifies override limits and warns that repository-traveling layers can’t set signing / cache.verification.
docs/api/caching.md Documents cache signing, key trust, verification modes, and where trust configuration is honored.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/api/caching.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (2)

docs/api/caching.md:334

  • The verification table implies entries are always signed on write for verification="on"/"strict", but LazyLoader skips writes when no private signing key is available (e.g. a public-key-only verifier). This row should be qualified to avoid suggesting unsigned entries will be written under verifying modes.
| Foreign key, bad signature, or unsigned | served **unchecked** | **miss** — recomputed | **raises** |
| On write | not signed | signed | signed |

docs/api/caching.md:354

  • This section says [signing] and [cache].verification are read from user config files only, but earlier in the same doc you describe MARIMO_CACHE_SIGNING_PRIVATE_KEY / MARIMO_CACHE_SIGNING_PUBLIC_KEY as additional (trusted, operator-controlled) ways to configure signing identity/trust. Consider clarifying that the restriction is about repository-controlled config layers, and that environment variables are still honored.
`[signing]` and `[cache].verification` are read from your own user configuration
only — the file at `~/.config/marimo/marimo.toml` or `~/.marimo.toml`. marimo
ignores them in `pyproject.toml`, in notebook script metadata, and in a
`.marimo.toml` that sits inside a project directory.

@dmadisetti
dmadisetti force-pushed the dm/cache-signing-docs branch from 32d2111 to 45b1cf7 Compare August 18, 2026 22:24
@dmadisetti
dmadisetti force-pushed the dm/cache-config-sanitize branch from 3963cc2 to 63cc6a4 Compare August 18, 2026 23:25
@dmadisetti
dmadisetti force-pushed the dm/cache-signing-docs branch from 45b1cf7 to 02e01cc Compare August 18, 2026 23:25
@dmadisetti
dmadisetti force-pushed the dm/cache-config-sanitize branch from 63cc6a4 to d574a97 Compare August 20, 2026 20:18
@dmadisetti
dmadisetti force-pushed the dm/cache-signing-docs branch from 02e01cc to 1dcbe8d Compare August 20, 2026 20:18
@dmadisetti
dmadisetti force-pushed the dm/cache-config-sanitize branch from d574a97 to c841dac Compare August 21, 2026 20:12
@dmadisetti
dmadisetti force-pushed the dm/cache-signing-docs branch from 1dcbe8d to 78088ea Compare August 21, 2026 20:12
@dmadisetti
dmadisetti marked this pull request as ready for review August 21, 2026 20:12
@dmadisetti
dmadisetti requested a review from akshayka as a code owner August 21, 2026 20:12
Base automatically changed from dm/cache-config-sanitize to main August 24, 2026 21:15
@dmadisetti
dmadisetti force-pushed the dm/cache-signing-docs branch from 78088ea to 8be95ab Compare August 24, 2026 21:15
Comment thread docs/api/caching.md Outdated
whatever code the entry tells it to. Reading a cache someone else wrote therefore
means running code they chose.

The lazy loader defends against that. It signs each entry it writes with an

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Has lazy loader been introduced before in the documentation? You should define it when it is first mentioned. When I read this paragraph, I think "What lazy loader? What is a lazy loader?"

Comment thread docs/api/caching.md Outdated
Comment on lines +312 to +315
Two environment variables set the same thing without a config file:
`MARIMO_CACHE_SIGNING_PRIVATE_KEY` holds a signing identity, and
`MARIMO_CACHE_SIGNING_PUBLIC_KEY` adds one trusted key. Both take the key itself
in Privacy-Enhanced Mail (PEM) form, not a path.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is difficult for a user to understand. Instead of saying "Two environment variables set the same thing without …" you should frame this as instructive for a user, based on what they are trying to do.

For example, something like: "You can also using environment variables. Store XXX in the XXX environment variable, and XXX in the XXX environment variable. The environment variables expect keys in XXX form."

Comment thread docs/api/caching.md
Comment on lines +318 to +319
Restoring a cache entry deserializes it with `pickle`, so trusting a
fingerprint lets whoever holds that key run arbitrary code on your machine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"Restoring a cache entry can involve arbitrary code execution. For this reason, only add a fingerprint if you would run any script that person handed you"

williambdean pushed a commit to williambdean/marimo that referenced this pull request Sep 6, 2026
…team#10523)

## 📝 Summary

Formalizes the caching config entrypoints, and adds "signing" fields for
cache verification.
This PR introduces the bones for signature verification that will come
in a subsequent change.

Cache configuration moves out of `experimental` into a top-level
`[cache]` table, and a `[signing]` table is added for trust and
identity:

```toml
[cache]
verification = "on"          # off | on | strict

[cache.store]
type = "file"
args = { save_path = "~/.cache/marimo" }

# Or a tiered store:
# [[cache.store]]
# type = "file"
# [[cache.store]]
# type = "redis"

[signing]
private_key_path = "~/.marimo/key.pem"

[signing.trusted_signers]
"SHA256:kV9x2c...q8" = "CI cache key"
"SHA256:abc9f1...4d" = "Alice"
```

`[cache].verification` and `[signing]` are declared and merged here,
with followup providing implementation.

### Breaking

`experimental.cache` is removed for the explicit cache path.

### Notes

- `signing.trusted_signers` is a **replace** path in `merge_config`, not
a deep merge. Deep-merging unions the fingerprints from every layer, and
then no layer can remove a signer that a lower-priority one anchored.
- `signing.private_key_path` joins the secrets mask, so this machine's
signing identity is never serialized to the frontend.

### Stack

1. **this PR** — config entrypoints + signing fields
2. marimo-team#10524 — `SigningPolicy`, `mode` -> `verification`
3. marimo-team#10525 — config sanitization
4. marimo-team#10526 — docs
@dmadisetti
dmadisetti force-pushed the dm/cache-signing-docs branch from 8be95ab to 724244f Compare September 16, 2026 20:19
Covers the config surface, the verification settings, and the framing that
matters: trusting a fingerprint grants arbitrary code execution to whoever holds
that key, because a cache restore is `pickle.loads`. There is no narrower
cache-only version of the grant, so the docs say so plainly rather than leaving
users to infer it.

The section states its scope up front. Signing applies to `method="lazy"`; the
default `method="pickle"` neither signs nor verifies, so a cache it wrote carries
no provenance.

Also documents which layers may set these settings and why the
repository-controlled ones cannot, and corrects the `pythonpath` and `dotenv`
sections: both are now read only from user configuration, and the `.env` beside a
`pyproject.toml` is no longer loaded implicitly.

This branch was successfully deployed

1 active deployment
Preview — 9c441ef3 Deployed Sep 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants