Plugins for your organization
Administrators can decide which plugin catalogs people may use, switch individual plugins off everywhere, show a note on every install, and ship plugins pre-loaded on managed machines. All of it is driven by managed policy, which users and repositories cannot override. This page explains each control and how to check that it took effect.
For the general mechanics of policy files, see Managed settings.
Where policy lives
Managed policy is read only from administrator-controlled locations, never from a project folder:
| Platform | Location |
|---|---|
| Linux | /etc/syntic/settings.policy.json |
| macOS | /etc/syntic/settings.policy.json, then /Library/Application Support/Syntic/settings.policy.json (the second wins) |
| macOS with MDM | A configuration profile for the preference domain ai.syntic.code, applied on top of the files |
| Windows | %ProgramData%\Syntic\settings.policy.json |
Next to each base file, a settings.policy.d/ folder may hold *.json drop-ins, applied in name order. A later file wins for the same key. A policy file that is not valid JSON stops Syntic Code from starting and names the file; inside a valid file, one bad entry is skipped and reported while the rest still applies.
The plugin keys
| Key | Type | Effect |
|---|---|---|
strictKnownMarketplaces | array of entries | When present, only catalogs that match an entry may be added, refreshed or installed from. An empty array allows none. allowedMarketplaces is accepted as another name. |
blockedMarketplaces | array of entries | Catalogs that may never be used. Always wins over the allow list. |
enabledPlugins | object { "plugin@marketplace": false } | A plugin set to false is force-disabled: it cannot be installed or enabled and does not load. Ids set to true or left out are untouched. |
pluginTrustMessage | string | Shown after every successful install as “Note from your organization”. |
These keys count only in managed policy. The same keys in user or project settings cannot loosen or replace them.
Restrict which catalogs people use
How entries are written
Each entry in strictKnownMarketplaces or blockedMarketplaces is one of:
- a source string, written as
syntic plugin marketplace addtakes it:owner/repo, a git or https URL, or a local path; { "hostPattern": "<regex>" }, matched against the source’s host;{ "pathPattern": "<regex>" }, matched against the source’s path. For a GitHub source, the path isowner/repo.
An entry that cannot be read is skipped; the others still apply.
Allow only your own catalogs
{
"strictKnownMarketplaces": [
{ "pathPattern": "^acme-corp/" },
{ "hostPattern": "^git\\.corp\\.example$" },
"partner-co/approved-plugins"
]
}This allows any GitHub repository under acme-corp, anything on the internal git server, and one partner repository. Everything else is refused with a message that names the policy key.
Block specific catalogs
{
"blockedMarketplaces": ["someone/untrusted-plugins"]
}A blocked GitHub owner/repo stays blocked when someone writes it another way, such as https://github.com/someone/untrusted-plugins.git or the SSH form. A block entry without a ref blocks every ref of that repository; one that names a ref blocks only that ref.
When the check runs
The catalog check runs before anything is fetched:
syntic plugin marketplace addand adding a catalog in/plugin;- every refresh, including the daily background refresh (a forbidden catalog is skipped with a note);
syntic plugin install, when the plugin’s catalog is now forbidden.
A catalog that was saved before the policy arrived stays in the user’s list but can no longer be refreshed or installed from.
Control matrix
| Policy | Unlisted catalog | Catalog on allow list | Catalog on block list |
|---|---|---|---|
| Neither key | Allowed | n/a | n/a |
Only blockedMarketplaces | Allowed | n/a | Refused |
Only strictKnownMarketplaces | Refused | Allowed | n/a |
| Both | Refused | Allowed, unless also blocked | Refused |
Switch plugins off everywhere
{
"enabledPlugins": {
"risky-tool@acme": false,
"old-helper@partner": false
}
}A force-disabled plugin:
- is refused by
syntic plugin installbefore anything is downloaded; - cannot be turned on with
syntic plugin enable; - does not load, even if it was installed earlier or is loaded with
--plugin-diror from a pre-seeded folder; - is reported as a startup problem in machine-readable output.
Only an explicit false has an effect. You cannot force a plugin on through policy.
Show a note on every install
{ "pluginTrustMessage": "Plugins run code with your permissions. Use only catalogs from the Platform team." }After each successful install, the output ends with the note. Use it to point people to your internal guidance.
Pre-load plugins on managed machines and images
For container images, CI runners and managed laptops, set SYNTIC_PLUGIN_SEED_DIR to one or more folders (separated by : on macOS and Linux, ; on Windows). Each folder is a plugin or a folder of plugins. They load in every session after the user’s installed plugins, without being installed:
export SYNTIC_PLUGIN_SEED_DIR=/opt/syntic/plugins- A leading
~is expanded to the home folder. - An installed plugin with the same name wins over a pre-seeded one.
- Pre-seeded plugins go through the same trust checks and
enabledPluginspolicy as installed ones. - They do not load in
--baresessions.
For scripted runs that need a plugin installed from a catalog, use --plugin name@marketplace (with --plugin-scope if needed). It installs before the run without prompting and prints results to standard error.
A repository cannot set SYNTIC_PLUGIN_SEED_DIR, SYNTIC_PLUGIN_DIRS, SYNTIC_TRUSTED_PLUGINS or any other SYNTIC_PLUGIN* variable through the env block of its settings. Only the user’s own environment and settings may choose where plugins load from.
A per-machine trust list
Separately from managed policy, each machine can keep a trust list in ~/.syntic/plugins/policy.json:
{ "trusted": ["formatter", "acme"], "lockdown": true }trustednames plugins or whole catalogs.- With
"lockdown": true, only trusted plugins load; others are blocked and reported. - Without lockdown, untrusted plugins still load and a trust warning is logged.
SYNTIC_PLUGIN_LOCKDOWN=1turns lockdown on regardless of the file.SYNTIC_TRUSTED_PLUGINS=a,b,cadds names to the trusted list.
This is useful on shared build machines. For fleet-wide rules, prefer managed policy. See also Plugin safety.
Check the rollout
On a managed machine:
syntic doctorlists the managed policy keys in force and any plugins left off because a dependency is missing or disabled. Then try the paths your policy should close:
syntic plugin marketplace add someone/untrusted-plugins # should be refused
syntic plugin install risky-tool@acme # should be refusedEach refusal names the reason, so users know it is policy and not a broken catalog.
What policy cannot enforce
- It cannot install plugins for users. Combine a pre-seeded folder or a scripted
--plugininstall with policy instead. - It cannot set plugin options or secrets. Those stay per user.
- It cannot stop a user from loading a folder of their own with
--plugin-dir, though that folder still passes throughenabledPluginsand the trust list. - Plugins recorded in the
managedscope are reported but never removed bysyntic plugin reconcile --prune.
Troubleshoot policy
| Symptom | Likely cause |
|---|---|
| Every catalog is refused | strictKnownMarketplaces is an empty array, or no entry matches. Check the regex and the host or path it is tested against. |
| A blocked repository still adds | It is written in a form your entry does not cover, such as a different host. Add a hostPattern entry. |
| Policy seems ignored | The file is in a user folder rather than an administrator location, or a later file overrides it. syntic doctor shows what is in force. |
| Syntic Code will not start | A policy file is not valid JSON. The error names the file. |