Scrydon
Integrations

Delivering & Managing Custom Integrations

Deliver custom integrations through packs (Git/OCI sources), and manage installed integrations

Manual tarball upload has been removed. Custom integrations are now delivered exclusively through packs — a Git or OCI source your CI/CD publishes to, installed from your org's pack catalog. Publish your .bundle.tar.gz inside a pack instead of uploading it directly. See Pack sources and Packaging a custom integration in a pack.

Custom Integration Scopes

Integration identities reserve three scopes. Organization uploads are the currently supported custom-integration path:

ScopeOriginVisibilityHow it's delivered
First-party (org:scrydon:)Baked into the Docker imageAll organizationsShipped with Scrydon releases
Platform (org:platform:)Reserved for a platform-scoped packAll organizationsNot currently enabled; requires dedicated platform-owned artifact storage
Organization (org:{orgId}:)Org pack sourceSingle organizationOrg admin installs from the org's pack catalog

Every organization-installed tool has a platform microVM floor. Only exact reviewed code shipped by Scrydon may use the approved Worker Thread tool backend; a matching vendor name never grants uploaded code that trust. A custom tool is selectable by an isolated Agent only while the exact Runtime Plane backend is qualified and attested.

Delivering via a pack source

Publish your built .bundle.tar.gz as an integration content entry inside a pack, to a Git or OCI source your CI/CD controls. See Packaging a custom integration in a pack.

Go to Settings > Platform > Integrations → the Custom tab (direct URL: /settings/platform/integrations#custom) and register your pack source. Sources sync packs into your org's pack catalog. See Pack sources.

Synced custom integrations appear in Add Integration under From your pack catalog — adding one installs and activates it immediately (your explicit install is the review). A cosign-signed source is also trusted for non-interactive installs; unsigned automated syncs land as Pending Review.

When a new artifact is published, the card shows an Update badge; clicking it takes you to Settings → Platform → Packs where you can review workflow impact and apply the update. See Pack version management.

What Happens on Install

When a pack carrying an integration entry is installed, the platform runs the same bundle pipeline it always has:

Extracts the .tar.gz with security checks:

  • No symlinks allowed
  • No absolute paths
  • No path traversal (../)
  • No device, FIFO, duplicate-path, or unsupported archive entries
  • A bounded entry count and bounded decompression output
  • Only allowed file extensions (.js, .js.map, .json, .svg, .png, .jpg)
  • A required dist/index.js entry point
  • Maximum extracted size: 100 MB

Validates manifest.json against the ManifestSchema (Zod):

  • Vendor ID format: /^[a-z][a-z0-9-]*$/
  • Tool IDs reference valid vendor prefixes
  • Auth credential types are valid
  • No duplicate product IDs
  • Required fields are present

Writes the artifact to blob storage:

00_organization/integration-bundles/{vendorId}/{version}/bundle.tar.gz

Registers the integration with the vendor ID, version, manifest JSON, storage key, SHA-256 hash, and scope in the org's installed-integration record (integration_bundle).

Managing Installed Custom Integrations

Statuses

StatusMeaning
ActiveCustom integration is available for use in workflows
DisabledCustom integration is installed but not available (manually disabled)
Pending ReviewInstalled from an unsigned, non-interactive pack sync — awaiting review (sign the source or install explicitly to activate)
FailedCustom integration failed to load at runtime (check error message)

Enable / Disable

Enable or disable a custom integration's products from the vendor detail dialog under Settings > Platform > Integrations. Disabling removes it from the workflow editor but does not delete the stored files.

Versioning

Publish a new pack version to update the integration. The platform stores each version by {vendorId}/{version}/, so multiple versions can coexist; the live version is the semver-max active one (or the pinned version if your org pinned one — see Pack version management).

Uninstalling or superseding a custom integration will break any workflows that reference its tools. Verify no workflows depend on it first.

Catalog and Execution Sequence

When the platform starts:

  1. Scan first-party bundles — parse manifest.json from /app/bundles/ (Docker image)
  2. Scan platform bundles — parse manifests from platform storage
  3. Scan org bundles — parse manifests from each organization's storage
  4. Populate Manifest Catalog — metadata only, no vendor code loaded
  5. Publish dynamic readiness — the Runtime Plane reports whether the exact digest-pinned vendor profile has current candidate and deployment proof
  6. Admit on demand — the compiler exposes a custom Agent tool only when its verified SHA-256 source and exact backend pass the security floor
  7. Execute once — the trusted broker revalidates tenant, environment, connection, source, policy, and binding revisions, then starts a fresh vendor_bundle microVM

Custom integration code is never loaded on the Agentic/API host at boot. The platform reads manifest metadata only. At execution, the active archive bytes are re-hashed, transferred through a one-use sealed grant, unpacked inside the vendor guest, and deleted with that single-use VM. The Agent's own agent_turn VM never receives the archive or reusable credentials.

Agent tool readiness

For an isolated Agent, a non-Scrydon tool is available only when all of these are true:

  • the active archive has a verified SHA-256 identity and still matches the compiled source revision;
  • the authenticated Runtime Plane supports the vendor_bundle contract;
  • runner, broker, and enforcer images are digest-pinned;
  • a schedulable Kata/KVM substrate is observed;
  • signed exact-candidate and deployment proofs match the configured images, profile, and evidence digests;
  • actual-request egress, outbound DLP, and audit are ready; and
  • the encrypted one-use grant store is ready.

Any missing condition produces a typed remediation error. The platform never degrades an organization-installed Agent tool to a Worker Thread.

Organization Policies

Organization policies (configured by admins) govern custom integration behavior:

Execution Policy

{
  "maxConcurrentExecutions": 10,
  "maxTimeoutSeconds": 30,
  "allowedCapabilities": ["llm", "stt", "tools"]
}

Governance Policy

{
  "allowedVendorScopes": ["scrydon", "platform"],
  "blockedVendorIds": []
}
  • blockedVendorIds — vendor IDs blocked from installing (enforced on pack install)
  • allowedCapabilities — which capability types are permitted

The legacy allowOrgUploads / requireApprovalForUploads fields governed the removed manual upload flow and no longer have any effect. Whether a pack-delivered integration activates on install is governed by source signing and the explicit-install policy (see the delivery steps above), not these fields.

Package Format

Every custom integration is packaged as a .tar.gz archive with this structure:

{vendorId}-{version}.bundle.tar.gz
├── manifest.json           (vendor metadata, JSON Schemas, UI definitions)
├── dist/
│   └── index.js            (compiled, minified ESM; all dependencies inlined)
├── meta/                   (automatically generated)
│   ├── sbom.cdx.json       (CycloneDX 1.6 SBOM)
│   └── metafile.json       (esbuild dependency graph)
└── assets/                 (optional)
    └── icon.svg, icon.png  (vendor/product icons)

SBOM Generation

Every custom integration artifact automatically includes a CycloneDX 1.6 Software Bill of Materials (SBOM) at meta/sbom.cdx.json. The SBOM is generated during sdk-authoring integrations build with no additional tools or configuration required.

What's in the SBOM

The SBOM lists every NPM package that esbuild bundled into dist/index.js:

  • Package name and version — exactly what's in the bundle
  • License — SPDX license identifier from package.json
  • Package URL (purl) — machine-readable identifier (pkg:npm/zod@3.24.0)
  • Evidence — file paths proving the package is actually bundled (tree-shaken code is excluded)

The SBOM only includes packages that esbuild actually bundled. If a dependency was tree-shaken away, it won't appear — making the SBOM an accurate reflection of what ships in your bundle.

How it's generated

During sdk-authoring integrations build, the CLI:

  1. Runs esbuild with metafile: true to capture all input files
  2. Extracts unique NPM packages from node_modules/ paths in the metafile
  3. Reads each package's package.json for name, version, license, and description
  4. Serializes everything to CycloneDX 1.6 JSON
  5. Writes the result to meta/sbom.cdx.json alongside the esbuild metafile

No external tools or dependencies are required — the generation is built into the CLI.

How admins use it

After installing a custom integration, the Dependencies tab in the vendor detail dialog shows the SBOM component count in the tab header and lists all auto-detected packages alongside declared dependencies. See Custom Integration Review Before Activation for the full review workflow.

Compliance

The CycloneDX format is widely supported by compliance tools. For environments that require SPDX, convert using:

cyclonedx-cli convert --input-file meta/sbom.cdx.json --output-file sbom.spdx.json --output-format spdxjson

The raw esbuild dependency graph is also available at meta/metafile.json for debugging. You can visualize it at esbuild.github.io/analyze.

Custom Integration Review Before Activation

After a custom integration is installed, administrators can review its contents before enabling it for the organization. The vendor detail dialog provides a structured review experience across multiple tabs.

Capabilities Tab

Shows all products, tools, triggers, and runtime capabilities the custom integration provides. Administrators can enable or disable individual blocks from this tab. Intelligence capabilities (LLM, STT, TTS, Embedding) display model counts and support allowlist-mode policy configuration. See Capabilities for details.

Dependencies Tab

The Dependencies tab displays two complementary views of the custom integration's dependency tree:

  • Declared dependencies — Hand-authored entries from defineProduct({ dependencies: [...] }) that include a human-readable reason for each dependency.
  • Auto-detected dependencies (SBOM) — The full set of NPM packages that esbuild bundled into dist/index.js, extracted from meta/sbom.cdx.json. Each entry shows the package name, version, license, and a machine-readable package URL (purl).

The tab header shows the total SBOM component count so administrators can quickly gauge the custom integration's dependency footprint. Organization dependency policies (risk levels, blocklists, post-install script blocking) are evaluated against both declared and auto-detected dependencies.

If a dependency is blocked by the organization's policy, it is flagged in the Dependencies tab with the reason (e.g., "Risk 'high' exceeds max 'medium'" or "Has post-install scripts"). Blocked dependencies prevent the custom integration from being activated until the policy is adjusted or the .bundle.tar.gz is rebuilt without the offending package.

Setup Tab

Shows the vendor's authentication configuration (OAuth, API Key, Bot Token, or None) and allows administrators to configure credentials before enabling the vendor's capabilities.

Storage Layout

First-party (baked into Docker image):
  /app/bundles/{vendorId}/dist/index.js

Platform uploads:
  {platformPrefix}/integration-bundles/{vendorId}/{version}/bundle.tar.gz

Org uploads:
  {storageKeyPrefix}/00_organization/integration-bundles/{vendorId}/{version}/bundle.tar.gz

Troubleshooting

Install fails with "Invalid manifest"

Run the CLI validator locally before publishing the pack to see detailed errors:

bunx @scrydon/sdk-authoring integrations test --level static

Common issues:

  • Vendor ID contains uppercase or special characters
  • Tool ID doesn't start with the vendor ID prefix
  • Missing required fields (id, name, version, icon, auth)
  • Zod schema uses unsupported types (the extractor converts Zod → JSON Schema)

Custom integration status shows "Failed"

Check the error message in the vendor detail dialog (and server logs). Common causes:

  • dist/index.js has a syntax error
  • Default export is not a defineVendor() result
  • Missing export default statement
  • Runtime import fails (ensure all deps are bundled — esbuild should inline them)

Tool doesn't appear in the workflow editor

  1. Verify the pack that carries the integration is installed (Settings > Platform > Packs) and its version is active
  2. Verify the product is enabled for your organization in Settings > Platform > Integrations
  3. Check the block's category — it must be "tools", "blocks", or "triggers" to appear in the correct palette section

Build warns that block tool configuration will be omitted

tools.config.tool and tools.config.params are functions, so they cannot be represented in manifest.json. Replace dynamic routing with tools.toolSelector, expose direct parameters as block inputs, and move any remaining parameter coercion into the tool's execute() function. Do not ignore this warning: an installed workflow block only has the JSON-safe manifest definition at serialization time.

On this page

On this page