Files
2026-07-13 12:37:52 +08:00

16 KiB

Nacos Plugin Spec

Purpose

Nacos uses plugins and SPI extensions to keep cross-cutting infrastructure and replaceable domain capabilities outside the fixed core. A plugin may provide authentication, resource visibility, data source dialects, encryption, tracing, flow control, environment adaptation, AI pipeline behavior, AI storage behavior, AI resource import behavior, or Java client-side request adaptation.

The plugin mechanism must let Nacos keep a stable core model while allowing deployments to choose an implementation that matches their identity system, database, observability stack, or extension scenario.

Plugin Identity

Every plugin is identified by:

  • pluginType: the extension category, such as auth or visibility.
  • pluginName: the implementation name inside that category, such as nacos.
  • pluginId: the runtime identifier in the form {pluginType}:{pluginName}.

The pluginId is the value used by the admin plugin API, cluster state synchronization, persisted plugin state, and user-facing diagnostics.

Plugin Types

The current plugin type registry is defined by PluginType.

Type Purpose Contract
auth Authentication and authorization implementation. Auth Plugin Spec
visibility Resource visibility and query visibility advisory. Visibility Plugin Spec
datasource-dialect Database dialect and persistence adaptation. Data Source Dialect Plugin Spec
config-change Configuration change extension. Config Change Plugin Spec
encryption Encryption and decryption extension. Config Encryption Plugin Spec
trace Trace and observability extension. Trace Plugin Spec
environment Environment adaptation extension. Environment Plugin Spec
control Traffic and control extension. Control Plugin Spec
ai-pipeline AI registry pipeline extension. AI Publish Pipeline Plugin Spec
ai-storage AI registry storage extension. AI Storage Plugin Spec
ai-resource-import AI registry external import extension. AI Resource Import Plugin Spec

Domain-specific plugin contracts are defined by their own specs. This document defines the common runtime contract shared by all plugin categories.

Addressing extension is documented with plugin specs for continuity with the public plugin documentation, but current server code handles it through MemberLookup and does not register it in PluginType.

Runtime Location

Nacos has two plugin-like extension surfaces:

Runtime Loading model State owner Examples
Server plugin Domain SPI plus PluginProvider, listed and managed by server plugin APIs where supported. Nacos server process and, for managed plugins, server plugin state. auth, visibility, datasource-dialect, control, trace.
Java client extension Java SPI or SDK API loaded inside the client process. Client classpath, client properties, and SDK instance lifecycle. ServerListProvider, ClientAuthService, IConfigFilter, client-side config encryption.

Client extensions are not managed by /v3/admin/core/plugin/* and do not have a server-side PluginStateCheckerHolder decision unless their corresponding server plugin also participates in request handling. They must still follow Nacos resource identity, authorization, and payload semantics because they shape requests sent by the SDK.

Execution Modes

Plugin categories do not all execute in the same shape. A plugin type must define its execution mode explicitly.

Mode Meaning Examples
Exclusive selection One implementation is selected for the process or request scope. Other loaded implementations remain inactive for that decision. auth, datasource-dialect
Configured single service Multiple implementations may be loaded, while a domain chooses one service by configuration or request context. visibility, ai-resource-import
Ordered chain Multiple matching plugins are invoked in a stable order. Each node may contribute a result, and the domain defines whether failure stops the chain. ai-pipeline, config-change
Subscriber or broadcast Multiple subscribers observe the same event or trace point without owning the primary decision. trace, event-style extensions

For chained plugins, the domain SPI must define:

  • How candidate plugins are selected for a resource or pointcut.
  • Which field controls ordering, such as getPreferOrder() or getOrder().
  • Whether execution is serial or parallel.
  • Whether a failed plugin stops the chain or only records a failed result.
  • How partial results are persisted and exposed.

The core plugin manager records loaded and enabled plugins; it does not by itself define the execution mode. Domain managers are responsible for applying the mode consistently.

SPI Layers

Nacos plugins have two related SPI layers:

  1. Domain SPI, such as AuthPluginService or VisibilityService, defines the behavior required by the owning domain.
  2. Core plugin SPI, PluginProvider, exposes plugin instances to the core plugin manager for listing, status management, configuration, and observability.

A plugin that needs dynamic configuration implements PluginConfigSpec. A plugin category that supports enable or disable checks must use PluginStateCheckerHolder rather than keeping an independent status source.

Loading And Lifecycle

Plugin implementations are discovered with the Nacos SPI loader. Deployments may provide plugins from the classpath or from the server plugin directory. The plugin implementation must be loadable without changing Nacos server code.

The core PluginManager discovers PluginProvider implementations after the server application is ready. Domain managers may also load their domain services through SPI, but availability decisions must still respect the plugin state held by the core plugin manager.

Plugin startup must be deterministic:

  • A plugin type and name pair must map to one runtime plugin instance.
  • Duplicate plugin names in the same type are invalid for stable operation.
  • Plugin implementations must not change the meaning of shared Nacos resource identifiers, response envelopes, or error conventions.

State And Configuration

Plugin state has two levels:

  • Loaded: the implementation exists in the runtime.
  • Enabled: the implementation may participate in request handling.

Most plugin types are enabled by default after loading. Exclusive plugin types select one default implementation:

Type Default selection rule
auth The implementation named by nacos.core.auth.system.type, default nacos.
datasource-dialect The configured SQL platform, default derby.

Critical plugins cannot be disabled while the server depends on them. The current critical set includes built-in data source dialects and the default AI storage plugin required by the server.

Plugins with PluginConfigSpec expose config definitions, current config, and config application behavior. Cluster-wide status or config changes must be synchronized through the plugin state operation path unless the request is explicitly local only.

Configuration Definition

Plugin config items are described by ConfigItemDefinition. The key field is the canonical item key inside the plugin implementation and does not include the nacos.plugin.{pluginType}.{pluginName}. prefix. Static configuration should prefer this normalized full key:

nacos.plugin.{pluginType}.{pluginName}.{itemKey}

Config definitions may declare the following metadata:

Field Meaning
aliases Historical static config keys for compatibility and migration hints.
sensitive Whether the value is sensitive. Query APIs must mask it before returning.
effectMode Effect mode. RUNTIME can take effect at runtime, and RESTART requires restart.

aliases are used when reading compatible static configuration and may also be accepted as migration-compatible API input. After normalization, aliases must not be written into runtime persistence files or local-only memory maps. If an input contains multiple aliases for the same item, the first alias declared in the definition takes effect and the server logs the ignored aliases.

Config Sources And Value Metadata

Effective plugin config values are computed by a unified resolution flow. Source priority is:

LOCAL_ONLY > RUNTIME_PERSISTED > STATIC > DEFAULT
Source Meaning
DEFAULT Value from ConfigItemDefinition.defaultValue.
STATIC Value from static configuration, such as application.properties, environment variables, JVM parameters, or Spring parameters.
RUNTIME_PERSISTED Cluster-wide runtime override. It may currently be persisted as the final content in plugin-configs.json.
LOCAL_ONLY Current-node override for diagnosis or emergency handling, not synchronized to the cluster.

Plugin detail responses may add a configValueMetas map keyed by canonical item key. Each PluginConfigValueMeta describes the current source and overridden state of one config item. overridden ignores DEFAULT and should be true only when the same key has multiple non-default sources.

Runtime persisted config and local-only config store only values by pluginId + itemKey. They do not store normalized full keys, alias keys, source, or version information.

Every internal source resolver must expose its canonical item-key map through getConfig(PluginInfo). Reading is independent from update capability: DEFAULT reads definition defaults, STATIC reads normalized and alias keys from the environment, and the two runtime sources read their internal maps. isUpdatable is checked only when replacing a source map. An update replaces the complete map; an empty map clears all overrides for that plugin and source. The source contract does not require separate remove or restore operations.

Config Update Compatibility

Plugin detail APIs must remain additively compatible: existing config and configDefinitions fields remain available. config may represent the current effective config, and the added configValueMetas map carries source and overridden metadata by canonical item key.

PUT /v3/admin/core/plugin/config and the matching Console API keep the current full override map update semantics. localOnly=true updates only the current node local-only override; otherwise the request updates the cluster-wide runtime persisted override. Key normalization and effectMode checks are server-side logic and are not exposed as new API parameters. Fields marked effectMode=RESTART must not be applied immediately by runtime updates. The server compares the previous and submitted full map for the target source, so adding, changing, or removing a RESTART item is rejected. Omitting a key from the submitted map therefore removes its override only when that item is runtime-effective. Canonical item keys, normalized full keys, and compatible alias keys are normalized to item keys before validation and storage. An undefined key or an alias that ambiguously matches multiple config items must produce a parameter validation error.

For an item declared sensitive=true, a submitted value containing the standard ****** marker is treated as a masked display value. If the target source already contains that item, the server preserves the original value from that same source. If the target source does not contain the item, the input is ignored and no override is created. This rule also covers values such as a******z and ab******yz; it must not copy an effective value from another source such as STATIC into a runtime override. The server logs a warning with only pluginId, item key, and target source, and must not log the value.

Initialization And Runtime Apply

Startup and runtime updates use the same source resolver and effective config calculation:

  1. Startup loads all plugin-configs.json entries into the runtime persisted source before applying any plugin config.
  2. Every loaded configurable plugin is then resolved and applied, including plugins without a persisted override. Startup may apply both RUNTIME and RESTART fields because the plugin is being initialized.
  3. A runtime request replaces one complete RUNTIME_PERSISTED or LOCAL_ONLY source map. The server resolves all sources again and invokes the plugin for each accepted request, including a same-map request used as a manual retry.

Updates for the same plugin are serialized. A runtime persisted update first persists the normalized complete source map, replaces the resolver source, resolves and validates the effective config, and then applies it to the plugin. If persistence fails, the resolver source and plugin are not changed and no rollback is attempted. If apply fails after the source update, the accepted source map remains persisted and resolved; the server does not issue an automatic rollback or compensation update. The API returns an explicit server error that the config was updated but apply failed, and the server logs the plugin ID and source without config values. Repeating the same complete map is a supported manual apply retry. A LOCAL_ONLY update follows the same replace-resolve-apply behavior without persistence or synchronization; its new local source map also remains when apply fails.

Admin API

The core plugin admin API is:

Method Path Purpose
GET /v3/admin/core/plugin/list List loaded plugins, optionally filtered by type.
GET /v3/admin/core/plugin/detail Read one plugin detail with effective config and optional value metadata.
PUT /v3/admin/core/plugin/status Enable or disable a plugin.
PUT /v3/admin/core/plugin/config Update plugin configuration.

These endpoints are Admin APIs and require console-scoped authorization as defined by the HTTP Authorization Spec. Plugin management must use the standard v3 response and error model.

Design Requirements

Plugin implementations must follow these rules:

  • Use existing Nacos resource identifiers and domain models instead of inventing an incompatible model for the same resource.
  • Preserve v3 HTTP API response, error, and authorization conventions for any plugin-provided HTTP APIs.
  • Expose only plugin-owned configuration through PluginConfigSpec.
  • Keep cluster-wide state changes synchronized unless the caller explicitly requests a local-only operation for diagnosis or emergency handling.
  • Document security-sensitive defaults and deployment requirements in the plugin implementation spec.

The plugin mechanism is an extension boundary, not a license to bypass Nacos resource, API, or security rules.