> ## Documentation Index
> Fetch the complete documentation index at: https://docs.binarly.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Rulesets

> Package and push your detection rules to the Binarly Registry as OCI artifacts.

A Ruleset is a collection of detection rules packaged as an OCI artifact and stored in the Binarly Registry. Rulesets are the unit of deployment — you deploy Rulesets, not individual rules. A Ruleset can contain YARA rules, FwHunt rules, or a mix of both.

## Prerequisites

Rulesets are pushed using [oras](https://oras.land/) (OCI Registry As Storage), a CLI tool for pushing and pulling OCI artifacts. Install it before proceeding:

<Tabs>
  <Tab title="macOS">
    ```bash theme={null}
    brew install oras
    ```
  </Tab>

  <Tab title="Linux">
    ```bash theme={null}
    VERSION="1.2.0"
    curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz"
    sudo tar -zxf oras_${VERSION}_linux_amd64.tar.gz -C /usr/local/bin oras
    ```

    Check the [oras releases page](https://github.com/oras-project/oras/releases) for a newer version before installing.
  </Tab>

  <Tab title="Windows">
    ```powershell theme={null}
    winget install oras
    ```
  </Tab>
</Tabs>

## Directory structure

Organize your rules in a directory before pushing. You can use any folder structure — oras will push the entire directory tree as a single artifact.

```
my-ruleset/
├── yara/
│   ├── threat_hunting.yar
│   └── supply_chain.yar
└── fwhunt/
    ├── smm_callouts.yaml
    └── uefi_implants.yaml
```

Rules do not need to be separated by type, but grouping them makes the Ruleset easier to navigate in the Playground.

## Writing rules

<Tabs>
  <Tab title="YARA">
    YARA rules follow the standard YARA format. This example detects an embedded PE file with a suspicious import:

    ```yara theme={null}
    rule SuspiciousEmbeddedPE : firmware
    {
        meta:
            description = "Detects embedded PE with remote thread creation capability"
            author      = "security-team"
            date        = "2026-01-01"
        strings:
            $mz              = { 4D 5A }
            $remote_thread   = "CreateRemoteThread" wide ascii
            $debug_priv      = "SeDebugPrivilege" wide ascii
        condition:
            $mz at 0 and any of ($remote_thread, $debug_priv)
    }
    ```

    See the [YARA documentation](https://yara.readthedocs.io/) for the full rule syntax.
  </Tab>

  <Tab title="FwHunt">
    FwHunt rules are YAML-based and target UEFI firmware binaries. This example matches a module by its GUID and checks for a known-bad code pattern:

    ```yaml theme={null}
    name: FWHUNT_EXAMPLE_SMM_CALLOUT
    version: "1.0"
    description: "Detects SMM callout via NVRAM variable in a specific module"
    rules:
      - rule:
          guid: "7C436110-AB2A-4BBB-A880-FE41995C9F82"
          strings:
            - name: callout_pattern
              value: "GetVariable"
          wide: false
          condition: any
    ```

    See the [FwHunt documentation](https://github.com/binarly-io/FwHunt) for the full rule specification.
  </Tab>
</Tabs>

## Pushing a Ruleset

<Steps>
  <Step title="Find your registry hostname">
    Your registry hostname is derived from your platform URL. If your platform is at `app.{instance}.binarly.cloud`, your registry is at `registry.{instance}.binarly.cloud`. For example, if you access the platform at `app.i7sydgb4.binarly.cloud`, your registry hostname is `registry.i7sydgb4.binarly.cloud`.
  </Step>

  <Step title="Log in to the Binarly Registry">
    Use your Binarly account email and password.

    ```bash theme={null}
    oras login registry.{instance}.binarly.cloud -u your@email.com -p <YOUR_PASSWORD>
    ```
  </Step>

  <Step title="Push the Ruleset">
    From the parent directory of your rules folder, push its contents to the registry. Use a meaningful name and tag to identify the Ruleset version.

    ```bash theme={null}
    oras push registry.{instance}.binarly.cloud/<ruleset-name>:latest ./my-ruleset/
    ```

    To tag a specific version instead of overwriting `latest`:

    ```bash theme={null}
    oras push registry.{instance}.binarly.cloud/<ruleset-name>:v1.2.0 ./my-ruleset/
    ```
  </Step>

  <Step title="Verify in the platform">
    After a successful push, the Ruleset appears in **Rules → Rulesets**. From there you can open it in the [Playground](/user-guides/rule-management/playground) to test individual rules, or [deploy it](/user-guides/rule-management/deployments) to run on scans.
  </Step>
</Steps>

## Updating a Ruleset

Push to the same name with an updated tag. The platform tracks Ruleset versions — previous versions remain accessible and findings already generated from them are linked to the rule revision that produced them.

```bash theme={null}
# Update the latest tag
oras push registry.{instance}.binarly.cloud/<ruleset-name>:latest ./my-ruleset/

# Or tag a new explicit version
oras push registry.{instance}.binarly.cloud/<ruleset-name>:v1.3.0 ./my-ruleset/
```

<Note>
  Findings generated from an earlier version of a Ruleset remain visible and continue to link to the specific rule revision that produced them, even after the Ruleset is updated.
</Note>

## Other useful commands

### List Rulesets

```bash theme={null}
oras repo ls registry.{instance}.binarly.cloud
```

### List tags

```bash theme={null}
oras repo tags registry.{instance}.binarly.cloud/<ruleset-name>
```

### Pull a Ruleset

Download a Ruleset to inspect or modify it locally:

```bash theme={null}
oras pull registry.{instance}.binarly.cloud/<ruleset-name>:v1.2.0 -o ./my-ruleset/
```

### Re-tag without re-pushing

Promote a specific version to `latest` without uploading the files again:

```bash theme={null}
oras tag registry.{instance}.binarly.cloud/<ruleset-name>:v1.2.0 latest
```

### Log out

```bash theme={null}
oras logout registry.{instance}.binarly.cloud
```
