Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(notation): add support for notation in HelmChart and OCIRepository configuration #1075

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ make run

### Building the container image

Set the name of the container image to be created from the source code. This will be used
Set the name of the container image to be created from the source code. This will be used
when building, pushing and referring to the image on YAML files:

```sh
Expand All @@ -79,7 +79,7 @@ make docker-push
```

Alternatively, the three steps above can be done in a single line:

```sh
IMG=registry-path/source-controller TAG=latest BUILD_ARGS=--push \
make docker-build
Expand Down Expand Up @@ -128,7 +128,8 @@ Create a `.vscode/launch.json` file:
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go"
"program": "${workspaceFolder}/main.go",
"args": ["--storage-adv-addr=:0", "--storage-path=${workspaceFolder}/bin/data"]
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ and is a core component of the [GitOps toolkit](https://fluxcd.io/flux/component
## Features

* authenticates to sources (SSH, user/password, API token, Workload Identity)
* validates source authenticity (PGP, Cosign)
* validates source authenticity (PGP, Cosign, Notation)
* detects source changes based on update policies (semver)
* fetches resources on-demand and on-a-schedule
* packages the fetched resources into a well-known format (tar.gz, yaml)
Expand Down
2 changes: 1 addition & 1 deletion api/v1beta2/ocirepository_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ type OCILayerSelector struct {
// OCIRepositoryVerification verifies the authenticity of an OCI Artifact
type OCIRepositoryVerification struct {
// Provider specifies the technology used to sign the OCI Artifact.
// +kubebuilder:validation:Enum=cosign
// +kubebuilder:validation:Enum=cosign;notation
// +kubebuilder:default:=cosign
Provider string `json:"provider"`

Expand Down
1 change: 1 addition & 0 deletions config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ spec:
OCI Artifact.
enum:
- cosign
- notation
type: string
secretRef:
description: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ spec:
OCI Artifact.
enum:
- cosign
- notation
type: string
secretRef:
description: |-
Expand Down
25 changes: 25 additions & 0 deletions config/testdata/helmchart-from-oci/notation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmRepository
metadata:
name: podinfo-notation
spec:
url: oci://ghcr.io/stefanprodan/charts
type: "oci"
interval: 1m
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmChart
metadata:
name: podinfo-notation
spec:
chart: podinfo
sourceRef:
kind: HelmRepository
name: podinfo-notation
version: '6.6.0'
interval: 1m
verify:
provider: notation
secretRef:
name: notation-config
14 changes: 14 additions & 0 deletions config/testdata/ocirepository/signed-with-notation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: podinfo-deploy-signed-with-notation
spec:
interval: 5m
url: oci://ghcr.io/stefanprodan/podinfo-deploy
ref:
semver: "6.6.x"
verify:
provider: notation
secretRef:
name: notation-config
66 changes: 60 additions & 6 deletions docs/spec/v1beta2/helmcharts.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,20 @@ For practical information, see

**Note:** This feature is available only for Helm charts fetched from an OCI Registry.

`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign)
`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign) or [Notation](https://github.com/notaryproject/notation)
signatures. The field offers three subfields:

- `.provider`, to specify the verification provider. Only supports `cosign` at present.
- `.provider`, to specify the verification provider. The supported options are `cosign` and `notation` at present.
- `.secretRef.name`, to specify a reference to a Secret in the same namespace as
the HelmChart, containing the Cosign public keys of trusted authors.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers. Please see
the HelmChart, containing the public keys of trusted authors. For Notation this Secret should also include the [trust policy](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/trust-store-trust-policy.md#trust-policy) in
addition to the CA certificate.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers (only supported when using `cosign` as the verification provider). Please see
[Keyless verification](#keyless-verification) for more details.

#### Cosign

The `cosign` provider can be used to verify the signature of an OCI artifact using either a known public key or via the [Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure.

```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
Expand All @@ -281,7 +286,7 @@ following attributes to the HelmChart's `.status.conditions`:
- `status: "True"`
- `reason: Succeeded`

#### Public keys verification
##### Public keys verification

To verify the authenticity of HelmChart hosted in an OCI Registry, create a Kubernetes
secret with the Cosign public keys:
Expand All @@ -303,7 +308,7 @@ Note that the keys must have the `.pub` extension for Flux to make use of them.
Flux will loop over the public keys and use them to verify a HelmChart's signature.
This allows for older HelmCharts to be valid as long as the right key is in the secret.

#### Keyless verification
##### Keyless verification

For publicly available HelmCharts, which are signed using the
[Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure,
Expand Down Expand Up @@ -362,6 +367,55 @@ instance hosted at [rekor.sigstore.dev](https://rekor.sigstore.dev/).
Note that keyless verification is an **experimental feature**, using
custom root CAs or self-hosted Rekor instances are not currently supported.

#### Notation

The `notation` provider can be used to verify the signature of an OCI artifact using known
trust policy and CA certificate.

```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: HelmChart
metadata:
name: podinfo
spec:
verify:
provider: notation
secretRef:
name: notation-config
```

When the verification succeeds, the controller adds a Condition with the
following attributes to the HelmChart's `.status.conditions`:

- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`

To verify the authenticity of an OCI artifact, create a Kubernetes secret
containing Certificate Authority (CA) root certificates and the a `trust policy`

```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: notation-config
type: Opaque
data:
certificate1.pem: <BASE64>
certificate2.crt: <BASE64>
trustpolicy.json: <BASE64>
```

Note that the CA certificates must have either `.pem` or `.crt` extension and your trust policy must
be named `trustpolicy.json` for Flux to make use of them.

For more information on the signing and verification process see [Signing and Verification Workflow](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/signing-and-verification-workflow.md).

Flux will loop over the certificates and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right certificate is in the secret.

## Working with HelmCharts

### Triggering a reconcile
Expand Down
74 changes: 66 additions & 8 deletions docs/spec/v1beta2/ocirepositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ patches:
target:
kind: Deployment
name: source-controller
```
```

When using pod-managed identity on an AKS cluster, AAD Pod Identity
has to be used to give the `source-controller` pod access to the ACR.
Expand Down Expand Up @@ -279,7 +279,7 @@ patches:
target:
kind: ServiceAccount
name: source-controller
```
```

The Artifact Registry service uses the permission `artifactregistry.repositories.downloadArtifacts`
that is located under the Artifact Registry Reader role. If you are using
Expand Down Expand Up @@ -454,7 +454,7 @@ metadata:
spec:
ref:
digest: "sha256:<SHA-value>"
```
```

This field takes precedence over all other fields.

Expand Down Expand Up @@ -501,14 +501,23 @@ for more information.
### Verification

`.spec.verify` is an optional field to enable the verification of [Cosign](https://github.com/sigstore/cosign)
or [Notation](https://github.com/notaryproject/notation)
signatures. The field offers three subfields:

- `.provider`, to specify the verification provider. Only supports `cosign` at present.
- `.provider`, to specify the verification provider. The supported options are `cosign` and `notation` at present.
- `.secretRef.name`, to specify a reference to a Secret in the same namespace as
the OCIRepository, containing the Cosign public keys of trusted authors.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers. Please see
the OCIRepository, containing the Cosign public keys of trusted authors. For Notation this Secret should also
include the [trust policy](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/trust-store-trust-policy.md#trust-policy) in
addition to the CA certificate.
- `.matchOIDCIdentity`, to specify a list of OIDC identity matchers (only supported when using `cosign` as the
verification provider). Please see
[Keyless verification](#keyless-verification) for more details.

#### Cosign

The `cosign` provider can be used to verify the signature of an OCI artifact using either a known public key
or via the [Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure.

```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
Expand All @@ -529,7 +538,7 @@ following attributes to the OCIRepository's `.status.conditions`:
- `status: "True"`
- `reason: Succeeded`

#### Public keys verification
##### Public keys verification

To verify the authenticity of an OCI artifact, create a Kubernetes secret
with the Cosign public keys:
Expand All @@ -551,7 +560,7 @@ Note that the keys must have the `.pub` extension for Flux to make use of them.
Flux will loop over the public keys and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right key is in the secret.

#### Keyless verification
##### Keyless verification

For publicly available OCI artifacts, which are signed using the
[Cosign Keyless](https://github.com/sigstore/cosign/blob/main/KEYLESS.md) procedure,
Expand Down Expand Up @@ -593,6 +602,55 @@ instance hosted at [rekor.sigstore.dev](https://rekor.sigstore.dev/).
Note that keyless verification is an **experimental feature**, using
custom root CAs or self-hosted Rekor instances are not currently supported.

#### Notation

The `notation` provider can be used to verify the signature of an OCI artifact using known
trust policy and CA certificate.

```yaml
---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: <repository-name>
spec:
verify:
provider: notation
secretRef:
name: notation-config
```

When the verification succeeds, the controller adds a Condition with the
following attributes to the OCIRepository's `.status.conditions`:

- `type: SourceVerified`
- `status: "True"`
- `reason: Succeeded`

To verify the authenticity of an OCI artifact, create a Kubernetes secret
containing Certificate Authority (CA) root certificates and the a `trust policy`

```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: notation-config
type: Opaque
data:
certificate1.pem: <BASE64>
certificate2.crt: <BASE64>
trustpolicy.json: <BASE64>
```

Note that the CA certificates must have either `.pem` or `.crt` extension and your trust policy must
be named `trustpolicy.json` for Flux to make use of them.

For more information on the signing and verification process see [Signing and Verification Workflow](https://github.com/notaryproject/specifications/blob/v1.0.0/specs/signing-and-verification-workflow.md).

Flux will loop over the certificates and use them to verify an artifact's signature.
This allows for older artifacts to be valid as long as the right certificate is in the secret.

### Suspend

`.spec.suspend` is an optional field to suspend the reconciliation of a
Expand Down
11 changes: 10 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ require (
github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20231202142526-55ffb0092afd
github.com/google/uuid v1.6.0
github.com/minio/minio-go/v7 v7.0.66
github.com/notaryproject/notation-core-go v1.0.2
github.com/notaryproject/notation-go v1.1.0
github.com/onsi/gomega v1.31.1
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/go-digest/blake3 v0.0.0-20231025023718-d50d2fec9c98
github.com/opencontainers/image-spec v1.1.0
github.com/ory/dockertest/v3 v3.10.0
github.com/otiai10/copy v1.14.0
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
Expand All @@ -64,6 +67,7 @@ require (
k8s.io/apimachinery v0.28.6
k8s.io/client-go v0.28.6
k8s.io/utils v0.0.0-20231127182322-b307cd553661
oras.land/oras-go/v2 v2.3.1
sigs.k8s.io/controller-runtime v0.16.3
sigs.k8s.io/yaml v1.4.0
)
Expand All @@ -87,6 +91,7 @@ require (
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
Expand Down Expand Up @@ -169,11 +174,14 @@ require (
github.com/fluxcd/gitkit v0.6.0 // indirect
github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-chi/chi v4.1.2+incompatible // indirect
github.com/go-errors/errors v1.5.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.1 // indirect
github.com/go-ldap/ldap/v3 v3.4.6 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/analysis v0.22.0 // indirect
Expand Down Expand Up @@ -265,7 +273,6 @@ require (
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/oleiade/reflections v1.0.1 // indirect
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pborman/uuid v1.2.1 // indirect
Expand Down Expand Up @@ -312,6 +319,8 @@ require (
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/transparency-dev/merkle v0.0.2 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
github.com/veraison/go-cose v1.2.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/go-gitlab v0.96.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
Expand Down
Loading
Loading