> For the complete documentation index, see [llms.txt](https://docs.sealsecurity.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sealsecurity.io/using-platform/working-with-seal-apps/remote.md).

# Under Remote

In the Remote deployment method, the Seal CLI runs in remote mode inside your CI/CD pipeline and reads [remote Sealing Rules](/using-platform/sealing-rules/remote-rules.md) from the Seal Platform. The everyday work happens entirely in the Seal UI; the CI pipeline does not change between builds.

## The recurring rhythm

The four steps from [Working with the platform](/using-platform/working-with-the-platform.md), specialized for Remote:

1. **Review** the Vulnerable packages tab on the [Protection page](/discovering/protection-page.md). New rows appear after a build whose CLI step discovered a vulnerable package. Rows are tagged with the Seal Project so you can see which projects each affects.
2. **Decide what to seal.** For each row you want to seal, create a Sealing Rule through one of the [create flows](/using-platform/sealing-rules/remote-rules.md#creating-a-sealing-rule). The row's state changes from **Ready to seal** to **Pending deploy**.
3. **Let the next CI build run.** No pipeline change is needed; the next invocation of the Seal CLI in remote mode reads the rule from the platform, substitutes the sealed version, and reports back.
4. **Verify.** After the build, the row state moves to **Sealed**.

## When new vulnerabilities are disclosed against a sealed iteration

<figure><img src="/files/nHQHhTL4Lbtyy5sOaoFN" alt="Vulnerable packages tab rows showing the six package state badges"><figcaption><p>The six package states a row can be in.</p></figcaption></figure>

A package version has a row on the Vulnerable packages tab only when it is in use **and** has at least one open vulnerability. The row's state reflects what is being done about those open vulnerabilities.

Take a Seal Project that uses `sp1` to seal `ejs@2.7.4`:

* The `ejs@2.7.4` row sits in **Sealed** — the package has open vulnerabilities, but a Sealing Rule applies a sealed iteration to substitute for it. As long as a newer sealed iteration than `sp1` is in use, the row stays in **Sealed**.
* `ejs@2.7.4-sp1` itself has no row on the Vulnerable packages tab as long as it has no open vulnerabilities. It appears on the [Sealed packages tab](/discovering/protection-page/sealed-packages-tab.md) instead.

When a new vulnerability is disclosed that affects `sp1`, `sp1` gains its own row on the Vulnerable packages tab. The state of that row tracks Seal's response:

* While Seal has not yet started a new sealed iteration, the row is in **Generate available** — a customer can trigger the backport with the Generate fix action.
* Once Seal publishes `sp2`, the row moves to **Ready to seal** — the **Seal** button is available.
* Once the rule (or a new rule) substitutes `sp2`, `sp1` is no longer in use. Its row returns to **Sealed** state, because a newer sealed iteration (`sp2`) is now in use.

`sp2` does not get its own row on the Vulnerable packages tab unless it is in use and itself has open vulnerabilities — i.e., when `sp3` becomes necessary.

For a rule pinned to a specific `-sp[N]`, the `sp1`-as-vulnerable row stays in **Ready to seal** until you edit the rule to the new pin. For a rule that uses the safest sealed version (the default), the next CI build pulls `sp2` automatically once it ships, and `sp1`'s row returns to **Sealed**.

## Common situations

### A new vulnerability is disclosed in a package you already use

A row appears for the affected package version. The state depends on what Seal has so far:

* If a sealed iteration already exists that fixes the new vulnerability — for example, Seal had already started on it because a different customer hit it first — the row appears in **Ready to seal**. Create a rule as usual.
* If Seal has not yet started backporting, the row appears in **Generate available** and the customer can trigger a backport with the Generate fix action. Critical and high-severity vulnerabilities are typically picked up by Seal automatically within hours; lower-severity ones may sit in **Generate available** until a customer triggers them.
* When Seal is actively building the iteration, the row appears in **Version in progress**.

If the affected package was already sealed by a safest-version rule, every newer sealed iteration is consumed automatically on the next CI build.

### A developer adds a new vulnerable dependency

The CLI run on the PR or merge build discovers the new package. It appears on the Vulnerable packages tab on the next refresh. Treat it like any other vulnerable row.

### CI fails after a Sealing Rule change

In the overwhelming majority of cases, a CI failure that follows shortly after a Sealing Rule change has nothing to do with the substitution. It is some other change shipped in the same build cycle (a code change, a test change, a configuration update) that happens to land alongside. Check your CI logs and your commit history first.

If you still suspect the sealed version is the cause, revert the rule (delete it, or pin to the previous sealed iteration) and re-run. If the build still fails, the rule was not the source; treat it as any other regression. If the build succeeds with the rule reverted but fails with the rule in place, contact your Seal account team with the build logs and the sealed version involved — incompatibility with a sealed iteration is rare but possible (a test that depends on the package's pre-fix behavior, an internal API the package exposed that changed, and so on), and Seal will work through it with you.

### When the substitution does not happen

The row stuck at **Pending deploy** after a build that otherwise succeeded is a narrow case: the CLI step did not produce errors but also did not apply the rule. Most failure modes — a corrupt config, a network outage, a wrong token — fail the CLI outright and therefore fail the CI; those are diagnosed from the CI logs, not from the row state. The cases where a build succeeds but the rule is not applied are:

* The CLI step was not actually invoked for this build (skipped step, conditional that bypassed it, or earlier pipeline failure that fell through to a passing job).
* The CLI ran in the wrong fix mode. Remote mode is required for remote rules to apply. A pipeline invoking the CLI in local or all mode does not fail the build over it; the substitution simply does not happen, and the row stays at **Pending deploy**.
* `SEAL_PROJECT` does not match the Seal Project the rule was created for. Project attribution comes entirely from `SEAL_PROJECT`; if the build's `SEAL_PROJECT` value points at a different project (or a typo that the platform treats as a new project), the rule for the original project is never consulted.

## Related

* [Remote Sealing Rules](/using-platform/sealing-rules/remote-rules.md): the create / edit / delete flows the Remote rhythm depends on.
* [Package states](/discovering/package-states.md): the lifecycle the rows move through.
* [Seal Apps via the Seal CLI in CI/CD](/setup-apps-os/cli-in-cicd.md): the setup chapter the Remote rhythm assumes.
