assertContentTableAccess (server/plugins/host/registry.ts:42-58) compares the requested table slug against the manifest's contentAccess[] using exact string equality, and list/search additionally filter their results to allowlisted slugs (server/plugins/host/handlers/content.ts:125,571). The schema is { table: string, modes: [...] } with additionalProperties: false (src/core/plugin-sdk/contentSchemas.ts:181-185), and there is no wildcard handling anywhere in the host.
The manifest ships inside the plugin zip, so the allowlist is fixed at build time. But a plugin that works with tables the user creates and names — form submission targets, for example — cannot know those slugs when it is built.
Today the only workaround is for the plugin to own the tables: declare a fixed set of slugs in the manifest and create them through content.tables.create, which requires cms.content.tables.manage and explicitly does not require a pre-existing allowlist row (documented in docs/features/plugin-system.md). That works, and we are shipping it, but it forces users to move their data into plugin-named tables and caps the plugin at however many slots it pre-declared.
Possible shapes, in rough preference order:
- A prefix entry, e.g.
{ table: 'leads-*', modes: ['read'] }.
- Table grants supplied at install time alongside
grantedPermissions, so the user consents to specific tables in the install dialog.
- A runtime request for access to a named table, with the host prompting the user for consent.
Option 2 seems closest to the existing consent model, and keeps the user in control of exactly which of their tables a plugin can read.
Observed at commit 6b055cf782ed1d8447f4904eb48e6f6f3f5f5301.
assertContentTableAccess(server/plugins/host/registry.ts:42-58) compares the requested table slug against the manifest'scontentAccess[]using exact string equality, and list/search additionally filter their results to allowlisted slugs (server/plugins/host/handlers/content.ts:125,571). The schema is{ table: string, modes: [...] }withadditionalProperties: false(src/core/plugin-sdk/contentSchemas.ts:181-185), and there is no wildcard handling anywhere in the host.The manifest ships inside the plugin zip, so the allowlist is fixed at build time. But a plugin that works with tables the user creates and names — form submission targets, for example — cannot know those slugs when it is built.
Today the only workaround is for the plugin to own the tables: declare a fixed set of slugs in the manifest and create them through
content.tables.create, which requirescms.content.tables.manageand explicitly does not require a pre-existing allowlist row (documented indocs/features/plugin-system.md). That works, and we are shipping it, but it forces users to move their data into plugin-named tables and caps the plugin at however many slots it pre-declared.Possible shapes, in rough preference order:
{ table: 'leads-*', modes: ['read'] }.grantedPermissions, so the user consents to specific tables in the install dialog.Option 2 seems closest to the existing consent model, and keeps the user in control of exactly which of their tables a plugin can read.
Observed at commit
6b055cf782ed1d8447f4904eb48e6f6f3f5f5301.