Scrydon
Integrations

Pack Sources

Automatically sync packs from your own Git repositories and OCI registries into your Scrydon installation.

Pack sources let your developers push packs to infrastructure they already control — a Git repository or an OCI registry — and have your Scrydon installation pick them up automatically on a schedule. No inbound traffic, no manual uploads for every release.

When to use pack sources vs. manual upload

Use pack sources when you have developers who push pack updates from CI and want those updates to land in Scrydon without an administrator running a manual upload for each release. Use manual upload for one-off testing, air-gapped environments, or packs with no automated publish step.

How It Works

Your Scrydon installation runs a reconciler that polls each registered source on a configurable interval (default 5 minutes, minimum 30 seconds). On each tick it:

  1. Fetches the scrydon.yaml catalog file from your source.
  2. Compares it against the previously installed versions.
  3. For each new or changed entry: fetches the artifact, verifies its signature, and installs it through the same pipeline as a manual upload.
  4. Records the result — success or detailed failure reason — in the source's run history.

The reconciler is pull-only. Your CI pipeline never needs inbound access to your Scrydon cluster.

The source catalog wins

The scrydon.yaml catalog file is the source of truth for which packs appear in your organization's catalog. If an administrator retires a source-managed pack from the catalog UI, the next sync restores it as long as it is still listed in scrydon.yaml — the same way re-uploading a retired pack manually brings it back. To remove a source-managed pack permanently:

  • remove its entry from the source's scrydon.yaml, or
  • disable (or delete) the source itself.

Retiring is still useful for manually uploaded packs (no source manages them, so they stay retired) and as a temporary hide for source-managed packs between syncs.

Choosing a Source Type

Source typeBest for
GitTeams that version pack contents directly in a Git repository and don't want to run a container registry
OCITeams that publish pack artifacts as OCI images (e.g. to GHCR) as part of their release pipeline

You can register multiple sources of either type per organization.

The scrydon.yaml Catalog File

Every source is described by a single scrydon.yaml file at a configurable path in your repository or registry. This file is the source of truth for which packs should be installed and at what version.

apiVersion: scrydon.io/v1
kind: PackCatalog
packs:
  - id: example.sample
    version: 1.0.0
    artifact:
      kind: git-tar
      ref: main
      path: packs/sample
    signature:
      kind: none

  - id: example.fraud
    version: 1.2.0
    artifact:
      kind: oci
      ref: ghcr.io/example/scrydon-fraud@sha256:abc123def456...
    signature:
      kind: cosign-keyless
      certificateIdentityRegexp: "https://github.com/example/.*"
      certificateOidcIssuer: "https://token.actions.githubusercontent.com"

Pack catalog fields

FieldRequiredDescription
idYesUnique pack identifier, dotted lowercase (e.g. acme.fraud). Combined with version it identifies a pack installation.
versionYesSemver string. The reconciler keys on this field — a release is only picked up when this entry is bumped, even if pack.json and the artifacts changed. See Pack versioning for the full release checklist.
artifact.kindYesgit-tar or oci.
artifact.refYesFor git-tar: the branch, tag, or commit ref to check out. For oci: the full image reference — prefer @sha256:… digests over mutable tags.
artifact.pathgit-tar onlySubdirectory inside the repository to package.
signature.kindYescosign-keyless, cosign-key, or none.

Unknown keys in scrydon.yaml are rejected. Typos in field names cause a parse_failed error — check the source's run history for details.

Publishing from CI

Git source layout

For a Git source, your repository contains the scrydon.yaml catalog alongside your pack directories. The reconciler packs the declared subdirectory at the configured ref into a .scrydon-pack.tar.gz on the fly.

Minimal layout:

my-packs/
├── scrydon.yaml          # Pack catalog
├── packs/
│   └── fraud/            # Pack directory — each has a pack.json
│       ├── pack.json
│       └── ontology/
│           └── manifest.json
└── .github/
    └── workflows/
        └── validate.yml  # Validates scrydon.yaml on every PR

Validate scrydon.yaml on pull requests so catalog errors are caught before they reach your Scrydon installation:

# .github/workflows/validate.yml
name: validate-catalog
on:
  pull_request:
    paths: ['scrydon.yaml', 'packs/**']
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v2
      - name: Validate catalog schema
        run: |
          bunx @scrydon/sdk-authoring sources validate scrydon.yaml

OCI source layout

For an OCI source, your CI pipeline builds a .scrydon-pack.tar.gz for each pack, pushes it as an OCI artifact, signs it with cosign, and updates the scrydon.yaml catalog (also pushed as an OCI artifact).

Your workflow needs cosign for signing and oras for pushing generic OCI artifacts:

- uses: sigstore/cosign-installer@v3
- uses: oras-project/setup-oras@v1
bunx @scrydon/sdk-authoring pack build packs/fraud \
  --out dist/fraud-${{ github.ref_name }}.tar.gz
oras push ghcr.io/${{ github.repository_owner }}/scrydon-fraud:${{ github.ref_name }} \
  --artifact-type application/vnd.scrydon.pack.v1.tar.gzip \
  dist/fraud-${{ github.ref_name }}.tar.gz:application/vnd.scrydon.pack.v1.tar.gzip
COSIGN_EXPERIMENTAL=1 cosign sign --yes \
  ghcr.io/${{ github.repository_owner }}/scrydon-fraud:${{ github.ref_name }}

No secrets needed — cosign uses GitHub Actions OIDC automatically when id-token: write permission is granted.

Resolve the digest and update scrydon.yaml, then push it as the :catalog tag:

DIGEST=$(oras manifest fetch --output - \
  ghcr.io/${{ github.repository_owner }}/scrydon-fraud:${{ github.ref_name }} \
  | jq -r '.config.digest // .digest')
sed -i "s|REPLACE_WITH_DIGEST|$DIGEST|" catalog/scrydon.yaml

oras push ghcr.io/${{ github.repository_owner }}/scrydon-catalog:catalog \
  --artifact-type application/vnd.scrydon.catalog.v1+yaml \
  catalog/scrydon.yaml:application/vnd.scrydon.catalog.v1+yaml

Full working examples are in the examples/pack-sources/ directory of the Scrydon SDK repository.

Registering a Source via the Settings UI

Go to Settings > Platform > Packs, then open the Sources tab.

Fill in the source details:

FieldDescription
NameA human-readable identifier for this source (e.g. acme-pack-repo). Must be unique within your organization.
TypeGit or OCI.
URLFor Git: the HTTPS clone URL of your repository. For OCI: the registry reference (e.g. ghcr.io/acme/scrydon-catalog).
RefGit branch/tag (default: main) or OCI tag (default: catalog).
Catalog pathPath to scrydon.yaml inside the source (default: scrydon.yaml).
Access credentialOptional. For a private source, paste the credential directly (Git PAT, deploy-key PEM, or OCI username:token). It's saved as an encrypted organization secret and referenced automatically. Leave blank for public sources. See Authenticating a private source.
Signature policySee Signature Policies below.
Sync intervalHow often the reconciler checks for changes (30 seconds–1 day).

Click Test connection to verify the reconciler can reach your source and parse scrydon.yaml without persisting anything.

The source is enabled immediately. The first sync runs within one interval.

For installations managed with Helm, pack sources can also be seeded via packSources: in your chart values file. Helm-managed sources appear read-only in the UI with a "managed by chart" banner. See the Helm reference for the full schema.

Authenticating a private source

Private Git repositories and private OCI registries need a credential. Paste it straight into the source's Access credential field — Scrydon saves it as an encrypted organization secret for you and wires up the reference automatically. You never manage a separate secret by hand.

In Access credential, enter:

  • Git over HTTPS — a personal access token (PAT) with read scope on the repository.
  • Git over SSH — a deploy-key private key in PEM form (begins with -----BEGIN).
  • OCI — a username:token pair for the registry.

Click Test connection — it uses the credential you just entered (before anything is persisted), so a green result confirms it works. On Save, the credential is stored as an encrypted org secret (named pack-source-<name>) and the source references it; every sync resolves and decrypts it automatically.

To rotate, edit the source and enter a new value (leaving it blank keeps the current one). Saved credentials are never displayed again. The underlying secret is visible (and manageable) under Settings → Secrets.

Credentials are stored as organization-scoped secrets in Scrydon (LOCAL strategy). External-KMS-backed secrets (BYOK/HYOK) aren't used for pack sources yet — a source falls back to anonymous access if its credential is external or missing.

Delivering custom integrations

A pack can include an integration content entry in its pack.json. When such a pack is installed, the platform registers the custom integration alongside any other content kinds (ontology, process-flow, etc.) — no separate upload step.

Sync only places packs in your org catalog — installation is an explicit second step. The Settings → Platform → Integrations → Add Integration marketplace is where custom integrations are discovered and first installed. The Settings → Platform → Packs → Catalog tab is where you track install state across all content kinds and apply updates.

In the marketplace, synced custom integrations appear under From your pack catalog:

  • Not yet installed — shows an Add button; clicking it installs and activates the integration immediately.
  • Already installed and current — shows an Up to date indicator and remains in the pack catalog group. Clicking the card opens the vendor configuration view.
  • Update available — shows an Update badge. Clicking the action deep-links to Settings → Platform → Packs so you can review workflow impact and apply the update there. See Pack version management.

Installing a whole pack (including its non-integration content kinds such as ontology, workflows, and data sources) is done via the Install row action under Settings → Platform → Packs → Catalog.

Adding an integration from the marketplace activates it immediately — the explicit admin action is the review. Signature policy gates non-interactive flows:

Install triggerActivation status
Explicit admin install (marketplace Add/Update, catalog Install)Active
Non-interactive install, cosign-keyless / cosign-key sourceActive
Non-interactive install, unsigned artifactPending Review — approve under Integrations → Custom

Pack size limit for integration artifacts: 8 MB per bundle.tar.gz. Larger integrations must use the Manual upload door (50 MB). See the pack authoring guide for the full subdir layout and pack.json declaration.

Signature Policies

Every pack artifact must pass signature verification before it is installed. The signature policy is set per source at registration time.

PolicyUse case
cosign-keylessArtifacts signed via GitHub Actions OIDC (no key management required). Specify certificateIdentityRegexp to pin to a specific repository and certificateOidcIssuer to pin to the OIDC provider.
cosign-keyArtifacts signed with a static key pair. Provide the PEM-encoded public key.
unsigned-allowedExplicit opt-in to skip signature checks. Not recommended for production. Surfaces a permanent warning banner in the UI.
signature:
  kind: cosign-keyless
  certificateIdentityRegexp: "https://github.com/acme/scrydon-packs/.*"
  certificateOidcIssuer: "https://token.actions.githubusercontent.com"

The reconciler calls cosign verify with these constraints. The OIDC issuer and certificate identity must match exactly — a pack signed in a different repository or by a different CI system will fail verification.

For this to work, your publish workflow must request id-token: write permission and use sigstore/cosign-installer@v3.

cosign-key

signature:
  kind: cosign-key
  publicKey: |
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
    -----END PUBLIC KEY-----

Generate a key pair with cosign generate-key-pair and paste the public key above. Keep the private key in a CI secret (COSIGN_PRIVATE_KEY) and sign with cosign sign --key env://COSIGN_PRIVATE_KEY.

unsigned-allowed

Use only for local development or air-gapped lab environments where running a signing infrastructure is impractical. In scrydon.yaml, entries under a unsigned-allowed source use signature: { kind: none }.

unsigned-allowed is logged as a security event at registration time. Every sync run under this policy is also flagged in the audit log. Enable it for a production source only after explicit acceptance by your security team.

Troubleshooting

verify_failed

Signature verification failed for one or more pack artifacts.

  • Check that your publish workflow has id-token: write permission (for keyless).
  • Confirm the certificateIdentityRegexp matches the GitHub Actions run URL for your repository (e.g. https://github.com/acme/scrydon-packs/.*).
  • Confirm the certificateOidcIssuer matches the OIDC provider your CI uses (https://token.actions.githubusercontent.com for GitHub Actions).
  • For cosign-key: verify the public key in the source configuration matches the private key used to sign the artifact.
  • Check that the pack was signed after being pushed to the registry — signing a different tag or digest than the one referenced in scrydon.yaml will fail.

fetch_failed

The reconciler could not reach your source.

  • For Git sources: verify the URL is an HTTPS clone URL and that any credentials (PAT or deploy key) have read scope on the repository.
  • For OCI sources: verify the registry reference is correct and that the pull credentials have read access to the repository.
  • Verify the source is reachable from your Scrydon cluster's network. The reconciler makes outbound HTTPS requests — ensure egress is not blocked.
  • Click Test connection in Settings to get a more detailed error.

parse_failed

scrydon.yaml failed schema validation.

  • Run the validator locally: bunx @scrydon/sdk-authoring sources validate scrydon.yaml
  • Common causes: unknown keys (typos), missing required fields, invalid pack ID format (must be dotted lowercase, e.g. acme.fraud), invalid semver, artifact ref missing for OCI entries.
  • Confirm the file is valid YAML before checking the schema.

install_failed

The pack was fetched and verified but failed to install.

  • The pack bundle itself may be malformed. Test it locally: bunx @scrydon/sdk-authoring pack test packs/fraud
  • Check the run history error detail in Settings > Platform > Packs > Sources tab — click a source row (or its View history action) to open the run-history panel — for the specific pack.json validation error.
  • Confirm the pack.json package.id matches the dotted-lowercase pattern and that installOrder matches the kinds in contents.

Source shows "managed by chart" and is read-only

This source was seeded via packSources: in your Helm values. Edit the chart values to change it — do not create a duplicate UI-managed source with the same name.

Sync stops after repeated failures

After three consecutive failed runs, the reconciler backs off to double the configured interval (capped at one hour). Fix the underlying error — the backoff resets automatically on the next successful sync. Clicking Sync now in the UI resets the counter immediately.

A retired pack came back / a pack is missing from the catalog

Source-managed packs follow the source catalog: a retired pack that is still listed in scrydon.yaml is restored on the next sync (see The source catalog wins). Conversely, if a pack you expect is missing, check that it is listed in the source's scrydon.yaml, that the latest run in the source's history succeeded, and that the Sync now toast reports it as installed — then retire/restore state follows the source automatically.

On this page

On this page