# Rego Packages

Rego Packages let you define shared Rego helper functions and data sets once and import them into any number of governance policies. When a package is updated, every policy that imports it automatically uses the new logic at its next evaluation — no per-policy edits required.

This is useful whenever the same logic needs to be enforced across multiple policies: tag validation helpers, approved resource lists, account classification rules, and similar shared constructs.

***

## How Rego Packages Work

Each package is a named module of Rego code stored under the `firefly.packages` namespace. A package named `tag_validator` is imported in a policy as:

```rego
import data.firefly.packages.tag_validator
```

At policy evaluation time, Firefly resolves all imported packages automatically. The latest version of each package is always used; there is no need to re-save a policy when a package is updated.

***

## Package Naming Rules

Package names must be valid Rego identifiers:

* Start with a letter (`a–z`, `A–Z`) or underscore (`_`)
* Followed by any combination of letters, digits, or underscores
* Maximum 128 characters
* Must be unique within your account

| Valid examples  | Invalid examples                |
| --------------- | ------------------------------- |
| `aws_helpers`   | `aws.helpers` (dot not allowed) |
| `IamChecks`     | `123check` (starts with digit)  |
| `tag_validator` | `my-pkg` (hyphen not allowed)   |
| `_internal`     | `http.send` (dot not allowed)   |

> **Note:** Package names cannot be changed after a package is created.

***

## Package Code Constraints

Package code is a standalone Rego module. It must follow these rules:

| Rule                  | Requirement                                                                         |
| --------------------- | ----------------------------------------------------------------------------------- |
| `package` declaration | Must **not** be included — Firefly injects it automatically                         |
| `import` statements   | Must **not** be included — packages are standalone and cannot import other packages |
| Restricted built-ins  | `http.send` and `opa.runtime` are not permitted                                     |
| Maximum size          | 50 KB                                                                               |
| Maximum line length   | 1,000 characters per line                                                           |
| Valid Rego            | Code must compile as valid OPA Rego                                                 |

The Rego editor validates your code in real time as you type, so you can catch errors before saving.

***

## Managing Packages

### Viewing Your Packages

Navigate to **Governance** and select **Policy Packages** from the menu. The list page shows all packages for your account, with columns for name and description. You can search by name or description using the search bar.

### Creating a Package

1. On the **Policy Packages** page, click the **Add Policy Package** button (top right).
2. In the **Package Details** section:
   * **Package Name** (required) — enter a name that follows the [naming rules](#package-naming-rules) above. This cannot be changed after the package is created.
   * **Description** (optional) — a plain-text description of what the package provides.
3. In the **Rego Code** section, write your package logic in the editor. Do not include a `package` declaration or any `import` statements.
   * The editor validates your code in real time. A **✓ Rego code is valid** indicator appears when the code compiles successfully.
4. Click **Create**. A confirmation message confirms the package was saved and you are returned to the package list.

**Example package code** — a set of tag validation helpers:

```rego
# Returns true if the resource has the specified tag key.
has_tag(resource, key) {
  resource.tags[key]
}

# Returns true if the resource has all of the specified tag keys.
has_all_tags(resource, keys) {
  count([k | k := keys[_]; has_tag(resource, k)]) == count(keys)
}
```

### Editing a Package

1. On the **Policy Packages** page, click the row actions menu (**⋮**) next to the package and select **Edit**.
2. Update the description or Rego code as needed. The package name cannot be changed.
3. Click **Save**. All policies that import this package will use the updated code at their next evaluation — no changes to those policies are required.

### Deleting a Package

1. On the **Policy Packages** page, click the row actions menu (**⋮**) next to the package and select **Delete**, or use the **Delete** button on the package edit page.
2. Confirm the deletion in the dialog that appears.

> **Warning:** Deleting a package is immediate and permanent. If any policies still contain an `import data.firefly.packages.<name>` statement for the deleted package, those policies will fail to compile at their next evaluation. Remove the import from any referencing policies before deleting a package.

***

## Using Packages in Policies

### Adding an Import

To use a package in a policy, add an import statement at the top of the policy's Rego code, after any existing imports:

```rego
import data.firefly.packages.<package_name>
```

Replace `<package_name>` with the exact name of the package you want to use. You must add this import to each policy that needs the package.

### Using Package Functions in Policy Rules

Once the import is in place, call the package's functions or reference its data using the package name as a prefix:

```rego
import data.firefly.packages.tag_validator

default firefly = false

firefly {
  tag_validator.has_all_tags(input, ["team", "env", "owner"])
}
```

### Import Validation

As you edit a policy's Rego code, Firefly automatically validates that every `import data.firefly.packages.*` statement refers to a package that exists in your account. If a referenced package is not found, a warning is shown in the editor. This check runs automatically as you type.

***

## Required Permissions

| Action                                      | Required Permission |
| ------------------------------------------- | ------------------- |
| View the package list or a specific package | `governance:read`   |
| Create a package                            | `governance:create` |
| Edit a package                              | `governance:update` |
| Delete a package                            | `governance:delete` |

For information on configuring roles and permissions, see [Access Management (RBAC)](https://docs.firefly.ai/getting-started/access-management-rbac).
