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

doc: update README #84

Merged
merged 33 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e3e3fee
feat: refactor describe-key command & add unit test
JeyJeyGao Mar 8, 2023
daa60eb
feat: add installation script and update README
JeyJeyGao Mar 9, 2023
d278fc8
fix: update code
JeyJeyGao Mar 9, 2023
b5e05d6
fix: update code
JeyJeyGao Mar 9, 2023
a69d26c
fix: update code
JeyJeyGao Mar 9, 2023
fc87bb5
fix: update code
JeyJeyGao Mar 9, 2023
d4fc080
fix: update code
JeyJeyGao Mar 9, 2023
ebfd654
fix: update code
JeyJeyGao Mar 9, 2023
b450522
fix: golint
JeyJeyGao Mar 9, 2023
c1b0750
fix: update code
JeyJeyGao Mar 9, 2023
9dd776f
fix: update code
JeyJeyGao Mar 9, 2023
d52bbf1
fix: update code
JeyJeyGao Mar 10, 2023
979d2df
fix: download with curl instead of wget
JeyJeyGao Mar 10, 2023
1fc930b
fix: update code
JeyJeyGao Mar 10, 2023
aab25eb
fix: update codecov target to 60% to pass the check
JeyJeyGao Mar 10, 2023
cd13669
fix: update doc
JeyJeyGao Mar 10, 2023
cfff6be
fix: update doc
JeyJeyGao Mar 13, 2023
3345b07
Merge remote-tracking branch 'upstream/main' into feat/update_doc
JeyJeyGao Mar 13, 2023
d899c23
fix: update codecov
JeyJeyGao Mar 13, 2023
9100207
fix: update doc
JeyJeyGao Mar 13, 2023
bdbf450
doc: update
JeyJeyGao Mar 14, 2023
2db644e
doc: update
JeyJeyGao Mar 14, 2023
8da1f15
doc: update
JeyJeyGao Mar 14, 2023
85cf03d
doc: update doc
JeyJeyGao Mar 14, 2023
9c0fbdf
doc: update doc
JeyJeyGao Mar 15, 2023
14f95a2
doc: update
JeyJeyGao Mar 15, 2023
6988dd0
doc: update
JeyJeyGao Mar 29, 2023
6f28c15
doc: update
JeyJeyGao Mar 29, 2023
6e0a3bc
doc: update
JeyJeyGao Mar 29, 2023
c1848e9
doc: update
JeyJeyGao Mar 29, 2023
99cfa4c
doc: update
JeyJeyGao Mar 29, 2023
7af57b7
fix: golint
JeyJeyGao Mar 29, 2023
46a2f6c
doc: update
JeyJeyGao Mar 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
2 changes: 1 addition & 1 deletion .github/.codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ coverage:
status:
project:
default:
target: 70%
target: 60%
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
- name: Check out code into the Go module directory
uses: actions/checkout@v3
- name: Run unit tests
run: go test -race -v -coverprofile=coverage.txt -covermode=atomic ./...
run: make test
- name: Build testing
run: make build
- name: Upload coverage reports to Codecov
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Test binary, built with `go test -c`
*.test
coverage.txt

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
Expand Down
9 changes: 3 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Notation Azure KeyVault Plugin Makefile for Linux
MODULE = github.com/Azure/notation-azure-kv
COMMANDS = notation-azure-kv
GIT_TAG = $(shell git describe --tags --abbrev=0 --exact-match 2>/dev/null)
Expand Down Expand Up @@ -30,13 +31,9 @@ download: ## download dependencies via go mod
.PHONY: build
build: $(addprefix bin/,$(COMMANDS)) ## builds binaries

.PHONY: clean
clean:
git status --ignored --short | grep '^!! ' | sed 's/!! //' | xargs rm -rf

.PHONY: test
test:
go test ./... -coverprofile cover.out
test: ## run unit test
go test -race -v -coverprofile=coverage.txt -covermode=atomic ./...

.PHONY: install
install: bin/notation-azure-kv ## installs the plugin
Expand Down
186 changes: 161 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,173 @@

[![codecov](https://codecov.io/gh/Azure/notation-azure-kv/branch/main/graph/badge.svg)](https://codecov.io/gh/Azure/notation-azure-kv)

Azure Provider for the Notary v2 [Notation CLI](https://github.com/notaryproject/notation)
Azure Provider for the [Notation CLI](https://github.com/notaryproject/notation)

## Getting Started:
The following summarizes the steps to configure the Azure Key Vault notation plugin, configure gatekeeper, sign and verify a container image to Azure Kubernetes Service
The notation-azure-kv plugin provides the capability to signing the Notation generated payload by using Azure Key Vault (AKV). The user's certificate and private key should be stored in AKV and the plugin will request signing and getting the certificate from AKV.

```bash
# Sign in with Azure CLI.
# Other authorization methods are also available.
# See https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authorizatio
az login
The plugin supports Azure CLI identity and Managed Identity for accessing AKV.
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved

# Add signing and verification keys to the notation configuration policy
notation key add --name $KEY_NAME --plugin azure-kv --id $KEY_ID
notation cert add --name $KEY_NAME $CERT_PATH

# Install ratify, with the verification key
helm install ratify ratify/charts/ratify \
--set registryCredsSecret=regcred \
--set ratifyTestCert=$PUBLIC_KEY
kubectl apply -f ./ratify/charts/ratify-gatekeeper/templates/constraint.yaml

# Remotely sign with Azure Key Vault
notation sign --key $KEY_NAME $IMAGE

# Deploy the image, with Gatekeeper, Ratify and Notary v2 validation of the signed image
kubectl run net-monitor --image=$IMAGE -n demo
## Installation
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
Install the latest released Notation CLI and Azure-kv plugin via the command-line with curl
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/install.sh)" -- notation azure-kv
```
```
# example output
Installing on Linux amd64
Collecting notation latest release...
############################################################ 100.0%
Sucessfully installed notation-v1.0.0-rc.3 to /home/exampleuser/bin
Run the command to add the notation to PATH:
export PATH=$PATH:/home/exampleuser/bin

Collecting notation-azure-kv latest release...
############################################################ 100.0%
Successfully installed notation-azure-kv-v0.5.0-rc.1 to /home/exampleuser/.config/notation/plugins/azure-kv
Run the command to show the installed plugins:
/home/exampleuser/bin/notation plugin list
```
- if you only install Notation CLI, please execute the command:
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/install.sh)" -- notation
```

See [documentation for details on remote signing with Azure Key Vault, validating a deployment to AKS with Notation and Ratify, using a simple setup script.](docs/nv2-bicep.md).

- if you only install Azure-kv plugin, please execute the command:
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/install.sh)" -- azure-kv
```
> The installation script only supports Linux and MacOS based on amd64 or arm64 architecture. For Windows amd64 users to install Azure-kv plugin, please download the latest released binary for Windows and extract the `notation-azure-kv.exe` binary from the Zip file to `%AppData%\notation\plugins\azure-kv` directory manually.
## Getting Started with a self-signed Azure Key Vault Certificate
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
To demonstrate the basic use case, starting with a self-signed certificate is easier to understand how the Azure-kv plugin works with Notation, however, you **should not** use this in production because the self-signed certificate is not trusted.
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
1. install Azure CLI by following the [guide](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
2. login with Azure CLI and set the subscription:
```sh
az login
az account set --subscription $subscriptionID
```
3. create an Azure Key Vault and a self-signed certificate:
```sh
resourceGroup=notationResource
keyVault=notationKV
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
location=westus
certName=notationSelfSignedCert

# create a resource group
az group create -n $resourceGroup -l $location

# create a Azure Key Vault
az keyvault create -l $location -n $keyVault --resource-group $resourceGroup

# generate certificate policy
cat <<EOF > ./selfSignedPolicy.json
{
"issuerParameters": {
"certificateTransparency": null,
"name": "Self"
},
"keyProperties": {
"curve": null,
"exportable": false,
"keySize": 2048,
"keyType": "RSA",
"reuseKey": true
},
"secretProperties": {
"contentType": "application/x-pem-file"
},
"x509CertificateProperties": {
"ekus": [
"1.3.6.1.5.5.7.3.3"
],
"keyUsage": [
"digitalSignature"
],
"subject": "CN=Test Signer",
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
"validityInMonths": 12
}
}
EOF

# create self-signed certificate
az keyvault certificate create -n $certName --vault-name $keyVault -p @selfSignedPolicy.json

# get the key identifier
keyID=$(az keyvault certificate show -n $certName --vault-name $keyVault --query 'kid' -o tsv)
```
4. run a local registry and push an image to be signed:
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
```sh
# run a local registry with Docker
docker run --rm -d -p 5000:5000 ghcr.io/oras-project/registry:v1.0.0-rc.4

# push a hello-world image
docker pull hello-world
docker tag hello-world:latest localhost:5000/hello-world:v1
docker push localhost:5000/hello-world:v1
```
5. notation sign:
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
```sh
# sign with azure-kv
notation sign localhost:5000/hello-world:v1 --id $keyID --plugin azure-kv
# example output
Warning: Always sign the artifact using digest(@sha256:...) rather than a tag(:v1) because tags are mutable and a tag reference can point to a different artifact than the one signed.
Successfully signed localhost:5000/hello-world@sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4
```
6. notation verify:
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
```sh
# add self-signed certificate to notation trust store
cat <<EOF > ./selfSignedCert.crt
-----BEGIN CERTIFICATE-----
$(az keyvault certificate show -n $certName --vault-name $keyVault --query 'cer' -o tsv)
-----END CERTIFICATE-----
EOF
notation cert add --type ca --store selfSigned ./selfSignedCert.crt

# add notation trust policy
notationConfigDir="${HOME}/.config/notation" # for Linux
notationConfigDir="${HOME}/Library/Application Support/notation" # for MacOS
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved

JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
mkdir -p $notationConfigDir
cat <<EOF > $notationConfigDir/trustpolicy.json
{
"version": "1.0",
"trustPolicies": [
{
"name": "trust-policy-example",
"registryScopes": [ "*" ],
"signatureVerification": {
"level" : "strict"
},
"trustStores": [ "ca:selfSigned" ],
"trustedIdentities": [
"*"
]
}
]
}
EOF
chmod 0600 $notationConfigDir/trustpolicy.json
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved

# verify signature
notation verify localhost:5000/hello-world:v1
# example output
Warning: Always verify the artifact using digest(@sha256:...) rather than a tag(:v1) because resolved digest may not point to the same signed artifact, as tags are mutable.
Successfully verified signature for localhost:5000/hello-world@sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4
JeyJeyGao marked this conversation as resolved.
Show resolved Hide resolved
```

## Uninstall
Uninstall Azure-kv plugin via command-line with curl:
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/uninstall.sh)" -- azure-kv
```
- if you uninstall both Notation and Azure-kv plugin, please execute the command:
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/uninstall.sh)" -- notation azure-kv
```

To clean up Notation configurations, please execute the command:
```sh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/uninstall.sh)" -- config
```

## Contributing

Expand Down
128 changes: 128 additions & 0 deletions tools/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/bin/sh
#
# This script should be run via curl:
# To install Notation and Notation-azure-kv plugin
# sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/install.sh)" -- notation azure-kv
#
# To install Notation
# sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/install.sh)" -- notation
#
# To install Notation-azure-kv plugin
# sh -c "$(curl -fsSL https://raw.githubusercontent.com/Azure/notation-azure-kv/main/tools/install.sh)" -- azure-kv
#
set -e

osType="$(uname -s)"
case "${osType}" in
Linux*)
pluginInstallPath="${HOME}/.config/notation/plugins/azure-kv"
osType="Linux"
;;
Darwin*)
pluginInstallPath="${HOME}/Library/Application Support/notation/plugins/azure-kv"
osType="Darwin"
;;
*)
echo "unsupported OS ${osType}"
exit 1
;;
esac

archOut="$(uname -m)"
case "${archOut}" in
x86_64) archType="amd64" ;; # MacOS os Linux amd64
aarch64) archType="arm64" ;; # Linux ARM
arm64) atchType="arm64" ;; # MacOS ARM
*)
echo "Unsupported architecture ${archType}"
exit 1
;;
esac
echo "Installing on ${osType} ${archType}"

# defer cleanup temp directory
tempDir="$(mktemp -d)"
cleanup() {
rm -rf $tempDir
}
trap cleanup EXIT

# set install directory
binDir="${HOME}/bin"

# downloadLatestBinary returns the downloaded target path with shared variable
# `targetPath`.
downloadLatestBinary() {
owner=$1
repo=$2

echo "Collecting ${repo} latest release..."
downloadLink="$(curl -sL \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${owner}/${repo}/releases |
awk "BEGIN{IGNORECASE = 1}/browser_download_url/ && /${osType}/ && /${archType}/;" | grep -v dev | head -1 | awk -F '"' '{print $4}')"
curl -OL $downloadLink --progress-bar --output-dir $tempDir

# return target path
targetPath="${tempDir}/$(basename ${downloadLink})"
}

install() {
tarPath=$1
binaryName=$2
installPath=$3
mkdir -p $installPath

# extract and install
tar -zxf $tarPath -C $installPath $binaryName

# check install
if [ ! -f "$installPath/$binaryName" ]; then
echo "Failed to install ${binaryName}"
exit 1
fi
}

installNotation=false
installAzureKV=false

for i in $*; do
case $i in
notation) installNotation=true ;;
azure-kv) installAzureKV=true ;;
*)
echo "unknown argument: $i"
exit 1
;;
esac
done

# install notation
if [ $installNotation = true ]; then
downloadLatestBinary notaryproject notation
install $targetPath notation $binDir

version=$($binDir/notation version | grep Version | awk -F ' ' {'print $2'})
echo "Sucessfully installed notation-v$version to $binDir"
echo "Run the command to add the notation to PATH:"
echo " export PATH=\$PATH:$binDir"
echo ""
fi

# install notation-akv-plugin
if [ $installAzureKV = true ]; then
pluginName=notation-azure-kv
downloadLatestBinary Azure $pluginName
install $targetPath $pluginName $pluginInstallPath

# check pluign installation
if [ -z "$($binDir/notation plugin list | grep azure-kv)" ]; then
echo "Failed to install notation-azure-kv plugin, or Notation is missing"
exit 1
fi
version=$($binDir/notation plugin list | grep azure-kv | awk -F '[' {'print $1'} | awk -F ' ' {'print $NF'})
echo "Successfully installed notation-azure-kv-v$version to $pluginInstallPath"
echo "Run the command to show the installed plugins:"
echo " $binDir/notation plugin list"
fi
Loading