Skip to content

Commit 45ff974

Browse files
authored
doc: update README (#84)
- update README.md to include a basic case azure-kv sign & verify guide Resolve part of #78 Signed-off-by: Junjie Gao <[email protected]>
1 parent 8406300 commit 45ff974

File tree

5 files changed

+310
-28
lines changed

5 files changed

+310
-28
lines changed

README.md

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,58 @@
22

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

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

7-
## Getting Started:
8-
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
7+
The `notation-azure-kv` plugin allows you to sign the Notation-generated payload with a certificate in Azure Key Vault (AKV). The certificate and private key are stored in AKV and the plugin will request signing and obtain the leaf certificate from AKV.
98

10-
```bash
11-
# Sign in with Azure CLI.
12-
# Other authorization methods are also available.
13-
# See https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authorizatio
14-
az login
9+
The plugin supports authentication by [Azure CLI](https://learn.microsoft.com/cli/azure/authenticate-azure-cli) or [Managed Identity](https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview). Azure CLI authenticate is used by default. To enable `Managed Identity` authentication, set the `AKV_AUTH_METHOD` environment variable to `AKV_AUTH_FROM_MI`.
1510

16-
# Add signing and verification keys to the notation configuration policy
17-
notation key add --name $KEY_NAME --plugin azure-kv --id $KEY_ID
18-
notation cert add --name $KEY_NAME $CERT_PATH
11+
## Installation the AKV plugin
12+
Before you begin, make sure the latest version of the [Notation CLI has been installed](https://notaryproject.dev/docs/installation/cli/).
1913

20-
# Install ratify, with the verification key
21-
helm install ratify ratify/charts/ratify \
22-
--set registryCredsSecret=regcred \
23-
--set ratifyTestCert=$PUBLIC_KEY
24-
kubectl apply -f ./ratify/charts/ratify-gatekeeper/templates/constraint.yaml
14+
1. Navigate to the [Releases](https://github.com/Azure/notation-azure-kv/releases) page and select the latest release of `notation-azure-kv`. Under the *Assets* section, select the `notation-azure-kv` binary for your platform.
15+
2. Validate the checksum using the values in `checksums.txt` and then install the plugin.
2516

26-
# Remotely sign with Azure Key Vault
27-
notation sign --key $KEY_NAME $IMAGE
17+
For Linux Bash:
18+
```sh
19+
version=0.6.0
2820

29-
# Deploy the image, with Gatekeeper, Ratify and Notary v2 validation of the signed image
30-
kubectl run net-monitor --image=$IMAGE -n demo
31-
```
21+
# validate checksum
22+
cat checksums.txt | grep notation-azure-kv_${version}_linux_amd64.tar.gz | sha256sum -c
3223

33-
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).
24+
# install the plugin
25+
mkdir -p "$HOME/.config/notation/plugins/azure-kv"
26+
tar zxf notation-azure-kv_${version}_linux_amd64.tar.gz -C "$HOME/.config/notation/plugins/azure-kv" notation-azure-kv
27+
```
28+
For macOS Zsh:
29+
```sh
30+
version=0.6.0
3431

32+
# validate checksum
33+
cat checksums.txt | grep notation-azure-kv_${version}_darwin_amd64.tar.gz | shasum -a 256 -c
3534

35+
# install the plugin
36+
mkdir -p "$HOME/Library/Application Support/notation/plugins/azure-kv"
37+
tar zxf notation-azure-kv_${version}_darwin_amd64.tar.gz -C "$HOME/Library/Application Support/notation/plugins/azure-kv" notation-azure-kv
38+
```
39+
For Windows Powershell:
40+
```powershell
41+
$version = "0.6.0"
3642
43+
# validate checksum
44+
(Get-FileHash .\notation-azure-kv_${version}_windows_amd64.zip).Hash
45+
46+
# install the plugin
47+
mkdir "$env:AppData\notation\plugins\azure-kv"
48+
Expand-Archive -Path notation-azure-kv_${version}_windows_amd64.zip -DestinationPath "$env:AppData\notation\plugins\azure-kv"
49+
```
50+
3. Run `notation plugin list` and confirm the `azure-kv` plugin is installed.
51+
52+
## Getting started
53+
1. [Sign and verify an artifact with a self-signed Azure Key Vault certificate](docs/self-signed-workflow.md)
54+
2. [Sign and verify an artifact with a certificate signed by a trusted CA in Azure Key Vault](docs/ca-signed-workflow.md)
55+
56+
> **Note** Please make sure the certificate is in PEM format. PCKS#12 will be supported in the future.
3757
## Contributing
3858

3959
This project welcomes contributions and suggestions. Most contributions require you to agree to a

cmd/notation-azure-kv/key_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ type certificateMock struct {
2424
err error
2525
}
2626

27-
func (c *certificateMock) Sign(ctx context.Context, algorithm azkeys.JSONWebKeySignatureAlgorithm, digest []byte) ([]byte, error) {
27+
func (c *certificateMock) Sign(_ context.Context, _ azkeys.JSONWebKeySignatureAlgorithm, _ []byte) ([]byte, error) {
2828
panic("not implemented") // TODO: Implement
2929
}
3030

31-
func (c *certificateMock) CertificateChain(ctx context.Context) ([]*x509.Certificate, error) {
31+
func (c *certificateMock) CertificateChain(_ context.Context) ([]*x509.Certificate, error) {
3232
panic("not implemented") // TODO: Implement
3333
}
3434

35-
func (c *certificateMock) Certificate(ctx context.Context) (*x509.Certificate, error) {
35+
func (c *certificateMock) Certificate(_ context.Context) (*x509.Certificate, error) {
3636
return c.cert, c.err
3737
}
3838

docs/ca-signed-workflow.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Sign and verify an artifact with a certificate signed by a trusted CA in Azure Key Vault
2+
> **Note** The following guide can be executed on Linux bash, macOS Zsh and Windows WSL
3+
1. [Install the Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli)
4+
2. Log in to Azure with Azure CLI, set the subscription and make sure the `GetCertificate` and `Sign` permission have been granted to your role:
5+
```sh
6+
az login
7+
az account set --subscription $subscriptionID
8+
```
9+
3. Create an Azure Key Vault:
10+
```sh
11+
resourceGroup=<your-resource-group-name>
12+
keyVault=<your-key-vault-name>
13+
location=westus
14+
certName=notationLeafCert
15+
16+
# create a resource group
17+
az group create -n $resourceGroup -l $location
18+
19+
# create a Azure Key Vault
20+
az keyvault create -l $location -n $keyVault --resource-group $resourceGroup
21+
```
22+
4. Create a Certificate Signing Request (CSR):
23+
```sh
24+
# generate certificate policy
25+
cat <<EOF > ./leafCert.json
26+
{
27+
"issuerParameters": {
28+
"certificateTransparency": null,
29+
"name": "Unknown"
30+
},
31+
"keyProperties": {
32+
"curve": null,
33+
"exportable": false,
34+
"keySize": 2048,
35+
"keyType": "RSA",
36+
"reuseKey": true
37+
},
38+
"secretProperties": {
39+
"contentType": "application/x-pem-file"
40+
},
41+
"x509CertificateProperties": {
42+
"ekus": [
43+
"1.3.6.1.5.5.7.3.3"
44+
],
45+
"keyUsage": [
46+
"digitalSignature"
47+
],
48+
"subject": "CN=Test-Signer,C=US,ST=WA,O=notation",
49+
"validityInMonths": 12
50+
}
51+
}
52+
EOF
53+
54+
# create the leaf certificate
55+
az keyvault certificate create -n $certName --vault-name $keyVault -p @leafCert.json
56+
57+
# get the CSR
58+
CSR=$(az keyvault certificate pending show --vault-name $keyVault --name $certName --query 'csr' -o tsv)
59+
CSR_PATH=${certName}.csr
60+
printf -- "-----BEGIN CERTIFICATE REQUEST-----\n%s\n-----END CERTIFICATE REQUEST-----\n" $CSR > ${CSR_PATH}
61+
```
62+
5. Please take `${certName}.csr` file to a trusted CA to sign and issue your certificate, or you can use `openssl` tool to sign it locally for testing.
63+
6. After you get the leaf certificate, you can merge the leaf certificate (`$leafCert`) to your Azure Key Vault:
64+
```sh
65+
az keyvault certificate pending merge --vault-name $keyVault --name $certName --file $leafCert
66+
67+
# get the key identifier
68+
keyID=$(az keyvault certificate show -n $certName --vault-name $keyVault --query 'kid' -o tsv)
69+
```
70+
7. [Create an Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-portal?tabs=azure-cli). The remaining steps use the example login server `<registry-name>.azurecr.io`, but you must substitute your own login server value.
71+
8. Log in to container registry and push an image for signing:
72+
```sh
73+
registryName="<registry-name>"
74+
server="${registryName}.azurecr.io"
75+
76+
az acr login --name $registryName
77+
# notation login $server # if you don't use Azure Container Registry
78+
79+
# push a hello-world image for signing
80+
docker pull hello-world:latest
81+
docker tag hello-world:latest $server/hello-world:v1
82+
docker push $server/hello-world:v1
83+
```
84+
9. Sign the image with an external certificate bundle (`$certBundlePath`) including the intermediate certificates and a root certificate in PEM format. You may fetch the certificate bundle from your CA official website.
85+
```sh
86+
notation key add --plugin azure-kv --id $keyID akv-key --default
87+
notation sign $server/hello-world:v1 --plugin-config=ca_certs=$certBundlePath
88+
```
89+
90+
The following example output shows the artifact is successfully signed.
91+
```
92+
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.
93+
Successfully signed notation.azurecr.io/hello-world@sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4
94+
```
95+
10. Signature verification with Notation needs the root certificate of your CA in the trust store and a `trustpolicy.json` file in Notation configuration directory:
96+
```sh
97+
# add root certificate ($rootCertPath) to notation trust store
98+
notation cert add --type ca --store trusted $rootCertPath
99+
100+
# add notation trust policy
101+
notationConfigDir="${HOME}/.config/notation" # for Linux and WSL
102+
# notationConfigDir="${HOME}/Library/Application Support/notation" # for macOS
103+
104+
mkdir -p $notationConfigDir
105+
cat <<EOF > $notationConfigDir/trustpolicy.json
106+
{
107+
"version": "1.0",
108+
"trustPolicies": [
109+
{
110+
"name": "trust-policy-example",
111+
"registryScopes": [ "*" ],
112+
"signatureVerification": {
113+
"level" : "strict"
114+
},
115+
"trustStores": [ "ca:trusted" ],
116+
"trustedIdentities": [
117+
"*"
118+
]
119+
}
120+
]
121+
}
122+
EOF
123+
chmod 600 $notationConfigDir/trustpolicy.json
124+
```
125+
11. Verify the signature associated with the image:
126+
```
127+
notation verify $server/hello-world:v1
128+
```
129+
The following output shows the artifact is successfully verified.
130+
```
131+
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.
132+
Successfully verified signature for notation.azurecr.io/hello-world@sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4
133+
```

docs/self-signed-workflow.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Sign and verify an artifact with a self-signed Azure Key Vault certificate
2+
> **Warning** Using self-signed certificates are intended for development and testing. Outside of development and testing, a certificate from a trusted CA is recommended.
3+
4+
> **Note** The following guide can be executed on Linux bash, macOS Zsh and Windows WSL
5+
1. [Install the Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli)
6+
2. Log in using the Azure CLI, set the subscription, and confirm the `GetCertificate` and `Sign` permission have been granted to your role:
7+
```sh
8+
az login
9+
az account set --subscription $subscriptionID
10+
```
11+
3. Create an Azure Key Vault:
12+
```sh
13+
resourceGroup=<your-resource-group-name>
14+
keyVault=<your-key-vault-name>
15+
location=westus
16+
certName=notationSelfSignedCert
17+
18+
# create a resource group
19+
az group create -n $resourceGroup -l $location
20+
21+
# create a Azure Key Vault
22+
az keyvault create -l $location -n $keyVault --resource-group $resourceGroup
23+
```
24+
4. create a self-signed certificate:
25+
```sh
26+
# generate certificate policy
27+
cat <<EOF > ./selfSignedPolicy.json
28+
{
29+
"issuerParameters": {
30+
"certificateTransparency": null,
31+
"name": "Self"
32+
},
33+
"keyProperties": {
34+
"curve": null,
35+
"exportable": false,
36+
"keySize": 2048,
37+
"keyType": "RSA",
38+
"reuseKey": true
39+
},
40+
"secretProperties": {
41+
"contentType": "application/x-pem-file"
42+
},
43+
"x509CertificateProperties": {
44+
"ekus": [
45+
"1.3.6.1.5.5.7.3.3"
46+
],
47+
"keyUsage": [
48+
"digitalSignature"
49+
],
50+
"subject": "CN=Test-Signer,C=US,ST=WA,O=notation",
51+
"validityInMonths": 12
52+
}
53+
}
54+
EOF
55+
56+
# create self-signed certificate
57+
az keyvault certificate create -n $certName --vault-name $keyVault -p @selfSignedPolicy.json
58+
59+
# get the key identifier
60+
keyID=$(az keyvault certificate show -n $certName --vault-name $keyVault --query 'kid' -o tsv)
61+
```
62+
5. [Create an Azure Container Registry](https://learn.microsoft.com/azure/container-registry/container-registry-get-started-portal?tabs=azure-cli). The remaining steps use the example login server `<registry-name>.azurecr.io`, but you must substitute your own login server value.
63+
6. Log in to container registry and push an image for signing:
64+
```sh
65+
registryName="<registry-name>"
66+
server="${registryName}.azurecr.io"
67+
68+
az acr login --name $registryName
69+
# notation login $server # if you don't use Azure Container Registry
70+
71+
# push a hello-world image for signing
72+
docker pull hello-world:latest
73+
docker tag hello-world:latest $server/hello-world:v1
74+
docker push $server/hello-world:v1
75+
```
76+
7. Sign the container image with Notation:
77+
```sh
78+
notation key add --plugin azure-kv --id $keyID akv-key --default
79+
notation sign $server/hello-world:v1
80+
```
81+
82+
The following example output shows the artifact is successfully signed.
83+
```
84+
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.
85+
Successfully signed notation.azurecr.io/hello-world@sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4
86+
```
87+
8. Add the certificate to your trust store and the `trustpolicy.json` to Notation configuration directory:
88+
```sh
89+
cat <<EOF > ./selfSignedCert.crt
90+
-----BEGIN CERTIFICATE-----
91+
$(az keyvault certificate show -n $certName --vault-name $keyVault --query 'cer' -o tsv)
92+
-----END CERTIFICATE-----
93+
EOF
94+
notation cert add --type ca --store selfSigned ./selfSignedCert.crt
95+
96+
# add notation trust policy
97+
notationConfigDir="${HOME}/.config/notation" # for Linux and WSL
98+
# notationConfigDir="${HOME}/Library/Application Support/notation" # for macOS
99+
100+
mkdir -p $notationConfigDir
101+
cat <<EOF > $notationConfigDir/trustpolicy.json
102+
{
103+
"version": "1.0",
104+
"trustPolicies": [
105+
{
106+
"name": "trust-policy-example",
107+
"registryScopes": [ "*" ],
108+
"signatureVerification": {
109+
"level" : "strict"
110+
},
111+
"trustStores": [ "ca:selfSigned" ],
112+
"trustedIdentities": [
113+
"*"
114+
]
115+
}
116+
]
117+
}
118+
EOF
119+
chmod 600 $notationConfigDir/trustpolicy.json
120+
```
121+
9. Verify the signature associated with the image:
122+
```sh
123+
notation verify $server/hello-world:v1
124+
```
125+
The following output shows the artifact is successfully verified.
126+
```
127+
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.
128+
Successfully verified signature for notation.azurecr.io/hello-world@sha256:f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4
129+
```

internal/keyvault/keyvault_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ type keyVault struct {
7272
err error
7373
}
7474

75-
func (s *keyVault) Sign(ctx context.Context, name string, version string, parameters azkeys.SignParameters, options *azkeys.SignOptions) (azkeys.SignResponse, error) {
75+
func (s *keyVault) Sign(_ context.Context, _ string, _ string, _ azkeys.SignParameters, _ *azkeys.SignOptions) (azkeys.SignResponse, error) {
7676
return s.resp, s.err
7777
}
7878

@@ -142,7 +142,7 @@ type certificateVault struct {
142142
err error
143143
}
144144

145-
func (s *certificateVault) GetCertificate(ctx context.Context, certificateName string, certificateVersion string, options *azcertificates.GetCertificateOptions) (azcertificates.GetCertificateResponse, error) {
145+
func (s *certificateVault) GetCertificate(_ context.Context, _ string, _ string, _ *azcertificates.GetCertificateOptions) (azcertificates.GetCertificateResponse, error) {
146146
return s.resp, s.err
147147
}
148148

@@ -191,7 +191,7 @@ type secretVault struct {
191191
err error
192192
}
193193

194-
func (s *secretVault) GetSecret(ctx context.Context, name string, version string, options *azsecrets.GetSecretOptions) (azsecrets.GetSecretResponse, error) {
194+
func (s *secretVault) GetSecret(_ context.Context, _ string, _ string, _ *azsecrets.GetSecretOptions) (azsecrets.GetSecretResponse, error) {
195195
return s.resp, s.err
196196
}
197197

0 commit comments

Comments
 (0)