TableCore

Read-only connections

A connection profile can be marked so that nothing TableCore does will write to it. Marking production read-only is the recommended default, and this page is about what that promise covers and where it stops.

Read the limits first

This is a guard, not a permission

TableCore runs on your computer. Anyone who can edit its settings file can turn this off, and a local client can always be patched. The security boundary is your MongoDB server's authentication, not this switch.

What it protects against is the wrong window — the mistake people actually make, at eleven at night, with staging and production side by side. For a connection that cannot write no matter what, ask your administrator for a read-only MongoDB user. The connection dialog says this too; it is not a disclaimer hidden in documentation.

The levels

Writing to this connection in the connection dialog offers:

LevelBehaviour
Read and writeThe default. TableCore does not stand in the way of any change
Read onlyNothing that writes runs on this connection, including a command document typed into the editor. Only reads go through

A third level, Ask before changing anything, exists in the settings format and is not offered in the dialog. The guard understands it, but nothing asks the question yet, so showing the option would promise a confirmation that never appears — and someone who chose it would feel protected while every delete went straight through. A settings file that already carries it keeps it and is guarded accordingly.

Profiles saved before this feature existed read back as Read and write.

What a read-only connection blocks

Every write path in the application goes through one gate rather than checking a flag in twenty places. That gate covers:

  • saving and deleting documents in the grid,
  • creating, renaming and deleting databases,
  • creating, renaming and deleting collections,
  • creating, rebuilding and dropping indexes,
  • setting collection validation rules,
  • import, restore, migration and collection reshaping,
  • loading the sample data set.

The blocked entries in menus, toolbars and the command palette are marked as locked rather than disabled outright, so hovering one still tells you why it is unavailable.

That single gate is enforced by a test that reads the source: a service that writes without asking the guard, and an operation nobody asks about, both fail the build. The failure mode this design exists for is the one place that forgot to check.

It covers raw commands too

This is the part that makes the setting worth trusting. A connection that greys out the context menu and still runs { update: "orders", updates: [ … ] } pasted into the editor is not read-only, and shipping it that way would be worse than shipping nothing, because it would be believed.

Before opening a session, the engine checks the command name against an allowlist of readsfind, getMore, aggregate, count, distinct, explain, the list* and *Stats commands, and the server-inspection commands the monitoring views need. An unknown command name is refused, not passed through: a rule whose default answer is allow becomes a hole in every read-only connection the next time MongoDB adds a command.

aggregate gets one extra check, because the command name alone cannot tell: a pipeline ending in $out or $merge is a write and is refused.

What you will see

Two different messages, because they are two different situations:

  • On an explorer or grid action"This connection is marked read only in TableCore, so nothing was sent to the server. Change it in the connection settings, or use a connection that allows writing."
  • On a command in the editor"That command writes, and this connection is marked read only in TableCore. Only reads run here."

Both say nothing was sent. That is the point: the refusal happens before the server is contacted, so a read-only connection is not relying on MongoDB to reject the operation afterwards.

In the results grid, a read-only connection is reported as its own reason rather than being folded into "this query is too complex to edit" — sending you off to rewrite a query that was never the problem is exactly the wrong help.

Two different guards

This page is about the connection. There is a second, unrelated rule about the language: translated SQL is SELECT-only, on every connection, because a mistranslated write is unrecoverable. See What this release covers.

You want to understand both. A read-write connection still refuses UPDATE customers SET … as SQL; a read-only connection still refuses the equivalent MongoDB command document. Neither implies the other.