The three pieces
1
Declare a credentials schema
A
BaseCredentials subclass with a type and one Parameter per field.
Mask secrets with ConfigPassword. Override is_ready() to say when the
credential is usable.2
Declare the integration
A
BaseIntegration[YourCredentials] subclass — display_name and image.
Optionally override is_ready to probe the service for real.3
Bind it on a node
Set
integrations = {"<type>": ["<field>", ...]} on the node, and read the
injected credentials with ctx.get_integration_credentials("<type>").Defining credentials and the integration
BaseCredentials and BaseIntegration come from noxus_sdk.integrations.base;
the field widgets from noxus_sdk.ncl. The credential’s type string is the id
nodes bind to and the key the platform stores credentials under.
type is derived automatically from the
credentials class, and the field widgets render the connect form in workspace
settings. Return the integration from your plugin’s integrations():
Live readiness checks
BaseIntegration.is_ready defaults to “the fields validate and
credentials.is_ready() is true”. Override it (async) to probe the service, so
readiness reflects real authorization rather than just filled-in fields — as the
ClipOne integration does:
Binding an integration on a node
A node lists the credentials it needs inintegrations — a mapping of the
credential type to the field names it consumes — and reads them from ctx. The
platform shows a credential picker for that type on the node and injects the
selected workspace credential into the call.
Read credentials from
ctx at call time — never cache them across calls. They
are per-workspace and may differ between runs. If a required credential is
missing, raise IntegrationFailedError from noxus_sdk.errors so the user sees
an actionable message.Development Flow
1
Model the credentials
Decide the fields (URL, key, tenant, …). Mask every secret with
ConfigPassword. Implement is_ready() on the credentials.2
Build the client layer
A robust async client (e.g.
httpx) with retries and typed parsing. Import
heavy deps inside call/helpers, not at module top — manifest generation
imports your module in a lightweight environment.3
Expose nodes
Add nodes that bind the integration via
integrations={...} and read ctx.4
Probe readiness
Override
is_ready to hit the real service so the workspace UI shows accurate
connection status.Security & Isolation
- No platform credential enters the sandbox. Only the workspace-scoped integration credentials the node declared are injected, and only for the calling workspace.
- Per-workspace boundary. A plugin cannot read another tenant’s credentials or
files; the single-use call token scopes every callback to
ctx.group_id.
Configurable Plugins
Add plugin-level config, node config, and dynamic config to your integration.