Why capabilities exist
Without a capability model, any installed plugin could access persistent storage, execute system processes, or modify the hosts file — with no way for the host to control or audit which plugins do what. Capabilities solve this by requiring the host to explicitly grant each privileged feature before a plugin can use it. The host configures the granted set in thePLUGIN_INIT message payload, and the SDK enforces it at every privileged call site.
Available capabilities
storage.json — persistent JSON storage
storage.json — persistent JSON storage
Capability string: The JSON store persists data to a file under the plugin’s scoped storage root. It requires an explicit storage root configured via
"storage.json"Required to call PluginRegistry.useStore("json"). Without this capability, requesting the JSON store throws:PluginRegistry.configureStorage({ rootDir }) or the FDO_SDK_STORAGE_ROOT environment variable.sudo.prompt — sudo privilege escalation
sudo.prompt — sudo privilege escalation
Capability string:
"sudo.prompt"Required to call runWithSudo(...). This capability allows your plugin to prompt the user for sudo credentials to run privileged system commands.system.hosts.write — hosts file updates
system.hosts.write — hosts file updates
Capability string:
"system.hosts.write"Required for host-mediated updates to the system hosts file via createHostsWriteActionRequest(...) and requestPrivilegedAction(...). The host validates, audits, and applies the change — plugins never write directly.system.process.exec — process execution
system.process.exec — process execution
Capability string:
"system.process.exec"Required for host-mediated process execution via createProcessExecActionRequest(...) or operator tooling helpers. Always paired with a scope capability (system.process.scope.<scope-id>) that defines which executables, working directories, and arguments are permitted.system.fs.scope.<scope-id> — scoped filesystem access
system.fs.scope.<scope-id> — scoped filesystem access
Capability string:
"system.fs.scope.<scope-id>" (template literal type)Grants permission for host-mediated filesystem mutations within a named scope. Used alongside system.fs.mutate privileged actions. The scope constrains which paths and operations the host will allow.Example: "system.fs.scope.config-writer" grants write access within a scope named config-writer.system.process.scope.<scope-id> — scoped process execution
system.process.scope.<scope-id> — scoped process execution
Capability string:
"system.process.scope.<scope-id>" (template literal type)Narrows which executables, arguments, working directories, and environment variables the host allows within the named process execution scope. Always used together with system.process.exec.Example: "system.process.scope.kubectl" restricts execution to kubectl commands only.How the host grants capabilities
The host includes capabilities in thePLUGIN_INIT message payload. When the SDK processes PLUGIN_INIT, it calls PluginRegistry.configureCapabilities(...) with the granted set before calling init().
The PLUGIN_INIT payload shape:
PluginCapability is:
configureCapabilities directly in plugin code — the SDK handles this as part of the PLUGIN_INIT flow. Your plugin receives only the capabilities the host explicitly grants.
Declaring capabilities in your plugin
Implement the optionaldeclareCapabilities() method on your plugin class to declare which capabilities your plugin needs. The SDK uses this declaration during init() preflight to log any capabilities you declared but were not granted.
declareCapabilities() is defined in FDOInterface:
What happens when a capability is missing
If your plugin calls a privileged SDK feature without the required capability, the SDK throws an error immediately. The operation does not proceed. For example, callingPluginRegistry.useStore("json") without the storage.json capability:
Helper functions
describeCapability(capability)
Returns a human-readable descriptor for any capability string, including label, description, and category. Use this to build diagnostic UIs or display permission explanations to users.
parseMissingCapabilityError(error)
Parses a capability error thrown by the SDK and returns a structured MissingCapabilityDiagnostic with the capability name, category, label, description, and remediation guidance. Use this in error handlers to surface actionable information rather than raw error strings.
MissingCapabilityDiagnostic type:
Capability bundle helpers
The SDK provides helpers to build capability arrays for common patterns:declareCapabilities() to avoid hand-crafting capability strings: