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: plugins as OCI artifacts #519

Merged
merged 39 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
66b1f84
Initial spike of support for downloading plugins as OCI artifacts
noelbundick-msft Dec 14, 2022
027e13f
Merge remote-tracking branch 'upstream/main' into plugins-as-oci-arti…
noelbundick-msft Dec 14, 2022
26178a1
add log level toggle to helm chart
akashsinghal Dec 15, 2022
2a356df
Merge remote-tracking branch 'upstream/main' into plugins-as-oci-arti…
noelbundick-msft Dec 16, 2022
b5d3601
Merge commit '26178a171e58cd62ff25dbd0fd477f14fa8e564b' of https://gi…
noelbundick-msft Dec 16, 2022
cf3ae07
Fix permissions on plugin dir
noelbundick-msft Dec 16, 2022
7a1e73c
Add CRD support for OCI artifact plugins
noelbundick-msft Dec 21, 2022
cd6834b
Merge remote-tracking branch 'upstream/main' into plugins-as-oci-arti…
noelbundick-msft Dec 21, 2022
37a852c
Merge branch 'main' of https://github.com/deislabs/ratify into plugin…
noelbundick-msft Jan 13, 2023
1d7a209
Update imports
noelbundick-msft Jan 13, 2023
82bb22d
add ability to specify authProvider for dynamic plugins
noelbundick-msft Jan 13, 2023
a38067c
e2e tests for dynamic plugins
noelbundick-msft Jan 13, 2023
f747d6b
fix bats teardown calls
noelbundick-msft Jan 13, 2023
2cdfffc
try larger runners for e2e
noelbundick-msft Jan 13, 2023
987e088
ci: revert large runners
noelbundick-msft Jan 13, 2023
76df183
wip: re-add chart upgrade
noelbundick-msft Jan 13, 2023
f2f3a86
add cli test for dynamic plugins
noelbundick-msft Jan 14, 2023
9bf4994
Merge branch 'main' into plugins-as-oci-artifacts
noelbundick-msft Jan 14, 2023
68beaeb
Merge branch 'main' of https://github.com/deislabs/ratify into plugin…
noelbundick-msft Jan 18, 2023
32d73aa
Add config parsing tests
noelbundick-msft Jan 18, 2023
a733749
go fmt
noelbundick-msft Jan 18, 2023
f1633e9
s/install/upgrade
noelbundick-msft Jan 18, 2023
2f2bc71
fix path in markdown
noelbundick-msft Jan 18, 2023
bee82cb
Merge branch 'main' into plugins-as-oci-artifacts
noelbundick-msft Jan 18, 2023
da3dcbd
use %w in error handling
noelbundick-msft Jan 18, 2023
396160e
Merge branch 'main' of https://github.com/deislabs/ratify into plugin…
noelbundick-msft Jan 19, 2023
f898518
s/ratify-service/gatekeeper-system
noelbundick-msft Jan 19, 2023
675989c
add cli test for dynamic referrerstore
noelbundick-msft Jan 23, 2023
c711d12
Merge branch 'main' of https://github.com/deislabs/ratify into plugin…
noelbundick-msft Jan 23, 2023
6fcc37a
enable dynamic plugin e2e test on aks
noelbundick-msft Jan 23, 2023
712083a
Merge branch 'main' of https://github.com/deislabs/ratify into plugin…
noelbundick-msft Jan 24, 2023
5c6b340
Merge branch 'main' of https://github.com/deislabs/ratify into plugin…
noelbundick-msft Jan 25, 2023
9978da5
Merge remote-tracking branch 'upstream/main' into plugins-as-oci-arti…
noelbundick-msft Jan 27, 2023
b343f44
re-run make generate
noelbundick-msft Jan 27, 2023
32653ae
fix test merge
noelbundick-msft Jan 27, 2023
65f9ab6
Merge remote-tracking branch 'upstream/main' into plugins-as-oci-arti…
noelbundick-msft Jan 31, 2023
3b3196c
use wabbitnetworks plugins
noelbundick-msft Jan 31, 2023
0f36bd9
Merge branch 'main' into plugins-as-oci-artifacts
noelbundick-msft Jan 31, 2023
f11c38a
Merge branch 'main' into plugins-as-oci-artifacts
noelbundick-msft Jan 31, 2023
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
4 changes: 4 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ RUN curl -Lo oras.tar.gz https://github.com/oras-project/oras/releases/download/
&& mv oras-install/oras /usr/local/bin/ \
&& rm -rf ./oras-install oras.tar.gz

ARG KUBEBUILDER_VERSION="3.8.0"
RUN curl -L https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${KUBEBUILDER_VERSION}/kubebuilder_linux_amd64 -o /usr/local/bin/kubebuilder \
&& chmod +x /usr/local/bin/kubebuilder

# [Optional] Uncomment this section to install additional OS packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends protobuf-compiler libprotobuf-dev
Expand Down
9 changes: 8 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/ratify",
"env": {
"RATIFY_DYNAMIC_PLUGINS": "1"
},
"args": [
"verify",
"-s",
Expand All @@ -22,6 +25,9 @@
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/cmd/ratify",
"env": {
"RATIFY_DYNAMIC_PLUGINS": "1"
},
"args": [
"serve",
"--http",
Expand All @@ -36,7 +42,8 @@
"mode": "auto",
"program": "${workspaceFolder}/cmd/ratify",
"env": {
"RATIFY_LOG_LEVEL": "debug"
"RATIFY_LOG_LEVEL": "debug",
"RATIFY_DYNAMIC_PLUGINS": "1"
},
"args": [
"serve",
Expand Down
31 changes: 31 additions & 0 deletions api/v1alpha1/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2022.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import runtime "k8s.io/apimachinery/pkg/runtime"

// PluginSource defines the fields needed to download a plugin from an OCI Artifact source
type PluginSource struct {
// Important: Run "make" to regenerate code after modifying this file

// OCI Artifact source to download the plugin from
Artifact string `json:"artifact,omitempty"`

// +kubebuilder:pruning:PreserveUnknownFields
// AuthProvider to use to authenticate to the OCI Artifact source, optional
AuthProvider runtime.RawExtension `json:"authProvider,omitempty"`
}
2 changes: 2 additions & 0 deletions api/v1alpha1/store_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type StoreSpec struct {
Name string `json:"name,omitempty"`
// Plugin path, optional
Address string `json:"address,omitempty"`
// OCI Artifact source to download the plugin from, optional
Source *PluginSource `json:"source,omitempty"`

// +kubebuilder:pruning:PreserveUnknownFields
// Parameters of the store
Expand Down
3 changes: 3 additions & 0 deletions api/v1alpha1/verifier_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ type VerifierSpec struct {
// # Optional. URL/file path
Address string `json:"address,omitempty"`

// OCI Artifact source to download the plugin from, optional
Source *PluginSource `json:"source,omitempty"`

// +kubebuilder:pruning:PreserveUnknownFields
// Parameters for this verifier
Parameters runtime.RawExtension `json:"parameters,omitempty"`
Expand Down
26 changes: 26 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion charts/ratify/crds/store-customresourcedefinition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,22 @@ spec:
description: Parameters of this store
type: object
x-kubernetes-preserve-unknown-fields: true
source:
description: OCI Artifact source to download the plugin from, optional
properties:
artifact:
description: OCI Artifact source to download the plugin from
type: string
authProvider:
description: AuthProvider to use to authenticate to the OCI Artifact
source, optional
type: object
x-kubernetes-preserve-unknown-fields: true
type: object
type: object
status:
description: StoreStatus defines the observed state of Store
type: object
type: object
served: true
storage: true
storage: true
14 changes: 13 additions & 1 deletion charts/ratify/crds/verifier-customresourcedefinition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,22 @@ spec:
description: Parameters of this verifier
type: object
x-kubernetes-preserve-unknown-fields: true
source:
description: OCI Artifact source to download the plugin from, optional
properties:
artifact:
description: OCI Artifact source to download the plugin from
type: string
authProvider:
description: AuthProvider to use to authenticate to the OCI Artifact
source, optional
type: object
x-kubernetes-preserve-unknown-fields: true
type: object
type: object
status:
description: VerifierStatus defines the observed state of Verifier
type: object
type: object
served: true
storage: true
storage: true
12 changes: 12 additions & 0 deletions config/crd/bases/config.ratify.deislabs.io_stores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ spec:
description: Parameters of the store
type: object
x-kubernetes-preserve-unknown-fields: true
source:
description: OCI Artifact source to download the plugin from, optional
properties:
artifact:
description: OCI Artifact source to download the plugin from
type: string
authProvider:
description: AuthProvider to use to authenticate to the OCI Artifact
source, optional
type: object
x-kubernetes-preserve-unknown-fields: true
type: object
type: object
status:
description: StoreStatus defines the observed state of Store
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/config.ratify.deislabs.io_verifiers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ spec:
description: Parameters for this verifier
type: object
x-kubernetes-preserve-unknown-fields: true
source:
susanshi marked this conversation as resolved.
Show resolved Hide resolved
description: OCI Artifact source to download the plugin from, optional
properties:
artifact:
description: OCI Artifact source to download the plugin from
type: string
authProvider:
description: AuthProvider to use to authenticate to the OCI Artifact
source, optional
type: object
x-kubernetes-preserve-unknown-fields: true
type: object
type: object
status:
description: VerifierStatus defines the observed state of Verifier
Expand Down
9 changes: 9 additions & 0 deletions config/samples/config_v1alpha1_verifier_dynamic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: config.ratify.deislabs.io/v1alpha1
kind: Verifier
metadata:
name: verifier-dynamic
spec:
name: dynamic
artifactTypes: application/vnd.ratify.spdx.v0
source:
artifact: wabbitnetworks.azurecr.io/test/sample-verifier-plugin:v1
78 changes: 78 additions & 0 deletions docs/reference/dynamic-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Dynamic Plugins

While Ratify provides a number of built-in referrer stores and verifiers, there may be times that you need to add additional out-of-tree plugins to verify additional artifact types or check for specific conditions. Whether you've followed the [plugin authoring guide](./creating-plugins.md), or you want to use a plugin that's provided by a third party, the next step is to make your plugin available to be called at runtime.

Ratify includes an optional dynamic plugins feature to simplify plugin distribution. This removes the need to rebuild or maintain your own Ratify container image. When enabled, plugins are stored as OCI artifacts and pulled down at runtime when they are registered via CRD. This guide will show you how to activate and configure dynamic plugins.

## Uploading your plugin

Upload your plugin to a registry that supports OCI artifacts. Here we're using the sample plugin located at `plugins/verifier/sample`. Replace the registry values with your own.

```shell
CGO_ENABLED=0 go build -o=./sample ./plugins/verifier/sample
oras push myregistry.azurecr.io/sample-plugin:v1 ./sample
```

> It's important to build plugins with `CGO_ENABLED=0` so that they can run inside the Ratify [distroless](https://github.com/GoogleContainerTools/distroless) container

## Ratify Configuration

Now that you have a plugin available as an OCI artifact, it's time to enable the `RATIFY_DYNAMIC_PLUGINS` [feature flag](/docs/reference/usage.md#feature-flags). Here, we enable it via Helm chart parameter:

```shell
# Option 1: to enable on a fresh install
helm install ratify \
ratify/ratify --atomic \
--set-file provider.tls.crt=${CERT_DIR}/server.crt \
--set-file provider.tls.key=${CERT_DIR}/server.key \
--set provider.tls.cabundle="$(cat ${CERT_DIR}/ca.crt | base64 | tr -d '\n')" \
--set featureFlags.RATIFY_DYNAMIC_PLUGINS=true

# Option 2: to enable on a previously-installed release
helm upgrade ratify \
ratify/ratify --atomic \
--reuse-values \
--set featureFlags.RATIFY_DYNAMIC_PLUGINS=true
```

## Plugin Configuration

The last step is to specify the optional `source` property to tell Ratify where to download the plugin from. Dynamic plugins use the same [auth providers](/docs/reference/oras-auth-provider.md) and options as the builtin ORAS store (ex: `azureWorkloadIdentity`, `awsEcrBasic`, `k8Secrets`) for authentication to the registry where your plugins are located.

```yaml
apiVersion: config.ratify.deislabs.io/v1alpha1
kind: Verifier
metadata:
name: verifier-sample
spec:
name: sample
artifactTypes: application/vnd.ratify.spdx.v0
source:
artifact: myregistry.azurecr.io/sample-plugin:v1
authProvider:
name: azureWorkloadIdentity
```

## Confirmation / Troubleshooting

You can check the Ratify logs for more details on which plugin(s) were downloaded. Your specific commands may vary slightly based on the values you provided during chart installation.

```shell
kubectl logs -n gatekeeper-system deployment/ratify
```

This will generate output similar to below, which can be used for confirmation of a successful plugin download or to aid in troubleshooting.

```text
time="2023-01-18T16:44:46Z" level=info msg="Setting log level to info"
time="2023-01-18T16:44:46Z" level=info msg="Feature flag DYNAMIC_PLUGINS is enabled"
time="2023-01-18T16:44:46Z" level=info msg="starting crd manager"
time="2023-01-18T16:44:46Z" level=info msg="initializing executor with config file at default config path"
<snip>
time="2023-01-18T16:44:46Z" level=info msg="reconciling verifier 'verifier-dynamic'"
time="2023-01-18T16:44:46Z" level=info msg="Address was empty, setting to default path: /.ratify/plugins"
time="2023-01-18T16:44:47Z" level=info msg="selected auth provider: azureWorkloadIdentity"
time="2023-01-18T16:44:48Z" level=info msg="downloaded verifier plugin dynamic from myregistry.azurecr.io/sample-plugin:v1 to /.ratify/plugins/dynamic"
time="2023-01-18T16:44:48Z" level=info msg="verifier 'dynamic' added to verifier map"
<snip>
```
2 changes: 2 additions & 0 deletions docs/reference/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ This page documents useful flags and options supported by Ratify

Ratify may roll out new features behind feature flags, which are activated by setting the corresponding environment variable `RATIFY_<FEATURE_NAME>=1`.
A value of `1` indicates the feature is active; any other value disables the flag.

- `RATIFY_DYNAMIC_PLUGINS`: (disabled) Enables Ratify to download plugins at runtime from an OCI registry by setting `source` on the plugin config
2 changes: 1 addition & 1 deletion httpserver/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ ARG RATIFY_FOLDER=$HOME/.ratify/
WORKDIR /

COPY --from=builder /app/out/ratify /app/
COPY --from=builder /app/out/plugins ${RATIFY_FOLDER}/plugins
COPY --from=builder --chown=65532:65532 /app/out/plugins ${RATIFY_FOLDER}/plugins
noelbundick-msft marked this conversation as resolved.
Show resolved Hide resolved
COPY --from=builder /app/config/config.json ${RATIFY_FOLDER}

ENV RATIFY_CONFIG=${RATIFY_FOLDER}
Expand Down
Loading