Synadia Protect

Bundles

A bundle is a versioned collection of rules packaged as a release unit. Bundles are the mechanism for deploying security policies to the gateway.

Concepts

  • A bundle has a name and a version
  • It contains one or more rules — either built-in rules configured via .conf files, or custom rules written in .yaml files
  • Bundles can optionally be signed with an NKey — the gateway can be configured to only accept bundles signed by trusted identities. This feature coupled with the internal integrity checks ensures that the artifact has not been tampered with.
  • Only one bundle instance of a given bundle name can be active on a given port
  • Different ports could have different versions of the same bundle active
  • Avoid conflicting rules on the same port

Lifecycle

create → install → activate → (upgrade) → deactivate → uninstall
StepDescription
createpackage rules into a bundle file
installupload the bundle to the gateway (validated but not yet active)
activatedeploy the bundle on a specific port
upgradereplace the active bundle on a port with a different version
deactivateremove the bundle from a port (rules stop evaluating)
uninstallpermanently remove the bundle from the gateway

Built-in rules

The gateway ships with built-in rules covering common use cases. List them with:

$ protect admin bundle builtins list --local

Built-in rules follow a naming convention:

com.synadia.protect.builtins.v1.<action>.<category>.<type>

Where action is allow, deny, or suspend; category describes what the rule inspects; and type is connect or message.

Get details on any built-in rule:

$ protect admin bundle builtins info --local <rule-id>

See the built-in rules reference for full documentation on each rule.

Creating a bundle

1. Write a configuration file

Create a directory for the bundle and add a .conf file that activates and configures the built-in rules:

$ mkdir mybundle

Create mybundle/deny-sensitive-payloads.conf:

activations:
  com.synadia.protect.builtins.v1.deny.payload.message: true

configurations:
  com.synadia.protect.builtins.v1.deny.payload.message:
    'logs.>': '(?i)password|secret|api_key'

The activation section declares which built-in rules to enable. The configuration section provides settings for each activated rule.

In the example above, the config activates and configures the deny payload rule — any message published to logs.> with a payload matching password, secret, or api_key (case-insensitive) will be denied.

A single .conf file can activate and configure multiple built-in rules. For example, adding a header check and a time restriction:

activations:
  com.synadia.protect.builtins.v1.deny.payload.message: true
  com.synadia.protect.builtins.v1.allow.header.message: true
  com.synadia.protect.builtins.v1.deny.time.message: true

configurations:
  com.synadia.protect.builtins.v1.deny.payload.message:
    'logs.>': '(?i)password|secret|api_key'
  com.synadia.protect.builtins.v1.allow.header.message:
    X-Tenant: '^acme$'
  com.synadia.protect.builtins.v1.deny.time.message:
    - schedule: '* 0-9 * * *'
      subject: 'orders.>'
    - schedule: '* 17-23 * * *'
      subject: 'orders.>'

2. Create the bundle

$ protect admin bundle create --name mybundle mybundle 1.0.0
Successfully created bundle: mybundle-1.0.0.zip

The first positional argument is the directory containing the rule files, the second is the version.

To sign the bundle, add --signer-key my_gateway/bundle-signer.nk. If the gateway has trusted_bundle_signers configured, unsigned bundles will be rejected on install.

3. Install the bundle

$ protect admin --context admin bundle install mybundle-1.0.0.zip
Successfully installed bundle: mybundle@1.0.0

The gateway validates the bundle (and verifies the signature if trusted_bundle_signers is configured) but does not activate it yet.

List installed bundles:

$ protect admin --context admin bundle list
╭─────────────────────────────────────────────────────────────────────────────────────╮
│                                  Installed Bundles                                  │
├──────────┬─────────┬───────────────────────────┬───────────────────────────┬────────┤
│ Name     │ Version │ Created                   │ Installed                 │ Active │
├──────────┼─────────┼───────────────────────────┼───────────────────────────┼────────┤
│ mybundle │ 1.0.0   │ 2026-04-03T15:16:04-05:00 │ 2026-04-03T15:16:11-05:00 │        │
╰──────────┴─────────┴───────────────────────────┴───────────────────────────┴────────╯

Installation copies the artifact to internal storage, verifies the bundle was issued by a trusted signer, checks internal integrity, and validates that the bundle can be activated. It does not activate the bundle — activation maps a bundle to a port and installs a runnable version so its rules process protocol traffic.

4. Activate the bundle on a port

Activating a bundle requires three parameters: the port name (or * for all ports), a bundle name, and a version. The port name refers to the named entry point defined in your gateway configuration (e.g., clients), not a TCP port number. Use protect admin --context admin bundle ports to list available port names.

Only one version of a given bundle can be active on a port.

$ protect admin --context admin bundle activate clients mybundle 1.0.0
Successfully activated bundle: mybundle@1.0.0 on port "clients"

The bundle is now evaluating traffic on the clients port:

$ protect admin --context admin bundle list
╭──────────────────────────────────────────────────────────────────────────────────────╮
│                                   Installed Bundles                                  │
├──────────┬─────────┬───────────────────────────┬───────────────────────────┬─────────┤
│ Name     │ Version │ Created                   │ Installed                 │ Active  │
├──────────┼─────────┼───────────────────────────┼───────────────────────────┼─────────┤
│ mybundle │ 1.0.0   │ 2026-04-03T15:16:04-05:00 │ 2026-04-03T15:16:11-05:00 │ clients │
╰──────────┴─────────┴───────────────────────────┴───────────────────────────┴─────────╯

Upgrading a bundle

Create a new version with updated rules, install it, then run the upgrade to change the version running on the port. You can "upgrade" to a lower version too.

$ protect admin bundle create --name mybundle --signer-key my_gateway/bundle-signer.nk mybundle 1.1.0
$ protect admin --context admin bundle install mybundle-1.1.0.zip
$ protect admin --context admin bundle upgrade clients mybundle 1.1.0
Successfully upgraded bundle: mybundle from mybundle@1.0.0 to mybundle@1.1.0 on port "clients"

Deactivating and uninstalling

Remove a bundle from the list of rules that a port uses to evaluate traffic, deactivate it.

$ protect admin --context admin bundle deactivate clients mybundle 1.0.0
Successfully deactivated bundle: mybundle@1.0.0 on port "clients"

Remove a bundle from the gateway entirely:

$ protect admin --context admin bundle uninstall mybundle 1.0.0
Successfully uninstalled bundle: mybundle@1.0.0

A bundle must be deactivated from all ports before it can be uninstalled.

Uninstalling a bundle permanently deletes it from the gateway. There is no separate "delete" command — uninstall is the deletion. To preserve a history of deployed artifacts, keep bundles installed even when inactive.

Bundle structure

A bundle is a ZIP file containing rules, configuration, metadata, and integrity checksums:

mybundle-1.0.0.zip
├── config/deny-sensitive-payloads.conf   # built-in rule configurations
├── rules/client_connect.yaml            # custom rules (if any)
├── MANIFEST                             # bundle metadata (name, version, date)
├── RULESBOM.json                        # rule bill of materials
├── SHA256SUMS                           # checksums for every file
└── SHA256SUMS.sig                       # signature over the checksums

Bundles containing only built-in rule configurations have files under config/. Bundles with custom rules have .yaml files under rules/. A bundle can contain both.

Inspecting a bundle

Inspect a bundle file to see its contents without installing it:

$ protect admin bundle inspect mybundle-1.0.0.zip
Bundle Information

      Version: 1.0.0
  Description:
       Signer: UDHLNCKJRIFWS4QYOMMN4EPB7UIMIHDHXSRYSDOTDW4LPDDIV3IYXSOT

Rules:

 No rules found

Files:

               MANIFEST
               RULESBOM.json
               SHA256SUMS
               SHA256SUMS.sig
               config/deny-sensitive-payloads.conf

A bundle with custom rules shows them in the Rules section:

$ protect admin bundle inspect myrules-1.0.0.zip
Bundle Information

      Version: 1.0.0
  Description:
       Signer: UDHLNCKJRIFWS4QYOMMN4EPB7UIMIHDHXSRYSDOTDW4LPDDIV3IYXSOT

Rules:

               rules/client_connect.yaml

Files:

               MANIFEST
               RULESBOM.json
               SHA256SUMS
               SHA256SUMS.sig
               rules/client_connect.yaml

Use --json for machine-readable output.

Verifying a bundle

Bundles are checksummed and signed. Each file is checksummed into SHA256SUMS, and SHA256SUMS is signed into SHA256SUMS.sig. Any modification to the bundle after creation will be detected:

$ protect admin bundle verify mybundle-1.0.0.zip
Bundle verification successful: mybundle-1.0.0.zip

If the bundle has been tampered with:

$ protect admin bundle verify mybundle-1.0.0.zip
protect: error: failed to load bundle: bundle validation: checksum mismatch for "MANIFEST": expected "494e6d35..." got "faac746d..."

To verify against a specific public key:

$ protect admin bundle verify --public-key <public-nkey> mybundle-1.0.0.zip

Listing available ports

List the ports where bundles can be activated:

$ protect admin --context admin bundle ports
╭─────────╮
│  Ports  │
├─────────┤
│ Name    │
├─────────┤
│ clients │
╰─────────╯

Downloading installed bundles

Download a bundle that is already installed on the gateway:

$ protect admin --context admin bundle download mybundle 1.0.0 --output mybundle-downloaded.zip
Downloading bundle mybundle 1.0.0 to mybundle-downloaded.zip...
Successfully downloaded bundle to: mybundle-downloaded.zip

This retrieves the exact binary image of the bundle that was installed.

Bundle signing

Bundle signing is opt-in but recommended. When the gateway has trusted_bundle_signers configured, it only accepts bundles signed by the listed identities. This is a tamper-proof mechanism ensuring bundles have not been modified on their way to installation.

Removing a trusted signer from the gateway's configuration revokes all bundles issued by that identity. The gateway will auto-deactivate those bundles.

Sign a bundle at creation time:

$ protect admin bundle create --name mybundle --signer-key my_gateway/bundle-signer.nk mybundle 1.0.0

The my_gateway/bundle-signer.nk file contains the private NKey seed. The corresponding public key must be listed in the gateway's rules.trusted_bundle_signers.

Verify a bundle's signature:

$ protect admin bundle verify mybundle-1.0.0.zip
Previous
Rules
Next
UI