diff --git a/.spelling b/.spelling index c9f5c3f3977..14c57364f27 100644 --- a/.spelling +++ b/.spelling @@ -71,6 +71,10 @@ AzureDNS BKPR Bazel Bitnami +BundleSource +BundleTarget +BundleCondition +NamespaceSelector CAs CNAME CNAMEs diff --git a/content/docs/configuration/ca.md b/content/docs/configuration/ca.md index 9c1fb479f46..fffb6f2401d 100644 --- a/content/docs/configuration/ca.md +++ b/content/docs/configuration/ca.md @@ -13,8 +13,10 @@ The CA issuer represents a Certificate Authority whose certificate and private key are stored inside the cluster as a Kubernetes `Secret`. Certificates issued by a CA issuer will not be publicly trusted and so are unlikely to be trusted -by your applications without further configuration work. Consider the [trust-manager](../projects/trust-manager.md) -project for distributing trust stores. +by your applications without further configuration. + +Consider [trust-manager](../projects/trust-manager/README.md) for distributing your CA certificate safely +across your cluster! ## Deployment diff --git a/content/docs/configuration/selfsigned.md b/content/docs/configuration/selfsigned.md index edd591e7bf5..bfc2b39b2b4 100644 --- a/content/docs/configuration/selfsigned.md +++ b/content/docs/configuration/selfsigned.md @@ -136,12 +136,14 @@ spec: ### Trust Clients consuming `SelfSigned` certificates have _no way_ to trust them -without already having the certificates beforehand. This becomes hard to -manage when the client of the server using the certificate exists in a -different namespace. This limitation can be tackled by using [trust-manager](../projects/trust-manager.md) -to distribute the `ca.crt` to other namespaces. The alternative is to use -"TOFU" (trust on first use), which has security implications in the event -of a man-in-the-middle attack. +without already having the certificates beforehand, which can be hard to +manage when the client is in a different namespace to the server. + +This limitation can be tackled by using [trust-manager](../projects/trust-manager/README.md) to distribute `ca.crt` +to other namespaces. + +There is no secure alternative to solving the problem of distributing trust stores; it's possible +to "TOFU" (trust-on-first-use) a certificate, but that approach is vulnerable to man-in-the-middle attacks. ### Certificate Validity diff --git a/content/docs/manifest.json b/content/docs/manifest.json index 7d87d242fdf..99c484c28de 100644 --- a/content/docs/manifest.json +++ b/content/docs/manifest.json @@ -343,7 +343,16 @@ }, { "title": "trust-manager", - "path": "/docs/projects/trust-manager.md" + "routes": [ + { + "title": "Introduction", + "path": "/docs/projects/trust-manager/README.md" + }, + { + "title": "API Reference", + "path": "/docs/projects/trust-manager/api-reference.md" + } + ] } ] }, diff --git a/content/docs/projects/README.md b/content/docs/projects/README.md index 85f49e9301f..20200adceb8 100644 --- a/content/docs/projects/README.md +++ b/content/docs/projects/README.md @@ -28,6 +28,7 @@ These tools help with security, compliance and control. in the form of X.509 certificate key pairs to mounting Kubernetes Pods. The end result is all and any Pod running in Kubernetes can securely request their SPIFFE identity document from a Trust Domain with minimal configuration. -- [trust-manager](./trust-manager.md): an +- [trust-manager](./trust-manager/README.md): an operator to distribute trust bundles, like CA certificates, across a Kubernetes cluster. +- [trust-manager API reference](./trust-manager/api-reference.md): full documentation of the trust-manager CRD(s) diff --git a/content/docs/projects/trust-manager.md b/content/docs/projects/trust-manager/README.md similarity index 100% rename from content/docs/projects/trust-manager.md rename to content/docs/projects/trust-manager/README.md diff --git a/content/docs/projects/trust-manager/api-reference.md b/content/docs/projects/trust-manager/api-reference.md new file mode 100644 index 00000000000..0d1f9642e6d --- /dev/null +++ b/content/docs/projects/trust-manager/api-reference.md @@ -0,0 +1,464 @@ +--- +title: trust-manager API Reference +description: "trust-manager API documentation for custom resources" +--- + +Packages: + +- [`trust.cert-manager.io/v1alpha1`](#trustcert-manageriov1alpha1) + +# `trust.cert-manager.io/v1alpha1` + +Resource Types: + + +- [Bundle](#bundle) + + + + +## `Bundle` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
apiVersionstringtrust.cert-manager.io/v1alpha1true
kindstringBundletrue
metadataobjectRefer to the Kubernetes API documentation for the fields of the `metadata` field.true
specobject + Desired state of the Bundle resource.
+
true
statusobject + Status of the Bundle. This is set and managed automatically.
+
false
+ + +### `Bundle.spec` + + +Desired state of the Bundle resource. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
sources[]object + Sources is a set of references to data whose data will sync to the target.
+
true
targetobject + Target is the target location in all namespaces to sync source data to.
+
true
+ + +### `Bundle.spec.sources[index]` + + +BundleSource is the set of sources whose data will be appended and synced to the BundleTarget in all Namespaces. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
configMapobject + ConfigMap is a reference to a ConfigMap's `data` key, in the trust Namespace.
+
false
inLinestring + InLine is a simple string to append as the source data.
+
false
secretobject + Secret is a reference to a Secrets's `data` key, in the trust Namespace.
+
false
+ + +### `Bundle.spec.sources[index].configMap` + + +ConfigMap is a reference to a ConfigMap's `data` key, in the trust Namespace. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
keystring + Key is the key of the entry in the object's `data` field to be used.
+
true
namestring + Name is the name of the source object in the trust Namespace.
+
true
+ + +### `Bundle.spec.sources[index].secret` + + +Secret is a reference to a Secrets's `data` key, in the trust Namespace. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
keystring + Key is the key of the entry in the object's `data` field to be used.
+
true
namestring + Name is the name of the source object in the trust Namespace.
+
true
+ + +### `Bundle.spec.target` + + +Target is the target location in all namespaces to sync source data to. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
configMapobject + ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to.
+
false
namespaceSelectorobject + NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector.
+
false
+ + +### `Bundle.spec.target.configMap` + + +ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
keystring + Key is the key of the entry in the object's `data` field to be used.
+
true
+ + +### `Bundle.spec.target.namespaceSelector` + + +NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
matchLabelsmap[string]string + MatchLabels matches on the set of labels that must be present on a Namespace for the Bundle target to be synced there.
+
false
+ + +### `Bundle.status` + + +Status of the Bundle. This is set and managed automatically. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
conditions[]object + List of status conditions to indicate the status of the Bundle. Known condition types are `Bundle`.
+
false
targetobject + Target is the current Target that the Bundle is attempting or has completed syncing the source data to.
+
false
+ + +### `Bundle.status.conditions[index]` + + +BundleCondition contains condition information for a Bundle. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
statusstring + Status of the condition, one of ('True', 'False', 'Unknown').
+
true
typestring + Type of the condition, known values are (`Synced`).
+
true
lastTransitionTimestring + LastTransitionTime is the timestamp corresponding to the last status change of this condition.
+
+ Format: date-time
+
false
messagestring + Message is a human readable description of the details of the last transition, complementing reason.
+
false
observedGenerationinteger + If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Bundle.
+
+ Format: int64
+
false
reasonstring + Reason is a brief machine readable explanation for the condition's last transition.
+
false
+ + +### `Bundle.status.target` + + +Target is the current Target that the Bundle is attempting or has completed syncing the source data to. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
configMapobject + ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to.
+
false
namespaceSelectorobject + NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector.
+
false
+ + +### `Bundle.status.target.configMap` + + +ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
keystring + Key is the key of the entry in the object's `data` field to be used.
+
true
+ + +### `Bundle.status.target.namespaceSelector` + + +NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
matchLabelsmap[string]string + MatchLabels matches on the set of labels that must be present on a Namespace for the Bundle target to be synced there.
+
false
diff --git a/scripts/bin/crdoc b/scripts/bin/crdoc new file mode 100755 index 00000000000..b6b401044d7 --- /dev/null +++ b/scripts/bin/crdoc @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +# Copyright 2023 The cert-manager Authors. +# +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +# This script downloads a crdoc binary for local use if such a binary doesn't already exist. + +REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)}" +VERSION="0.6.2" + +source "${REPO_ROOT}/scripts/bin/lib.sh" + +crdoc="${REPO_ROOT}/bin/crdoc" +mkdir -p "$(dirname "$crdoc")" + +if ! command -v curl &>/dev/null; then + echo "Ensure curl command is installed" + exit 1 +fi + +if ! test -f "${crdoc}"; then + echo "+++ Fetching crdoc binary and saving to $crdoc" + detect_and_set_goos_goarch + + tmpdir="$(mktemp -d)" + + if [ "$GOOS" = "darwin" ]; then + curl -Lo "${tmpdir}/file" "https://github.com/fybrik/crdoc/releases/download/v${VERSION}/crdoc_${VERSION}_Darwin_x86_64.tar.gz" + + check_sha "${tmpdir}/file" "dbc00cbb59115a8fea8c3027423c14e3209f13d7019a9a3be267b2760b85d28a" + elif [ "$GOOS" = "linux" ]; then + curl -Lo "${tmpdir}/file" "https://github.com/fybrik/crdoc/releases/download/v${VERSION}/crdoc_${VERSION}_Linux_x86_64.tar.gz" + + check_sha "${tmpdir}/file" "8a513a59c78462b65ef2bfe0bfc5d4981d7d6632c627d01ba1431c3afda0b251" + else + echo "Unsupported OS: $GOOS" + exit 1 + fi + + tar xfO "${tmpdir}/file" "crdoc" > ${crdoc} + + chmod +x "${crdoc}" + rm -rf "${tmpdir}" +fi + +"${crdoc}" "$@" diff --git a/scripts/gendocs/generate b/scripts/gendocs/generate index 003c63b54e7..d05f972655b 100755 --- a/scripts/gendocs/generate +++ b/scripts/gendocs/generate @@ -25,6 +25,12 @@ REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)}" ${REPO_ROOT}/scripts/gendocs/generate-new-import-path-docs +# NOTE: Currently, generate-trust-manager builds against a specific named tag. Given that we we should (hopefully) +# never change an already existing tag, there's little need to run this script against every build, but we might +# want to add this in the future if we start building against branches (as we do for cert-manager) + +# ${REPO_ROOT}/scripts/gendocs/generate-trust-manager + ###### WARNING ###### # If you uncomment the below line to build API docs with the import path "github.com/jetstack/cert-manager", # you'll also need to uncomment versions in "${REPO_ROOT}/scripts/gendocs/generate-old-import-path-docs" diff --git a/scripts/gendocs/generate-trust-manager b/scripts/gendocs/generate-trust-manager new file mode 100755 index 00000000000..f7027bd68b1 --- /dev/null +++ b/scripts/gendocs/generate-trust-manager @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright 2023 The cert-manager Authors. +# +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +REPO_ROOT="${REPO_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)}" + +CRDOC=${REPO_ROOT}/scripts/bin/crdoc + +tmpdir="$(mktemp -d)" + +cleanup() { + echo "+++ Cleaning up tmpdir" + rm -rf "${tmpdir}" +} +trap cleanup EXIT + +checkout() { + ref="$1" + + pushd "$tmpdir" + + echo "+++ Checking out trust-manager ref $ref" + + git fetch origin "$ref" + git reset --hard "$ref" +} + +gendocs() { + outputdir="$1" + + echo "+++ Generating trust-manager reference docs..." + + $CRDOC \ + --resources "$tmpdir/deploy/charts/trust-manager/templates/trust.cert-manager.io_bundles.yaml" \ + --template $REPO_ROOT/scripts/gendocs/templates-trust-manager/markdown.tmpl \ + --output $outputdir +} + +# Note that this script only supports generating a single version of trust-manager API docs, +# since trust-manager is under active development and we wouldn't generally expect older version +# of docs to be useful. The version is also hardcoded for simplicity + +echo "+++ Cloning trust-manager repository..." +git clone "https://github.com/cert-manager/trust-manager.git" "$tmpdir" + +checkout "v0.3.0" + +gendocs "$REPO_ROOT/content/docs/projects/trust-manager/api-reference.md" diff --git a/scripts/gendocs/templates-trust-manager/markdown.tmpl b/scripts/gendocs/templates-trust-manager/markdown.tmpl new file mode 100644 index 00000000000..aac77c9c57c --- /dev/null +++ b/scripts/gendocs/templates-trust-manager/markdown.tmpl @@ -0,0 +1,97 @@ +--- +title: trust-manager API Reference +description: "trust-manager API documentation for custom resources" +--- + +Packages: +{{range .Groups}} +- [`{{.Group}}/{{.Version}}`](#{{ anchorize (printf "%s/%s" .Group .Version) }}) +{{- end -}}{{/* range .Groups */}} + +{{- range .Groups }} +{{- $group := . }} + +# `{{.Group}}/{{.Version}}` + +Resource Types: + +{{range .Kinds}} +- [{{.Name}}](#{{ anchorize .Name }}) +{{end}}{{/* range .Kinds */}} + +{{range .Kinds}} +{{$kind := .}} +## `{{.Name}}` + +{{range .Types}} + +{{if not .IsTopLevel}} +### `{{.Name}}` +{{end}} + +{{.Description}} + + + + + + + + + + + + {{- if .IsTopLevel -}} + + + + + + + + + + + + + + + + + + + {{- end -}} + {{- range .Fields -}} + + + + + + + {{- end -}} + +
NameTypeDescriptionRequired
apiVersionstring{{$group.Group}}/{{$group.Version}}true
kindstring{{$kind.Name}}true
metadataobjectRefer to the Kubernetes API documentation for the fields of the `metadata` field.true
{{if .TypeKey}}{{.Name}}{{else}}{{.Name}}{{end}}{{.Type}} + {{.Description}}
+ {{- if or .Schema.Format .Schema.Enum .Schema.Default .Schema.Minimum .Schema.Maximum }} +
+ {{- end}} + {{- if .Schema.Format }} + Format: {{ .Schema.Format }}
+ {{- end }} + {{- if .Schema.Enum }} + Enum: {{ .Schema.Enum | toStrings | join ", " }}
+ {{- end }} + {{- if .Schema.Default }} + Default: {{ .Schema.Default }}
+ {{- end }} + {{- if .Schema.Minimum }} + Minimum: {{ .Schema.Minimum }}
+ {{- end }} + {{- if .Schema.Maximum }} + Maximum: {{ .Schema.Maximum }}
+ {{- end }} +
{{.Required}}
+ +{{- end}}{{/* range .Types */}} +{{- end}}{{/* range .Kinds */}} +{{- end}}{{/* range .Groups */}}