> For the complete documentation index, see [llms.txt](https://docs.pipekit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pipekit.io/why-pipekit/security.md).

# Security

Pipekit is built so your workflow data, secrets, and compute stay in your infrastructure. The control plane brokers commands and metadata; the actual `Workflow` execution and your data never leave the cluster.

## How Pipekit secures the stack

### Bring-your-own-cluster architecture

The [Pipekit Agent](/concepts/pipekit-agent.md) runs in your Kubernetes cluster and connects outbound to Pipekit's control plane (or to your self-hosted control plane). Your workflows execute on your nodes, against your storage, using your service accounts and your secrets. Pipekit never has direct cluster credentials or inbound network access into your environment.

### Optional self-hosted, air-gapped control plane

If a hosted control plane is incompatible with your compliance posture, [Self-Hosted Pipekit](/self-hosting-pipekit.md) installs the entire stack (UI, API, database, agent) inside your own infrastructure. The install is designed to work in air-gapped environments; see [Container Images](/self-hosting-pipekit/dependencies/container-images.md) for the image inventory.

### IdP-backed access, default-deny

Authentication is delegated to your identity provider via [SSO](/organizations-and-access/sso.md). Authorization is default-deny. Namespaces added to a cluster are inaccessible until an Org Admin explicitly binds them to a workspace. For the full model, see [Governance](/why-pipekit/governance.md) and [Access Control](/concepts/access-control.md).

### Software Bill of Materials (SBOM)

#### Containers

An SBOM for our public containers (e.g. [Pipekit Agent](/concepts/pipekit-agent.md) and the [Pipekit CLI](/reference/cli.md#docker-container)) is embedded within the container image in SPDX format. You can extract the SBOM by running the following `docker buildx` command:

```bash
docker buildx imagetools inspect pipekit13/pipekit-agent:v0.0.0 --format '{{ json (index .SBOM "linux/amd64").SPDX}}' > pipekit-agent.spdx
```

Remember to set the image tag accordingly:

* [Pipekit Agent](https://hub.docker.com/r/pipekit13/pipekit-agent/tags)
* [Pipekit CLI](https://hub.docker.com/r/pipekit13/cli/tags)

We combine a `linux/amd64` and a `linux/arm64` variant of the containers as one image tag, so you need to choose the correct variant of the SBOM to extract.

Alternatively, you can extract a list of all the packages used in the container by running:

```bash
docker buildx imagetools inspect pipekit13/pipekit-agent:v0.0.0 --format '{{ range (index .SBOM "linux/amd64").SPDX.packages }}{{ println .name .versionInfo }}{{ end }}' | sort
```

You can also search for individual packages:

```bash
docker buildx imagetools inspect pipekit13/pipekit-agent:v0.0.0 --format '{{ range (index .SBOM "linux/amd64").SPDX.packages }}{{ if eq .name "busybox" }}{{ println .versionInfo }}{{ end }}{{ end }}'
```

#### CLI Binaries

SBOM files are available alongside the CLI binaries in the [Pipekit CLI repository](https://github.com/pipekit/cli/releases).

### Signed containers

We sign our public containers using [Cosign](https://docs.sigstore.dev/cosign/installation). Signing materials are stored in a tamper-resistant public log.

After installing Cosign, verify the signature of a container by running:

```bash
cat <<EOF > pipekit-cosign.pub
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEUsGMXv9tynS/2yu4WkZLZwLYIbq1
kI/iAtFVazXjKbZVS4+UJnAFt1eh6I8+MEN75KHUD+xw0rm918ZxgRlXKA==
-----END PUBLIC KEY-----
EOF

cosign verify --key pipekit-cosign.pub pipekit13/pipekit-agent:latest
```

You can use an admission controller such as [Connaisseur](https://github.com/sse-secure-systems/connaisseur) to verify the signature of the container at runtime within Kubernetes.
