> 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/setup-containers/seal-my-container/centralized-pipeline.md).

# Implementing the centralized re-seal pipeline

The production pattern for Seal My Container at scale is a centralized automation that picks up every newly pushed image in your registry, seals it, and pushes the sealed result back. The originating teams do not change their `Dockerfile`s; the security team's pipeline runs after the fact.

This is the lowest-friction setup for organizations with many container-producing teams. A single pipeline replaces dozens of per-team integrations, and the security team owns the seal step end to end.

## The shape

```
team A's build → push to registry → registry webhook → re-seal job → push sealed image back
team B's build → push to registry → registry webhook → re-seal job → push sealed image back
team C's build → push to registry → registry webhook → re-seal job → push sealed image back
                                              │
                                              └─ runs seal image fix
```

The seam between the originating builds and the re-seal pipeline is the **registry push event**. Most registries expose this as a webhook (Docker Hub, JFrog Artifactory, Harbor, GitHub Container Registry, AWS ECR via EventBridge). The webhook fires the re-seal job; the job runs `seal image fix` against the image that was just pushed.

## The re-seal job

The job runs on a host with Docker, the Seal CLI, and credentials for the registry. The minimal shape, sealing the image in place:

```bash
#!/usr/bin/env bash
set -euo pipefail

# Seal credentials injected from the pipeline's secret store.
export SEAL_TOKEN  # set by the CI / orchestrator
export SEAL_PROJECT=my-image-os

# Inputs from the webhook payload.
SOURCE_IMAGE="$1"        # e.g. registry.example.com/team-a/api:1.2.3
PLATFORM="${2:-linux/amd64}"

# Seal in place: same tag, sealed contents.
seal image fix "$SOURCE_IMAGE" --platform "$PLATFORM"
```

Surrounding this with your CI / job orchestration of choice (Jenkins job triggered by a webhook, a GitHub Actions workflow on `repository_dispatch`, a Kubernetes Job triggered by Argo Events, an AWS Lambda triggered by an ECR push event) gives you a complete pipeline.

The in-place rewrite is the standard pattern: every deployment that already pulls `registry.example.com/team-a/api:1.2.3` gets the sealed image on its next pull, with no change to the team's deployment manifests, Helm values, or `Dockerfile`s. The image's content has changed; everything else is unchanged.

## When to split the sealed result out to a different tag

For most teams the in-place overwrite is correct. The cases where splitting the sealed result onto a separate tag (or a separate repository) is the right call:

* **You want to keep the unsealed bits around for explicit rollback** ("if anything regresses, the unsealed `:1.2.3` is still there"). Add `--tag` to push to a parallel reference like `:1.2.3-sealed`, and update the deployment to reference the sealed tag.
* **The unsealed image is also a published artifact** (an SDK image your customers consume, for example). Overwriting it would replace what your customers expect; the sealed copy belongs on a separate tag or repository.
* **A compliance pipeline requires the original image's digest to be preserved** for chain-of-custody reasons. In that case the sealed image lands at a separate reference and the original is left intact.

When you do split, the re-seal job adds `--tag` to the `seal image fix` invocation:

```bash
SEALED_IMAGE="${SOURCE_IMAGE}-sealed"
seal image fix "$SOURCE_IMAGE" --platform "$PLATFORM" --tag "$SEALED_IMAGE"
```

The deployment side then has to be updated to pull from `${SEALED_IMAGE}` instead of `${SOURCE_IMAGE}`. Pick the in-place overwrite unless one of the above applies.

## Triggering on push

Per-registry hook configuration:

{% tabs %}
{% tab title="Docker Hub" %}
Configure a webhook on each repository under **Repository Settings > Webhooks**. The webhook posts a JSON body to the URL of your re-seal job's trigger (a Jenkins URL, a GitHub Actions `repository_dispatch`, an internal HTTP endpoint). The payload contains the pushed tag in `push_data.tag` and the repository in `repository.repo_name`.
{% endtab %}

{% tab title="JFrog Artifactory" %}
Artifactory has a built-in webhook for Docker push events at **Administration > Webhooks**. The supported events include `docker.tag.pushed`. The payload includes the full image reference.
{% endtab %}

{% tab title="GitHub Container Registry" %}
GitHub Container Registry events are emitted via [GitHub workflows triggered by `registry_package`](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#registry_package). The workflow runs in the same repository whose container was pushed, so the re-seal job and the source build can share a repository or sit in a dedicated security repo that subscribes to the events.
{% endtab %}

{% tab title="AWS ECR" %}
ECR emits push events to EventBridge by default. Subscribe a Lambda or a Step Function to `Amazon ECR Image Action` events with detail `action-type=PUSH`; the function reads the repository and tag from the event and invokes the re-seal pipeline. CodeBuild is the usual host for the actual `seal image fix` run, since Lambda's execution time and disk space are limited.
{% endtab %}

{% tab title="Harbor" %}
Harbor projects expose webhooks under **Projects > \[project] > Webhooks**. Subscribe to `PUSH_ARTIFACT`; the payload contains the repository, tag, and digest.
{% endtab %}
{% endtabs %}

Each integration is a thin layer of glue between the webhook and the `seal image fix` invocation. The seal step itself is the same regardless of which registry fires the event.

## Filtering which images to seal

Sealing every pushed image is overkill; most teams seal only production-bound tags. Two ways to filter:

* **At the webhook layer**, by ignoring events for tags that match a development pattern (`dev-*`, `pr-*`, `*-rc`). The webhook handler's first job is to decide whether to invoke the re-seal pipeline.
* **At the registry layer**, by configuring the webhook against only the repositories that hold production images. Development images go to a separate repository the webhook does not watch.

The first approach is more flexible; the second is harder to misconfigure.

## Re-seal vs build-time seal

For teams that already run `seal fix` and `seal fix --os` inside their own `Dockerfile`s, the centralized re-seal pipeline is redundant — the seal happened at build time and the image arrives at the registry already sealed. For those teams, the webhook handler can detect the prior seal (via the Seal label the build process adds, or via the image's repository convention) and skip.

The centralized pattern shines when you have many teams with heterogeneous build processes and the security team wants one chokepoint that guarantees no unsealed image reaches production. In that case the re-seal pipeline is the canonical setup.

## Sealing on a schedule, not on push

Some teams prefer to re-seal on a schedule rather than per-push: every night, the pipeline re-seals every tag in the production-ready repositories. The advantage is that newer sealed iterations of OS packages reach the image without a push trigger; the disadvantage is that fresh pushes wait until the next scheduled run before they are sealed.

Pick the trade-off that fits your release cadence. Per-push gives the smallest seal latency on new builds; scheduled gives the freshest sealed packages for long-lived images.

## Related

* [The `seal image fix` command and flags](/setup-containers/seal-my-container/seal-image-fix-reference.md): the command the pipeline invokes.
* [Authenticating with your container registry](/setup-containers/seal-my-container/authenticating-registry.md): the credentials the pipeline's host needs.
* [Common issues](/setup-containers/seal-my-container/common-issues.md): the failures the pipeline is most likely to hit at scale.
