├── .github ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── config.yml │ ├── documentation-request.md │ └── enhancement.md ├── PULL_REQUEST_TEMPLATE ├── dependabot.yml ├── labeler.yml └── workflows │ ├── actionlint.yml │ ├── dependabot-auto-merge.yml │ ├── docker-image.yml │ └── triage.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE ├── README.md ├── autocert ├── .helmignore ├── Chart.lock ├── Chart.yaml ├── README.md ├── charts │ └── step-certificates-1.27.4.tgz ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── autocert.yaml │ ├── configmaps.yaml │ ├── rbac.yaml │ ├── secrets.yaml │ ├── service.yaml │ ├── tests │ │ └── test-connection.yaml │ └── webhook.yaml └── values.yaml ├── deploy.sh ├── docker └── step-ca-bootstrap │ ├── Dockerfile │ ├── Makefile │ └── entrypoint.sh ├── step-certificates ├── .helmignore ├── Chart.yaml ├── README.md ├── examples │ ├── README.md │ ├── certificate_authority_single_instance │ │ ├── .gitignore │ │ ├── ca.config │ │ ├── generate-values.sh │ │ ├── intermediate-tls.json.tpl │ │ ├── root-tls.json.tpl │ │ └── values.yml.tpl │ ├── existing_secrets │ │ └── values.yaml │ └── registration_authority │ │ └── values.yml ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── bootstrap.yaml │ ├── ca.yaml │ ├── configmaps.yaml │ ├── ingress.yaml │ ├── rbac.yaml │ ├── secrets.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ │ └── test-connection.yaml └── values.yaml └── step-issuer ├── .helmignore ├── Chart.yaml ├── README.md ├── crds ├── certmanager.step.sm_stepclusterissuers.yaml └── certmanager.step.sm_stepissuers.yaml ├── templates ├── NOTES.txt ├── _helpers.tpl ├── deployment.yaml ├── rbac │ ├── clusterRole.yaml │ ├── clusterRoleBinding.yaml │ ├── role.yaml │ ├── roleBinding.yaml │ └── sa.yaml ├── service.yaml ├── stepclusterissuer.yaml ├── stepissuer.yml └── tunnel.yaml └── values.yaml /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Subject of the issue 11 | Describe your issue here. 12 | 13 | ### Your environment 14 | * OS - 15 | * Version - 16 | 17 | ### Steps to reproduce 18 | Tell us how to reproduce this issue. Please provide a working demo, you can use [this template](https://plnkr.co/edit/XorWgI?p=preview) as a base. 19 | 20 | ### Expected behaviour 21 | Tell us what should happen. 22 | 23 | ### Actual behaviour 24 | Tell us what happens instead. 25 | 26 | ### Additional context 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Ask on Discord 4 | url: https://discord.gg/7xgjhVAg6g 5 | about: You can ask for help here! 6 | - name: Want to contribute to step Helm Charts? 7 | url: https://github.com/smallstep/cli/blob/master/docs/CONTRIBUTING.md 8 | about: Be sure to read contributing guidelines! 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation Request 3 | about: Request documentation for a feature 4 | title: '' 5 | labels: docs, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement 3 | about: Suggest an enhancement to helm-charts 4 | title: '' 5 | labels: enhancement, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### What would you like to be added 11 | 12 | 13 | ### Why this is needed 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | ### Description 2 | Please describe your pull request. 3 | 4 | ❤Thank you! 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | needs triage: 2 | - '**' # index.php | src/main.php 3 | - '.*' # .gitignore 4 | - '.*/**' # .github/workflows/label.yml 5 | -------------------------------------------------------------------------------- /.github/workflows/actionlint.yml: -------------------------------------------------------------------------------- 1 | name: Lint GitHub Actions workflows 2 | on: 3 | push: 4 | workflow_call: 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 8 | cancel-in-progress: true 9 | 10 | permissions: 11 | contents: write 12 | pull-requests: write 13 | 14 | jobs: 15 | actionlint: 16 | uses: smallstep/workflows/.github/workflows/actionlint.yml@main 17 | secrets: inherit 18 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-auto-merge.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot auto-merge 2 | on: pull_request 3 | 4 | permissions: 5 | contents: write 6 | pull-requests: write 7 | 8 | jobs: 9 | dependabot-auto-merge: 10 | uses: smallstep/workflows/.github/workflows/dependabot-auto-merge.yml@main 11 | secrets: inherit 12 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: docker-image 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | paths-ignore: 8 | - '**.md' 9 | - '.github/workflows/docs.yml' 10 | 11 | jobs: 12 | docker: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | - name: Prepare 18 | id: prepare 19 | run: | 20 | DOCKER_IMAGE=smallstep/step-ca-bootstrap 21 | DOCKER_PLATFORMS=linux/amd64,linux/386,linux/arm,linux/arm64 22 | VERSION=latest 23 | if [[ $GITHUB_REF == refs/tags/* ]]; then 24 | VERSION="${GITHUB_REF#refs/tags/v}" 25 | fi 26 | TAGS="--tag ${DOCKER_IMAGE}:${VERSION}" 27 | if [[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then 28 | TAGS="$TAGS --tag ${DOCKER_IMAGE}:latest" 29 | fi 30 | # shellcheck disable=SC2129 31 | echo "docker_image=${DOCKER_IMAGE}" >> "${GITHUB_OUTPUT}" 32 | echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" 33 | echo "buildx_args=--platform ${DOCKER_PLATFORMS} \ 34 | --build-arg VERSION=${VERSION} \ 35 | --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \ 36 | --build-arg VCS_REF=${GITHUB_SHA::8} \ 37 | ${TAGS} --file docker/step-ca-bootstrap/Dockerfile docker/step-ca-bootstrap/" >> "${GITHUB_OUTPUT}" 38 | - name: Set up QEMU 39 | uses: docker/setup-qemu-action@v3 40 | - name: Set up Docker Buildx 41 | id: buildx 42 | uses: docker/setup-buildx-action@v3 43 | - name: Docker Buildx (build) 44 | run: | 45 | docker buildx build --output "type=image,push=false" ${{ steps.prepare.outputs.buildx_args }} 46 | - name: Login to DockerHub 47 | if: success() && github.event_name != 'pull_request' && (endsWith(github.ref, github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/')) 48 | run: | 49 | echo '${{ secrets.DOCKER_PASSWORD }}' | docker login -u="${{ secrets.DOCKER_USERNAME }}" --password-stdin 50 | - name: Docker Buildx (push) 51 | if: success() && github.event_name != 'pull_request' && (endsWith(github.ref, github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/')) 52 | run: | 53 | docker buildx build --output "type=image,push=true" ${{ steps.prepare.outputs.buildx_args }} 54 | - name: Docker Check Manifest 55 | if: success() && github.event_name != 'pull_request' && (endsWith(github.ref, github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/')) 56 | run: | 57 | docker run --rm mplatform/mquery ${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }} 58 | -------------------------------------------------------------------------------- /.github/workflows/triage.yml: -------------------------------------------------------------------------------- 1 | name: Add Issues and PRs to Triage 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - reopened 8 | pull_request_target: 9 | types: 10 | - opened 11 | - reopened 12 | 13 | jobs: 14 | triage: 15 | uses: smallstep/workflows/.github/workflows/triage.yml@main 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Common backup files 2 | .DS_Store 3 | *.swp 4 | *.bak 5 | *.tmp 6 | *~ 7 | # Various IDEs 8 | .project 9 | .idea/ 10 | *.tmproj 11 | .vscode/ 12 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @smallstep/core 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Smallstep Helm Charts 2 | 3 | [Helm](https://helm.sh) packages for Kubernetes. The master branch of this 4 | repository contains work in progress packages. 5 | 6 | Visit https://smallstep.github.io/helm-charts/ for stable releases. 7 | 8 | ## Packages 9 | 10 | * [Step Certificates](./step-certificates/README.md): An online certificate authority and 11 | related tools for secure automated certificate management, so you can use TLS 12 | everywhere. 13 | 14 | * [Autocert](./autocert/README.md): A kubernetes add-on that automatically 15 | injects TLS/HTTPS certificates into your containers. 16 | 17 | * [Step Issuer](./step-issuer/README.md): A certificate issuer for cert-manager 18 | using Step Certificates. 19 | 20 | ## Distribution 21 | 22 | 1. Update `version` in _packageName/Chart.yaml_. 23 | 24 | 2. Update `appVersion` to the image tag in _packageName/Chart.yaml_. 25 | 26 | 3. Commit these changes to a branch and push the branch to the origin. 27 | Open a PR for merging to master. 28 | 29 | 4. Create helm package (using `step-certificates` as an example): 30 | 31 | ```sh 32 | helm package ./step-certificates 33 | ``` 34 | 35 | 5. Update repository (using `step-certificates` as an example): 36 | 37 | ```sh 38 | ./deploy.sh ./step-certificates 39 | ``` 40 | -------------------------------------------------------------------------------- /autocert/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /autocert/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: step-certificates 3 | repository: https://smallstep.github.io/helm-charts 4 | version: 1.27.4 5 | digest: sha256:b2c0916bae9b060987051053e1335a00fcb65f588e03ba1f81ceb5cf822936c6 6 | generated: "2024-10-08T11:46:03.986247-07:00" 7 | -------------------------------------------------------------------------------- /autocert/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: autocert 3 | version: 1.20.1 4 | appVersion: 0.20.1 5 | description: A kubernetes add-on that automatically injects TLS/HTTPS certificates into your containers. 6 | keywords: 7 | - ca 8 | - tls 9 | - pki 10 | - x509 11 | - step 12 | - step-ca 13 | - step-certificates 14 | - smallstep 15 | - certificate 16 | - certificates 17 | - authority 18 | - security 19 | - security-tools 20 | - certificate-authority 21 | - kubernetes 22 | home: https://smallstep.com 23 | icon: https://raw.githubusercontent.com/smallstep/autocert/master/icon.png 24 | sources: 25 | - https://github.com/smallstep/autocert 26 | maintainers: 27 | - name: Mariano Cano 28 | email: mariano@smallstep.com 29 | dependencies: 30 | - name: step-certificates 31 | version: 1.27.4 32 | repository: https://smallstep.github.io/helm-charts 33 | condition: step-certificates.enabled 34 | tags: 35 | - step-certificates 36 | -------------------------------------------------------------------------------- /autocert/README.md: -------------------------------------------------------------------------------- 1 | # Autocert 2 | 3 | A kubernetes add-on that automatically injects TLS/HTTPS certificates into your 4 | containers. 5 | 6 | To learn more, visit https://github.com/smallstep/certificates/tree/master/autocert. 7 | 8 | ## TL;DR 9 | 10 | ```console 11 | helm install autocert smallstep/autocert 12 | kubectl label namespace default autocert.step.sm=enabled 13 | ``` 14 | 15 | ## Prerequisites 16 | 17 | - Kubernetes 1.10+ 18 | 19 | ## Installing the Chart 20 | 21 | To install the chart with the release name `my-release`: 22 | 23 | ```console 24 | helm install my-release smallstep/autocert 25 | ``` 26 | 27 | The command deploys Autocert on the Kubernetes cluster in the default 28 | configuration. The [configuration](#configuration) section lists the parameters 29 | that can be configured during installation. 30 | 31 | > **Tip**: List all releases using `helm list` 32 | 33 | By default `autocert` helm chart installs a new `step-certificates` deployment. 34 | But if you already have an instance of `step-certificates` running you can 35 | configure it with autocert setting the values in the `ca` block like this: 36 | 37 | ```yaml 38 | ca: 39 | url: https://ca.example.com 40 | # provisioner is the provisioner name and password that autocert will use 41 | provisioner: 42 | name: admin 43 | password: my-plaintext-password 44 | # certs is the configmap in yaml that should contain the CA root certificate. 45 | certs: 46 | root_ca.crt: |- 47 | -----BEGIN CERTIFICATE----- 48 | MIIBdjCCAR2gAwIBAgIQNFvgRJo4ZuvaRquC9gB3WTAKBggqhkjOPQQDAjAaMRgw 49 | FgYDVQQDEw9FeGFtcGxlIFJvb3QgQ0EwHhcNMjExMjEzMjMxNTU4WhcNMzExMjEx 50 | MjMxNTU4WjAaMRgwFgYDVQQDEw9FeGFtcGxlIFJvb3QgQ0EwWTATBgcqhkjOPQIB 51 | BggqhkjOPQMBBwNCAAQlQRnmP9NZ2/L1iMWE1vGwOraPR3hUeashSdIWZk+snrQG 52 | Mt+DXBEz8AxlV5+nNtncYErtzIV8exX+fY7V8agVo0UwQzAOBgNVHQ8BAf8EBAMC 53 | AQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUxjwLhVkVREOolv5CA/J1 54 | QQ6SqhowCgYIKoZIzj0EAwIDRwAwRAIgf0MmZJhkAdyXscYQXLANdMUKJXx/JPjL 55 | XwH5kIIJvB0CIB+aMuA8aFpK/Ld1hkqrdzuvCLiD3cSaOAFzNJqFdCuo 56 | -----END CERTIFICATE----- 57 | # config is the configmap in yaml to use. This is currently optional only. 58 | config: 59 | defaults.json: |- 60 | {} 61 | ``` 62 | 63 | And then install autocert using a config.yaml like the above one, and setting 64 | the value `step-certificates.enabled` to `false`: 65 | 66 | ```console 67 | helm install --set step-certificates.enabled=false -f config.yaml my-release smallstep/autocert 68 | ``` 69 | 70 | > **Note**: Future version of the autocert helm-chart will not install 71 | > step-certificates and it will require these values. 72 | 73 | ## Uninstalling the Chart 74 | 75 | To uninstall/delete the `my-release` deployment: 76 | 77 | ```console 78 | helm delete my-release 79 | ``` 80 | 81 | The command removes all the Kubernetes components associated with the chart and 82 | deletes the release. 83 | 84 | ## Enable Autocert (per namespace) 85 | 86 | To enable Autocert for a namespace it must be labelled 87 | `autocert.step.sm=enabled`. 88 | 89 | To label the default namespace run: 90 | 91 | ```console 92 | kubectl label namespace default autocert.step.sm=enabled 93 | ``` 94 | 95 | To check which namespaces have Autocert enabled run: 96 | 97 | ```console 98 | $ kubectl get namespace -L autocert.step.sm 99 | NAME STATUS AGE AUTOCERT.STEP.SM 100 | default Active 59m enabled 101 | ... 102 | ``` 103 | 104 | ## Configuration 105 | 106 | The following table lists the configurable parameters of the Autocert chart and 107 | their default values. 108 | 109 | | Parameter | Description | Default | 110 | |--------------------------------------------|-----------------------------------------------------------------------------------|-----------------------------------------------| 111 | | `replicaCount` | Number of Autocert replicas | `1` | 112 | | `nameOverride` | Overrides the name of the chart | `""` | 113 | | `fullnameOverride` | Overrides the full name of the chart | `""` | 114 | | `service.type` | Service type | `ClusterIP` | 115 | | `service.port` | Incoming port to access Autocert | `443` | 116 | | `service.targetPort` | Internal port where Autocert runs | `4443` | 117 | | `autocert.image.repository` | Repository of the Autocert image | `cr.step.sm/smallstep/autocert-controller` | 118 | | `autocert.image.tag` | Tag of the Autocert image | `0.12.2` | 119 | | `autocert.image.pullPolicy` | Autocert image pull policy | `IfNotPresent` | 120 | | `autocert.label` | Label uses to enable Autocert in a namespaces (should not be changed) | `autocert.step.sm` | 121 | | `autocert.logFormat` | Log format, `json` or `text` | `json` | 122 | | `autocert.restrictCertificatesToNamespace` | If certificate names are restricted to the namespace | `false` | 123 | | `autocert.closterDomain` | Cluster domain name | `cluster.local` | 124 | | `autocert.certLifetime` | Certificate lifetime | `24h` | 125 | | `autocert.resources` | CPU/memory resource requests/limits (YAML) | `{requests: {cpu: 100m, memory: 20Mi}}` | 126 | | `autocert.nodeSelector` | Node labels for pod assignment (YAML) | `{}` | 127 | | `autocert.tolerations` | Toleration labels for pod assignment (YAML) | `[]` | 128 | | `autocert.affinity` | Affinity settings for pod assignment (YAML) | `{}` | 129 | | `bootstrapper.image.repository` | Repository of the Autocert bootstrapper image | `cr.step.sm/smallstep/autocert-bootstrapper` | 130 | | `bootstrapper.image.tag` | Tag of the Autocert bootstrapper image | `0.12.2` | 131 | | `bootstrapper.image.pullPolicy` | Autocert bootstrapper image pull policy | `IfNotPresent` | 132 | | `bootstrapper.resources` | CPU/memory resource requests/limits (YAML) | `{}` | 133 | | `renewer.image.repository` | Repository of the Autocert renewer image | `cr.step.sm/smallstep/autocert-renewer` | 134 | | `renewer.image.tag` | Tag of the Autocert renewer image | `0.12.2` | 135 | | `renewer.image.pullPolicy` | Autocert renewer image pull policy | `IfNotPresent` | 136 | | `renewer.resources` | CPU/memory resource requests/limits (YAML) | `{}` | 137 | | `ingress.enabled` | If true Autocert ingress will be created | `false` | 138 | | `ingress.annotations` | Autocert ingress annotations (YAML) | `{}` | 139 | | `ingress.hosts` | Autocert ingress hostNAMES (YAML) | `[]` | 140 | | `ingress.tls` | Autocert ingress TLS configuration (YAML) | `[]` | 141 | | `step-certificates.enabled` | Enables the installation of the `step-certificates` sub-chart | `true` | 142 | | `step-certificates.autocert.enabled` | Enables autocert in `step-certificates` sub-chart | `true` | 143 | | `ca.url` | Sets a custom CA URL, to be used with an existing `step-certificates` | `""` | 144 | | `ca.provisioner.name` | The provisioner name to use | `""` | 145 | | `ca.provisioner.password` | The plaintext version of provisioner password | `""` | 146 | | `ca.certs` | The files to write in the certs configmap, it should contain the root_ca.crt | `""` | 147 | | `ca.config` | The files to write in the config configmap, it might contain a defaults.json | `{}` | 148 | 149 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm 150 | install`. For example, 151 | 152 | ```console 153 | helm install my-release \ 154 | --set autocert.logFormat=text,step-certificates.ca.name=Foo \ 155 | autocert 156 | ``` 157 | 158 | The above command sets the Autocert provisioner `Foo` with the key password 159 | `secretpassword`. 160 | 161 | Alternatively, a YAML file that specifies the values for the parameters can be 162 | provided while installing the chart. For example, 163 | 164 | ```console 165 | helm install --name my-release -f values.yaml autocert 166 | ``` 167 | 168 | > **Tip**: You can use the default [values.yaml](values.yaml) 169 | -------------------------------------------------------------------------------- /autocert/charts/step-certificates-1.27.4.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smallstep/helm-charts/95fa05af2289b6ac29e56233cd6738b2bdc58807/autocert/charts/step-certificates-1.27.4.tgz -------------------------------------------------------------------------------- /autocert/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 2 | Thanks for installing Autocert. 3 | 4 | 1. Enable Autocert in your namespaces: 5 | kubectl label namespace {{ .Release.Namespace }} {{ .Values.autocert.label }}=enabled 6 | 7 | 2. Check the namespaces where Autocert is enabled: 8 | kubectl get namespace -L {{ .Values.autocert.label }} 9 | 10 | 3. Get the PKI and Provisioner secrets running these commands: 11 | kubectl get -n {{ .Release.Namespace }} -o jsonpath='{.data.password}' secret/{{ .Release.Name }}-step-certificates-ca-password | base64 --decode 12 | kubectl get -n {{ .Release.Namespace }} -o jsonpath='{.data.password}' secret/{{ .Release.Name }}-step-certificates-provisioner-password | base64 --decode 13 | {{- if .Release.IsInstall }} 14 | 15 | 4. Get the CA URL and the root certificate fingerprint running this command: 16 | kubectl -n {{ .Release.Namespace }} logs job.batch/{{ .Release.Name }} 17 | 18 | 5. Delete the configuration job running this command: 19 | kubectl -n {{ .Release.Namespace }} delete job.batch/{{ .Release.Name }} 20 | {{- end }} 21 | -------------------------------------------------------------------------------- /autocert/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "autocert.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "autocert.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "autocert.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "autocert.labels" -}} 38 | helm.sh/chart: {{ include "autocert.chart" . }} 39 | app.kubernetes.io/name: {{ include "autocert.name" . }} 40 | app.kubernetes.io/instance: {{ .Release.Name }} 41 | {{- if .Chart.AppVersion }} 42 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 43 | {{- end }} 44 | app.kubernetes.io/managed-by: {{ .Release.Service }} 45 | {{- end -}} 46 | 47 | {{/* 48 | Create CA URL 49 | */}} 50 | {{- define "autocert.ca.url" -}} 51 | {{- if .Values.ca.url }} 52 | {{- .Values.ca.url -}} 53 | {{- else }} 54 | {{- printf "https://%s-step-certificates.%s.svc.%s" .Release.Name .Release.Namespace .Values.autocert.clusterDomain -}} 55 | {{- end }} 56 | {{- end -}} 57 | -------------------------------------------------------------------------------- /autocert/templates/autocert.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "autocert.fullname" . }} 5 | labels: 6 | {{- include "autocert.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | app.kubernetes.io/name: {{ include "autocert.name" . }} 12 | app.kubernetes.io/instance: {{ .Release.Name }} 13 | template: 14 | metadata: 15 | labels: 16 | app.kubernetes.io/name: {{ include "autocert.name" . }} 17 | app.kubernetes.io/instance: {{ .Release.Name }} 18 | spec: 19 | {{- if and .Release.IsInstall (index .Values "step-certificates" "enabled") }} 20 | initContainers: 21 | - name: {{ .Chart.Name }}-init 22 | image: busybox:latest 23 | imagePullPolicy: {{ .Values.autocert.image.pullPolicy }} 24 | command: ["sleep", "30"] 25 | {{- end }} 26 | containers: 27 | - name: {{ .Chart.Name }} 28 | image: "{{ .Values.autocert.image.repository }}:{{ .Values.autocert.image.tag | default .Chart.AppVersion }}" 29 | imagePullPolicy: {{ .Values.autocert.image.pullPolicy }} 30 | resources: 31 | {{- toYaml .Values.autocert.resources | nindent 10 }} 32 | securityContext: 33 | {{- toYaml .Values.autocert.securityContext | nindent 10 }} 34 | env: 35 | - name: PROVISIONER_NAME 36 | value: {{ .Values.ca.provisioner.name | default "admin" }} 37 | - name: NAMESPACE 38 | value: {{ .Release.Namespace }} 39 | volumeMounts: 40 | - name: config 41 | mountPath: /home/step/config 42 | readOnly: true 43 | - name: certs 44 | mountPath: /home/step/certs 45 | readOnly: true 46 | - name: autocert-password 47 | mountPath: /home/step/password 48 | readOnly: true 49 | - name: autocert-config 50 | mountPath: /home/step/autocert 51 | readOnly: true 52 | livenessProbe: 53 | initialDelaySeconds: 5 54 | httpGet: 55 | path: /healthz 56 | port: {{ .Values.service.targetPort }} 57 | scheme: HTTPS 58 | readinessProbe: 59 | initialDelaySeconds: 5 60 | httpGet: 61 | path: /healthz 62 | port: {{ .Values.service.targetPort }} 63 | scheme: HTTPS 64 | volumes: 65 | - name: config 66 | configMap: 67 | name: {{ .Release.Name }}-step-certificates-config 68 | - name: certs 69 | configMap: 70 | name: {{ .Release.Name }}-step-certificates-certs 71 | - name: autocert-password 72 | secret: 73 | secretName: {{ .Release.Name }}-step-certificates-provisioner-password 74 | - name: autocert-config 75 | configMap: 76 | name: {{ .Release.Name }}-autocert-config 77 | {{- with .Values.autocert.nodeSelector }} 78 | nodeSelector: 79 | {{- toYaml . | nindent 8 }} 80 | {{- end }} 81 | {{- with .Values.autocert.affinity }} 82 | affinity: 83 | {{- toYaml . | nindent 8 }} 84 | {{- end }} 85 | {{- with .Values.autocert.tolerations }} 86 | tolerations: 87 | {{- toYaml . | nindent 8 }} 88 | {{- end }} 89 | securityContext: 90 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 91 | -------------------------------------------------------------------------------- /autocert/templates/configmaps.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: {{ .Release.Name }}-autocert-config 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | {{- include "autocert.labels" . | nindent 4 }} 8 | data: 9 | config.yaml: | 10 | address: :{{ .Values.service.targetPort }} 11 | service: {{ include "autocert.fullname" . }} 12 | logFormat: {{ .Values.autocert.logFormat }} 13 | caUrl: {{ include "autocert.ca.url" . }} 14 | certLifetime: {{ .Values.autocert.certLifetime }} 15 | clusterDomain: {{ .Values.autocert.clusterDomain }} 16 | restrictCertificatesToNamespace: {{ .Values.autocert.restrictCertificatesToNamespace }} 17 | rootCAPath: /home/step/certs/root_ca.crt 18 | provisionerPasswordPath: /home/step/password/password 19 | renewer: 20 | name: autocert-renewer 21 | image: "{{ .Values.renewer.image.repository }}:{{ .Values.renewer.image.tag | default .Chart.AppVersion }}" 22 | imagePullPolicy: {{ .Values.renewer.image.pullPolicy }} 23 | resources: 24 | {{- toYaml .Values.renewer.resources | nindent 8 }} 25 | volumeMounts: 26 | - name: certs 27 | mountPath: /var/run/autocert.step.sm 28 | bootstrapper: 29 | name: autocert-bootstrapper 30 | image: "{{ .Values.bootstrapper.image.repository }}:{{ .Values.bootstrapper.image.tag | default .Chart.AppVersion }}" 31 | imagePullPolicy: {{ .Values.bootstrapper.image.pullPolicy }} 32 | resources: 33 | {{- toYaml .Values.bootstrapper.resources | nindent 8 }} 34 | volumeMounts: 35 | - name: certs 36 | mountPath: /var/run/autocert.step.sm 37 | certsVolume: 38 | name: certs 39 | emptyDir: {} 40 | --- 41 | # Allow configuration of autocert without installing step-certificates. 42 | {{- if not (index .Values "step-certificates" "enabled") }} 43 | apiVersion: v1 44 | kind: ConfigMap 45 | metadata: 46 | name: {{ .Release.Name }}-step-certificates-certs 47 | namespace: {{ .Release.Namespace }} 48 | labels: 49 | {{- include "autocert.labels" . | nindent 4 }} 50 | data: 51 | {{- toYaml .Values.ca.certs | nindent 2 }} 52 | --- 53 | apiVersion: v1 54 | kind: ConfigMap 55 | metadata: 56 | name: {{ .Release.Name }}-step-certificates-config 57 | namespace: {{ .Release.Namespace }} 58 | labels: 59 | {{- include "autocert.labels" . | nindent 4 }} 60 | data: 61 | {{- toYaml .Values.ca.config | nindent 2 }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /autocert/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: {{ include "autocert.fullname" . }} 5 | labels: 6 | {{- include "autocert.labels" . | nindent 4 }} 7 | rules: 8 | - apiGroups: [""] 9 | resources: ["secrets"] 10 | verbs: ["create", "delete"] 11 | {{- if not (index .Values "step-certificates" "enabled") }} 12 | - apiGroups: ["admissionregistration.k8s.io"] 13 | resources: ["mutatingwebhookconfigurations"] 14 | verbs: ["get", "create", "update", "patch"] 15 | {{- end }} 16 | --- 17 | apiVersion: rbac.authorization.k8s.io/v1 18 | kind: ClusterRoleBinding 19 | metadata: 20 | name: {{ include "autocert.fullname" . }} 21 | labels: 22 | {{- include "autocert.labels" . | nindent 4 }} 23 | roleRef: 24 | apiGroup: rbac.authorization.k8s.io 25 | kind: ClusterRole 26 | name: {{ include "autocert.fullname" . }} 27 | subjects: 28 | - kind: ServiceAccount 29 | name: default 30 | namespace: {{ .Release.Namespace }} 31 | -------------------------------------------------------------------------------- /autocert/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | # Allow configuration of autocert without installing step-certificates. 2 | {{- if not (index .Values "step-certificates" "enabled") }} 3 | apiVersion: v1 4 | kind: Secret 5 | type: smallstep.com/provisioner-password 6 | metadata: 7 | name: {{ .Release.Name }}-step-certificates-provisioner-password 8 | namespace: {{ .Release.Namespace }} 9 | labels: 10 | {{- include "autocert.labels" . | nindent 4 }} 11 | data: 12 | password: {{ .Values.ca.provisioner.password | b64enc }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /autocert/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "autocert.fullname" . }} 5 | labels: 6 | {{- include "autocert.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: {{ .Values.service.targetPort }} 12 | protocol: TCP 13 | name: https 14 | selector: 15 | app.kubernetes.io/name: {{ include "autocert.name" . }} 16 | app.kubernetes.io/instance: {{ .Release.Name }} 17 | -------------------------------------------------------------------------------- /autocert/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "autocert.fullname" . }}-test-connection" 5 | labels: 6 | app.kubernetes.io/name: {{ include "autocert.name" . }} 7 | helm.sh/chart: {{ include "autocert.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | annotations: 11 | "helm.sh/hook": test-success 12 | spec: 13 | containers: 14 | - name: wget 15 | image: busybox 16 | command: ['wget'] 17 | args: ['{{ include "autocert.fullname" . }}:{{ .Values.service.port }}'] 18 | restartPolicy: Never 19 | -------------------------------------------------------------------------------- /autocert/templates/webhook.yaml: -------------------------------------------------------------------------------- 1 | {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion -}} 2 | apiVersion: admissionregistration.k8s.io/v1 3 | {{- else -}} 4 | apiVersion: admissionregistration.k8s.io/v1beta1 5 | {{- end }} 6 | kind: MutatingWebhookConfiguration 7 | metadata: 8 | name: {{ .Release.Name }}-autocert-webhook-config 9 | labels: 10 | {{- include "autocert.labels" . | nindent 4 }} 11 | webhooks: 12 | - name: {{ .Values.autocert.label }} 13 | clientConfig: 14 | {{- if not (index .Values "step-certificates" "enabled") }} 15 | caBundle: {{ index .Values.ca.certs "root_ca.crt" | b64enc }} 16 | {{- end }} 17 | service: 18 | name: {{ include "autocert.fullname" .}} 19 | namespace: {{ .Release.Namespace }} 20 | path: "/mutate" 21 | {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }} 22 | sideEffects: None 23 | admissionReviewVersions: ["v1beta1"] 24 | {{- end }} 25 | rules: 26 | - operations: ["CREATE"] 27 | apiGroups: [""] 28 | apiVersions: ["v1"] 29 | resources: ["pods"] 30 | failurePolicy: Ignore 31 | namespaceSelector: 32 | matchLabels: 33 | {{ .Values.autocert.label }}: enabled 34 | -------------------------------------------------------------------------------- /autocert/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for autocert. 2 | # This is a YAML-formatted file. 3 | 4 | # replicaCount is the number of replicas of autocert. 5 | replicaCount: 1 6 | 7 | # nameOverride overrides the name of the chart. 8 | nameOverride: "" 9 | # fullnameOverride overrides the full name of the chart. 10 | fullnameOverride: "" 11 | 12 | # service contains configuration for the kubernetes service. 13 | service: 14 | type: ClusterIP 15 | port: 443 16 | targetPort: 4443 17 | 18 | # Security Context for the pod 19 | podSecurityContext: {} 20 | # fsGroup: 2000 21 | 22 | # autocert contains the configuration for autocert. 23 | autocert: 24 | # image contains the docker image for step-certificates. 25 | image: 26 | repository: cr.step.sm/smallstep/autocert-controller 27 | pullPolicy: IfNotPresent 28 | # Overrides the image tag whose default is the chart appVersion. 29 | tag: "" 30 | # label is the label used used to enable autocert in a namespace. 31 | # This value is rightnow hardcoded in autocert and it should not be changed. 32 | label: autocert.step.sm 33 | # logFormat is the format for autocert logs. Options are json or text. 34 | logFormat: json 35 | # restrictCertificatesToNamespace defines if certificate names are restricted to the namespace 36 | restrictCertificatesToNamespace: false 37 | # clusterDomain is the domain name for your kubernetes cluster. 38 | clusterDomain: cluster.local 39 | # certLifetime is the default certificate life time. 40 | certLifetime: 24h 41 | # resources contains the CPU/memory resource requests/limits. 42 | resources: {requests: {cpu: 100m, memory: 20Mi}} 43 | # nodeSelector contains the node labels for pod assignment. 44 | nodeSelector: {} 45 | # tolerations contains the toleration labels for pod assignment. 46 | tolerations: [] 47 | # affinity contains the affinity settings for pod assignment. 48 | affinity: {} 49 | # security context for container 50 | securityContext: 51 | runAsUser: 1000 52 | allowPrivilegeEscalation: false 53 | 54 | # bootstrapper contains the autocert-bootstrapper image and configuration. 55 | bootstrapper: 56 | image: 57 | repository: cr.step.sm/smallstep/autocert-bootstrapper 58 | pullPolicy: IfNotPresent 59 | # Overrides the image tag whose default is the chart appVersion. 60 | tag: "" 61 | resources: {requests: {cpu: 10m, memory: 20Mi}} 62 | 63 | # renewer contains the autocert-renewer image and configuration. 64 | renewer: 65 | image: 66 | repository: cr.step.sm/smallstep/autocert-renewer 67 | pullPolicy: IfNotPresent 68 | # Overrides the image tag whose default is the chart appVersion. 69 | tag: "" 70 | resources: {requests: {cpu: 10m, memory: 20Mi}} 71 | 72 | # Enables autocert in the step-certificates subchart. 73 | step-certificates: 74 | enabled: true 75 | autocert: 76 | enabled: true 77 | 78 | # These values allow configuration of an existing step-certificates deployment 79 | # with autocert. 80 | # 81 | # Future version of the autocert helm-chart will not install step-certificates 82 | # by default and it will require these values. 83 | ca: 84 | # url is the step-certificates url to use. 85 | url: "" 86 | # provisioner is the provisioner name and the plaintext password that autocert 87 | # will use. 88 | provisioner: 89 | name: "" 90 | password: "" 91 | # certs is the configmap in yaml that should contain the CA root certificate. 92 | certs: 93 | root_ca.crt: |- 94 | -----BEGIN CERTIFICATE----- 95 | ... 96 | -----END CERTIFICATE----- 97 | # config is the configmap in yaml to use. This is currently optional only. 98 | config: 99 | defaults.json: |- 100 | {} 101 | -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ $# -ne 1 ]; then 6 | echo "Usage: $0 " 7 | echo " $0 step-certificates" 8 | exit 1 9 | fi 10 | 11 | function require() { 12 | for cmd in $@; 13 | do 14 | if ! command -v $cmd &> /dev/null 15 | then 16 | echo "$cmd is required" 17 | exit 1 18 | fi 19 | done 20 | } 21 | 22 | require yq git helm 23 | 24 | # Grab version from chart 25 | version=$(yq .version ./$1/Chart.yaml) 26 | 27 | # Build package 28 | helm package ./$1 29 | 30 | # Push it to gh-pages branch rebuilding the index 31 | git checkout gh-pages 32 | git pull origin gh-pages 33 | git add "$1-$version.tgz" 34 | mkdir new-charts 35 | cp "$1-$version.tgz" new-charts/ 36 | helm repo index --merge index.yaml --url https://smallstep.github.io/helm-charts/ new-charts 37 | cp new-charts/index.yaml . 38 | rm -rf new-charts 39 | git diff 40 | echo "Press enter to continue." 41 | read 42 | git commit -a -m "Add $1-$version.tgz" 43 | git push origin gh-pages 44 | git checkout master -------------------------------------------------------------------------------- /docker/step-ca-bootstrap/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM smallstep/step-cli:0.22.0 2 | 3 | ENV CA_NAME="Step CA" 4 | ENV CA_DNS="127.0.0.1" 5 | ENV CA_ADDRESS=":9000" 6 | ENV CA_DEFAULT_PROVISIONER="admin" 7 | ENV CA_URL="https://127.0.0.1:9000" 8 | 9 | ENV KUBE_LATEST_VERSION="v1.30.0" 10 | 11 | USER root 12 | RUN apk --update add expect && \ 13 | apkArch="$(apk --print-arch)"; \ 14 | case "$apkArch" in \ 15 | armhf) ARCH='arm' ;; \ 16 | armv7) ARCH='arm' ;; \ 17 | aarch64) ARCH='arm64' ;; \ 18 | x86_64) ARCH='amd64' ;; \ 19 | x86) ARCH='386' ;; \ 20 | *) echo >&2 "error: unsupported architecture: $apkArch"; exit 1 ;; \ 21 | esac && \ 22 | curl -L https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/${ARCH}/kubectl -o /usr/local/bin/kubectl && \ 23 | chmod +x /usr/local/bin/kubectl 24 | 25 | COPY entrypoint.sh /home/step/ 26 | RUN chmod +x /home/step/entrypoint.sh 27 | CMD ["/home/step/entrypoint.sh"] 28 | -------------------------------------------------------------------------------- /docker/step-ca-bootstrap/Makefile: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | all: artifacts 4 | 5 | # Version flags 6 | VERSION ?= $(shell [ -d .git ] && git describe --tags --always --dirty="-dev") 7 | VERSION := $(shell echo $(VERSION) | sed 's/^v//') 8 | NOT_RC := $(shell echo $(VERSION) | grep -v -e -rc) 9 | 10 | # If TRAVIS_TAG is set then we know this ref has been tagged. 11 | ifdef TRAVIS_TAG 12 | ifeq ($(NOT_RC),) 13 | PUSHTYPE=release-candidate 14 | else 15 | PUSHTYPE=release 16 | endif 17 | else 18 | PUSHTYPE=master 19 | endif 20 | 21 | ######################################### 22 | # Building Docker Image 23 | ######################################### 24 | 25 | DOCKER_BUILD=$Q docker build -t smallstep/$(1):latest -f $(2) . 26 | 27 | docker: Dockerfile 28 | $(call DOCKER_BUILD,step-ca-bootstrap,Dockerfile) 29 | 30 | .PHONY: docker 31 | 32 | ################################################# 33 | # Releasing Docker Images 34 | ################################################# 35 | 36 | DOCKER_TAG=docker tag smallstep/$(1):latest smallstep/$(1):$(2) 37 | DOCKER_PUSH=docker push smallstep/$(1):$(2) 38 | 39 | docker-tag: 40 | $(call DOCKER_TAG,step-ca-bootstrap,$(VERSION)) 41 | 42 | docker-push-tag: docker-tag 43 | $(call DOCKER_PUSH,step-ca-bootstrap,$(VERSION)) 44 | 45 | docker-push-tag-latest: 46 | $(call DOCKER_PUSH,step-ca-bootstrap,latest) 47 | 48 | # Rely on DOCKER_USERNAME and DOCKER_PASSWORD being set inside the CI or 49 | # equivalent environment 50 | docker-login: 51 | $Q echo "$(DOCKER_PASSWORD)" | docker login -u="$(DOCKER_USERNAME)" --password-stdin 52 | 53 | .PHONY: docker-login docker-tag docker-push-tag docker-push-tag-latest 54 | 55 | ################################################# 56 | # Targets for pushing the docker images 57 | ################################################# 58 | 59 | # For all builds we build the docker container 60 | docker-master: docker 61 | 62 | # For all builds with a release candidate tag 63 | docker-release-candidate: docker-master docker-login docker-push-tag 64 | 65 | # For all builds with a release tag 66 | docker-release: docker-release-candidate docker-push-tag-latest 67 | 68 | .PHONY: docker-master docker-release-candidate docker-release 69 | 70 | ################################################# 71 | # Targets for creating step artifacts 72 | ################################################# 73 | 74 | # This command is called by travis directly *after* a successful build 75 | artifacts: docker-$(PUSHTYPE) 76 | 77 | .PHONY: artifacts 78 | -------------------------------------------------------------------------------- /docker/step-ca-bootstrap/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Welcome to Step Certificates configuration." 4 | 5 | STEPPATH=/home/step 6 | 7 | # assert_variable exists if the given variable is not set. 8 | function assert_variable () { 9 | if [ -z "$1" ]; 10 | then 11 | echo "Error: variable $1 has not been set." 12 | exit 1 13 | fi 14 | } 15 | 16 | # check required variables 17 | assert_variable "$NAMESPACE" 18 | assert_variable "$PREFIX" 19 | assert_variable "$LABELS" 20 | assert_variable "$CA_URL" 21 | assert_variable "$CA_NAME" 22 | assert_variable "$CA_DNS" 23 | assert_variable "$CA_ADDRESS" 24 | assert_variable "$CA_PROVISIONER" 25 | 26 | # check autocert required variables 27 | if [ "$AUTOCERT" == "true" ]; then 28 | assert_variable "$AUTOCERT_SERVICE" 29 | assert_variable "$AUTOCERT_LABEL" 30 | fi 31 | 32 | # generate password if necessary 33 | CA_PASSWORD=${CA_PASSWORD:-$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')} 34 | CA_PROVISIONER_PASSWORD=${CA_PROVISIONER_PASSWORD:-$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')} 35 | 36 | echo -e "\e[1mChecking cluster permissions...\e[0m" 37 | 38 | function permission_error () { 39 | # TODO: Figure out the actual service account instead of assuming default. 40 | echo 41 | echo -e "\033[0;31mPERMISSION ERROR\033[0m" 42 | echo "Set permissions by running the following command, then try again:" 43 | echo -e "\e[1m" 44 | echo " kubectl create clusterrolebinding autocert-init-binding \\" 45 | echo " --clusterrole cluster-admin \\" 46 | echo " --user \"system:serviceaccount:default:default\"" 47 | echo -e "\e[0m" 48 | echo "Once setup is complete you can remove this binding by running:" 49 | echo -e "\e[1m" 50 | echo " kubectl delete clusterrolebinding autocert-init-binding" 51 | echo -e "\e[0m" 52 | 53 | exit 1 54 | } 55 | 56 | # Use the service account context 57 | kubectl config set-cluster cfc --server=https://kubernetes.default --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt 58 | kubectl config set-context cfc --cluster=cfc 59 | kubectl config set-credentials user --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) 60 | kubectl config set-context cfc --user=user 61 | kubectl config use-context cfc 62 | 63 | echo -n "Checking for permission to create configmaps in $NAMESPACE namespace: " 64 | kubectl auth can-i create configmaps --namespace $NAMESPACE 65 | if [ $? -ne 0 ]; then 66 | permission_error "create configmaps" 67 | fi 68 | 69 | echo -n "Checking for permission to create secrets in $NAMESPACE namespace: " 70 | kubectl auth can-i create secrets --namespace $NAMESPACE 71 | if [ $? -ne 0 ]; then 72 | permission_error "create secrets" 73 | fi 74 | 75 | if [ "$AUTOCERT" == "true" ]; then 76 | echo -n "Checking for permission to create mutatingwebhookconfiguration in $NAMESPACE namespace: " 77 | kubectl auth can-i create mutatingwebhookconfiguration --namespace $NAMESPACE 78 | if [ $? -ne 0 ]; then 79 | permission_error "create mutatingwebhookconfiguration" 80 | fi 81 | fi 82 | 83 | # Setting this here on purpose, after the above section which explicitly checks 84 | # for and handles exit errors. 85 | set -e 86 | 87 | TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX) 88 | TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX) 89 | 90 | echo $CA_PASSWORD > $TMP_CA_PASSWORD 91 | echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD 92 | 93 | step ca init \ 94 | --name "$CA_NAME" \ 95 | --dns "$CA_DNS" \ 96 | --address "$CA_ADDRESS" \ 97 | --password-file "$TMP_CA_PASSWORD" \ 98 | --provisioner "$CA_DEFAULT_PROVISIONER" \ 99 | --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" \ 100 | --with-ca-url "$CA_URL" 101 | 102 | rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD 103 | 104 | echo 105 | echo -e "\e[1mCreating configmaps and secrets in $NAMESPACE namespace ...\e[0m" 106 | 107 | function kbreplace() { 108 | kubectl $@ -o yaml --dry-run=client | kubectl replace -f - 109 | } 110 | 111 | # Replace secrets created on helm install 112 | # It allows to properly remove them on help delete 113 | kbreplace -n $NAMESPACE create configmap $PREFIX-config --from-file $(step path)/config 114 | kbreplace -n $NAMESPACE create configmap $PREFIX-certs --from-file $(step path)/certs 115 | kbreplace -n $NAMESPACE create configmap $PREFIX-secrets --from-file $(step path)/secrets 116 | 117 | kbreplace -n $NAMESPACE create secret generic $PREFIX-ca-password --from-literal "password=${CA_PASSWORD}" 118 | kbreplace -n $NAMESPACE create secret generic $PREFIX-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}" 119 | 120 | # Label all configmaps and secrets 121 | kubectl -n $NAMESPACE label configmap $PREFIX-config $LABELS 122 | kubectl -n $NAMESPACE label configmap $PREFIX-certs $LABELS 123 | kubectl -n $NAMESPACE label configmap $PREFIX-secrets $LABELS 124 | kubectl -n $NAMESPACE label secret $PREFIX-ca-password $LABELS 125 | kubectl -n $NAMESPACE label secret $PREFIX-provisioner-password $LABELS 126 | 127 | # Replace webhook if necessary 128 | if [ "$AUTOCERT" == "true" ]; then 129 | CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n') 130 | cat <=1.16-0" .Capabilities.KubeVersion.GitVersion -}} 132 | apiVersion: admissionregistration.k8s.io/v1 133 | {{- else -}} 134 | apiVersion: admissionregistration.k8s.io/v1beta1 135 | {{- end }} 136 | kind: MutatingWebhookConfiguration 137 | metadata: 138 | name: $PREFIX-webhook-config 139 | webhooks: 140 | - name: $AUTOCERT_LABEL 141 | clientConfig: 142 | service: 143 | name: $AUTOCERT_SERVICE 144 | namespace: $NAMESPACE 145 | path: "/mutate" 146 | caBundle: $CA_BUNDLE 147 | {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }} 148 | sideEffects: NoneOnDryRun 149 | admissionReviewVersions: ["v1beta1"] 150 | {{- end }} 151 | rules: 152 | - operations: ["CREATE"] 153 | apiGroups: [""] 154 | apiVersions: ["v1"] 155 | resources: ["pods"] 156 | failurePolicy: Ignore 157 | namespaceSelector: 158 | matchLabels: 159 | $AUTOCERT_LABEL: enabled 160 | EOF 161 | kubectl -n $NAMESPACE label mutatingwebhookconfiguration $PREFIX-webhook-config $LABELS 162 | fi 163 | 164 | FINGERPRINT=$(step certificate fingerprint $(step path)/certs/root_ca.crt) 165 | 166 | echo 167 | echo -e "\e[1mStep Certificates installed!\e[0m" 168 | echo 169 | echo "CA URL: ${CA_URL}" 170 | echo "CA Fingerprint: ${FINGERPRINT}" 171 | echo -------------------------------------------------------------------------------- /step-certificates/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /step-certificates/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: step-certificates 3 | version: 1.28.3 4 | appVersion: 0.28.3 5 | description: An online certificate authority and related tools for secure automated certificate management, so you can use TLS everywhere. 6 | keywords: 7 | - acme 8 | - authority 9 | - ca 10 | - certificate 11 | - certificates 12 | - certificate-authority 13 | - kubernetes 14 | - pki 15 | - security 16 | - security-tools 17 | - smallstep 18 | - ssh 19 | - step 20 | - step-ca 21 | - tls 22 | - x509 23 | home: https://smallstep.com 24 | icon: https://raw.githubusercontent.com/smallstep/certificates/master/icon.png 25 | sources: 26 | - https://github.com/smallstep/certificates 27 | maintainers: 28 | - name: Mariano Cano 29 | email: mariano@smallstep.com 30 | -------------------------------------------------------------------------------- /step-certificates/README.md: -------------------------------------------------------------------------------- 1 | # Step Certificates 2 | 3 | An online certificate authority and related tools for secure automated 4 | certificate management, so you can use TLS everywhere. 5 | 6 | To learn more, visit . 7 | 8 | ## TL;DR 9 | 10 | ```console 11 | helm repo add smallstep https://smallstep.github.io/helm-charts/ 12 | step ca init --helm > values.yaml 13 | echo "password" | base64 > password.txt 14 | helm install -f values.yaml \ 15 | --set inject.secrets.ca_password=$(cat password.txt) \ 16 | --set inject.secrets.provisioner_password=$(cat password.txt) \ 17 | --set service.targetPort=9000 \ 18 | step-certificates smallstep/step-certificates 19 | ``` 20 | 21 | ## Prerequisites 22 | 23 | - Kubernetes 1.10+ 24 | 25 | ## Installing the Chart 26 | 27 | Before installing the chart, we need to generate the 28 | [configuration](#configuration) that we will use. To do this, we will use 29 | [`step`](https://github.com/smallstep/cli): 30 | 31 | ```console 32 | step ca init --helm > values.yaml 33 | echo "password" | base64 > password.txt 34 | ``` 35 | 36 | Now we can install the chart with release name `step-certificates` using the 37 | generated configuration and password: 38 | 39 | ```console 40 | helm install -f values.yaml \ 41 | --set inject.secrets.ca_password=$(cat password.txt) \ 42 | --set inject.secrets.provisioner_password=$(cat password.txt) \ 43 | step-certificates smallstep/step-certificates 44 | ``` 45 | 46 | The command deploys Step certificates on the Kubernetes cluster in the default 47 | configuration. The [configuration](#configuration) section lists the parameters 48 | that can be configured during installation. 49 | 50 | The chart also has an option to generate the configuration automatically. This 51 | option is deprecated, and it will be removed in a future release. To install the 52 | chart using this option, we can run: 53 | 54 | ```console 55 | helm install my-release smallstep/step-certificates 56 | ``` 57 | 58 | > **Tip**: List all releases using `helm list` 59 | 60 | ## Uninstalling the Chart 61 | 62 | To uninstall the `step-certificates` release: 63 | 64 | ```console 65 | helm uninstall step-certificates 66 | ``` 67 | 68 | The command removes all the Kubernetes components associated with the chart and 69 | deletes the release. 70 | 71 | ## Linked CA 72 | 73 | Linked CA is an instance of `step-ca` that you run that connects to your 74 | [Certificate Manager](https://smallstep.com/certificate-manager/)) account for 75 | reporting, alerting, revocation, and other managed services. 76 | 77 | When you create a Linked CA authority, you will get a token that you will use to 78 | connect your instance to it. 79 | 80 | There're two ways to configure the token. You can define the value for `linkedca.token`: 81 | 82 | ```console 83 | helm install --set linkedca.token=xxx \ 84 | step-certificates smallstep/step-certificates 85 | ``` 86 | 87 | Or set the reference to another secret managed with your preferred 88 | infrastructure automation tool. 89 | 90 | ```console 91 | helm install \ 92 | --set linkedca.secretKeyRef.name=my-secret-name \ 93 | --set linkedca.secretKeyRef.key=my-key-name \ 94 | step-certificates smallstep/step-certificates 95 | ``` 96 | 97 | ## Configuration 98 | 99 | The easiest way to configure step-certificates is to use [step](https://github.com/smallstep/cli). 100 | 101 | Starting with `step` v0.17+ and `step-certificates` Chart v1.17+, you can use 102 | `step ca init` to create a values.yaml that you can use to configure your CA: 103 | 104 | ```console 105 | $ step ca init --helm > values.yaml 106 | ✔ Deployment Type: Standalone 107 | What would you like to name your new PKI? 108 | ✔ (e.g. Smallstep): Smallstep 109 | What DNS names or IP addresses would you like to add to your new CA? 110 | ✔ (e.g. ca.smallstep.com[,1.1.1.1,etc.]): step-certificates.default.svc.cluster.local 111 | What IP and port will your new CA bind to (it should match service.targetPort)? 112 | ✔ (e.g. :443 or 127.0.0.1:443): :9000 113 | What would you like to name the CA's first provisioner? 114 | ✔ (e.g. you@smallstep.com): me@example.org 115 | Choose a password for your CA keys and first provisioner. 116 | ✔ [leave empty and we'll generate one]: 117 | 118 | Generating root certificate... done! 119 | Generating intermediate certificate... done! 120 | ``` 121 | 122 | By default, the values.yaml won't contain the password used to encrypt the keys, 123 | nor the password of the default provisioner, so we have to pass it as values 124 | using the base64 encoding. And the port where the CA binds to, in the example, 125 | `:9000` must be set as `service.targetPort=9000`. 126 | 127 | ```console 128 | echo "password" | base64 > password.txt 129 | helm install -f values.yaml \ 130 | --set inject.secrets.ca_password=$(cat password.txt) \ 131 | --set inject.secrets.provisioner_password=$(cat password.txt) \ 132 | --set service.targetPort=9000 \ 133 | step-certificates smallstep/step-certificates 134 | ``` 135 | 136 | With this method, the automatic bootstrap of the PKI is deprecated and it will 137 | be removed in future releases. 138 | 139 | ### Advanced configuration 140 | 141 | In some circumstainces it is not an option to use Helm install or to inject secrets at the command line. For example when using GitOps / ArgoCD. 142 | Secrets and configurations can be provided before the helm chart is deployed by defining `existingSecrets` in the values file: 143 | 144 | ``` 145 | existingSecrets: 146 | enabled: true 147 | ca: true 148 | issuer: true 149 | certsAsSecret: true 150 | configAsSecret: true 151 | sshHostCa: true 152 | sshUserCa: true 153 | 154 | bootstrap: 155 | secrets: false 156 | enabled: false 157 | configmaps: false 158 | 159 | inject: 160 | enabled: false 161 | ``` 162 | 163 | Enabling `existingSecrets` can't be combined with enabling `bootstrap` nor `inject` elements from helm chart. 164 | Therefore the bootstrap and inject are disabled in the example above. 165 | 166 | Note, the MutatingWebhookConfiguration created by autocert is not patched with CA bundle as the bootstrap init-container is not started when `existingSecrets` are enabled. 167 | 168 | The following naming conventions are used for secret names: 169 | 170 | secret name: `{{ include "step-certificates.fullname" . }}-secrets` 171 | which contains the following data: 172 | 173 | - `intermediate_ca_key` 174 | - The encrypted X.509 intermediate certificate private key. 175 | - `root_ca_key` (optional) 176 | - The encrypted X.509 root certificate private key. 177 | - `ssh_host_ca_key` (optional) 178 | - The encrypted private key used to sign SSH host certificates. 179 | - `ssh_user_ca_key` (optional) 180 | - The encrypted private key used to sign SSH user certificates. 181 | - `certificate_issuer_key` (optional) 182 | - The encrypted private key used to sign tokens used on RA mode. This is 183 | required if an X5C provisioner is used to talk with the CA, but it can also 184 | be used with JWK if the encrypted key is not distributed by the CA. 185 | 186 | When `existingSecrets.certsAsSecret` is `true` 187 | secret name: `{{ include "step-certificates.fullname" . }}-certs` 188 | which contains the following data: 189 | 190 | - `root_ca.crt` 191 | - The root CA certificate. 192 | - `intermediate_ca.crt` 193 | - The intermediate CA certificate (optional). 194 | - `ssh_host_ca_key.pub:` 195 | - The SSH host CA public key (optional). 196 | - `ssh_user_ca_key.pub:` 197 | - The SSH user CA public key (optional). 198 | 199 | When `existingSecrets.configAsSecret` is `true` 200 | secret name: `{{ include "step-certificates.fullname" . }}-config` 201 | which contains the following data: 202 | 203 | - `ca.json` 204 | - The configuration file used by `step-ca`. 205 | - `default.json` 206 | - The configuration file used by `step` with the default flags. 207 | 208 | When `existingSecrets.ca` is `true` 209 | secret name: `{{ include "step-certificates.fullname" . }}-ca-password` 210 | secret type: `smallstep.com/ca-password` 211 | which contains the following data: 212 | 213 | - `password` 214 | - The password used to decrypt the X.509 intermediate certificate private key. 215 | 216 | When `existingSecrets.sshHostCa` is `true` 217 | secret name: `{{ include "step-certificates.fullname" . }}-ssh-host-ca-password` 218 | secret type: `smallstep.com/ssh-host-ca-password` 219 | which contains the following data: 220 | 221 | - `password` 222 | - The password used to decrypt the private key used to sign SSH host certificates. 223 | 224 | When `existingSecrets.sshUserCa` is `true` 225 | secret name: `{{ include "step-certificates.fullname" . }}-ssh-user-ca-password` 226 | secret type: `smallstep.com/ssh-user-ca-password` 227 | which contains the following data: 228 | 229 | - `password` 230 | - The password used to decrypt the private key used to sign SSH user certificates. 231 | 232 | When `existingSecrets.issuer` is `true` 233 | secret name: `{{ include "step-certificates.fullname" . }}--certificate-issuer-password` 234 | secret type: `smallstep.com/certificate-issuer-password` 235 | which contains the following data: 236 | 237 | - `password` 238 | - The password used to decrypt the private key used to sign RA tokens. 239 | 240 | Further more the secret name `{{ include "step-certificates.fullname" . }}-provisioner-password` is used for the password used to encrypt JWK provisioner. 241 | 242 | ### Configuration parameters 243 | 244 | The following table lists the configurable parameters of the Step certificates 245 | chart and their default values. 246 | 247 | | Parameter | Description | Default | 248 | | ----------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------- | 249 | | `command` | The command entrypoint array | `[]` | 250 | | `args` | Arguments to the entrypoint | `[]` | 251 | | `workingDir` | The container working directory | `"/home/step"` | 252 | | `ca.name` | Name for you CA | `Step Certificates` | 253 | | `ca.address` | TCP address where Step CA runs | `:9000` | 254 | | `ca.dns` | DNS of Step CA, if empty it will be inferred | `""` | 255 | | `ca.url` | URL of Step CA, if empty it will be inferred | `""` | 256 | | `ca.password` | Password for the CA keys, if empty it will be automatically generated | `""` | 257 | | `ca.provisioner.name` | Name for the default provisioner | `admin` | 258 | | `ca.provisioner.password` | Password for the default provisioner, if empty it will be automatically generated | `""` | 259 | | `ca.db.enabled` | If true, step certificates will be configured with a database | `true` | 260 | | `ca.db.persistent` | If true a persistent volume will be used to store the db | `true` | 261 | | `ca.db.accessModes` | Persistent volume access mode | `["ReadWriteOnce"]` | 262 | | `ca.db.size` | Persistent volume size | `10Gi` | 263 | | `ca.db.existingClaim` | Persistent volume existing claim name. If defined, PVC must be created manually before volume will be bound | `""` | 264 | | `ca.kms.type` | Key management system to use. | `""` | 265 | | `ca.env` | Environment variables to set in `step-certificates` container. | `[]` | 266 | | `ca.bootstrap.postInitHook` | Extra script snippet to run after `step ca init` has completed. | `""` | 267 | | `ca.init.containerSecurityContext` | Set SecurityContext for the STEP CA init container | See [values.yaml](./values.yaml) | 268 | | `ca.containerSecurityContext` | Set SecurityContext for the STEP CA container | See [values.yaml](./values.yaml) | 269 | | `ca.ssh.enabled` | If true, step certificates will be configured with ssh support enabled | `false` | 270 | | `linkedca.token` | The token used to configure step-ca using the linkedca mode. | `""` | 271 | | `linkedca.secretKeyRef.name` | The secret name where the linkedca token can be found. | `""` | 272 | | `linkedca.secretKeyRef.key` | The secret key where the linkedca token can be found. | `""` | 273 | | `service.type` | Service type | `ClusterIP` | 274 | | `service.port` | Incoming port to access Step CA | `443` | 275 | | `service.nodePort` | Incoming port to access Step CA | `""` | 276 | | `service.targetPort` | Internal port where Step CA runs | `9000` | 277 | | `service.annotations` | Service annotations (YAML) | `{}` | 278 | | `service.externalIPs` | Service externalIPs | `[]` | 279 | | `replicaCount` | Number of Step CA replicas. Only one replica is currently supported. | `1` | 280 | | `image.repository` | Repository of the Step CA image | `cr.step.sm/smallstep/step-ca` | 281 | | `image.initContainerRepository` | Repository of the Step CA Init Container image. | `busybox:latest` | 282 | | `image.tag` | Tag of the Step CA image | `latest` | 283 | | `image.pullPolicy` | Step CA image pull policy | `IfNotPresent` | 284 | | `image.imagePullSecrets` | Name of image pull secrets to be used by kubernetes | `[]` | 285 | | `bootstrap.image.repository` | Repository of the Step CA bootstrap image | `cr.step.sm/smallstep/step-ca-bootstrap` | 286 | | `bootstrap.image.tag` | Tag of the Step CA bootstrap image | `latest` | 287 | | `bootstrap.image.pullPolicy` | Step CA bootstrap image pull policy | `IfNotPresent` | 288 | | `bootstrap.image.imagePullSecrets` | Name of image pull secrets to be used by kubernetes. | `[]` | 289 | | `bootstrap.enabled` | If false, it does not create the bootstrap job. | `true` | 290 | | `bootstrap.configmaps` | If false, it does not create the configmaps. | `true` | 291 | | `bootstrap.secrets` | If false, it does not create the secrets. | `true` | 292 | | `bootstrap.containerSecurityContext` | Set SecurityContext for the STEP CA bootstrap container. | See [values.yaml](./values.yaml) | 293 | | `extraVolumes` | Array to add extra volumes | `[]` | 294 | | `extraVolumeMounts` | Array to add extra mount | `[]` | 295 | | `extraInitContainers` | Array to add extra init containers. | `[]` | 296 | | `extraContainers` | Array to add extra containers. | `[]` | 297 | | `nameOverride` | Overrides the name of the chart | `""` | 298 | | `fullnameOverride` | Overrides the full name of the chart | `""` | 299 | | `ingress.enabled` | If true Step CA ingress will be created | `false` | 300 | | `ingress.annotations` | Step CA ingress annotations (YAML) | `{}` | 301 | | `ingress.hosts` | Step CA ingress hostNAMES (YAML) | `[]` | 302 | | `ingress.tls` | Step CA ingress TLS configuration (YAML) | `[]` | 303 | | `resources` | CPU/memory resource requests/limits (YAML) | `{}` | 304 | | `nodeSelector` | Node labels for pod assignment (YAML) | `{}` | 305 | | `tolerations` | Toleration labels for pod assignment (YAML) | `[]` | 306 | | `affinity` | Affinity settings for pod assignment (YAML) | `{}` | 307 | | `inject.enabled` | When true, configuration files and templates are injected into a Kubernetes objects and bootstrap capability is disabled. | `false` | 308 | | `inject.config.files.ca.json` | Yaml representation of the step-ca ca.json file. This map object is converted to its equivalent json representation before being injected into a configMap. See the step-ca [documentation](https://smallstep.com/docs/step-ca/configuration). | See [values.yaml](./values.yaml) | 309 | | `inject.config.files.default.json` | Yaml representation of the step-cli defaults.json file. This map object is converted to its equivalent json representation before being injected into a configMap. See the step-cli [documentation](https://smallstep.com/docs/step-cli/reference). | See [values.yaml](./values.yaml) | 310 | | `inject.config.templates.x509_leaf.tpl` | Example X509 Leaf Certifixate Template to inject into the configMap. | See [values.yaml](./values.yaml) | 311 | | `inject.config.templates.ssh.tpl` | Example SSH Certificate Template to inject into the configMap. | See [values.yaml](./values.yaml) | 312 | | `inject.certificates.intermediate_ca` | Plain text PEM representation of the intermediate CA certificate. | `""` | 313 | | `inject.certificates.root_ca` | Plain text PEM representation of the root CA certificate. | `""` | 314 | | `inject.certificates.ssh_host_ca` | Plain text representation of the ssh host CA public key. | `""` | 315 | | `inject.certificates.ssh_user_ca` | Plain text representation of the ssh user CA public key. | `""` | 316 | | `inject.secrets.ca_password` | Base64 encoded string. Password used to encrypt intermediate and ssh keys. | `Cg==` | 317 | | `inject.secrets.provisioner_password` | Base64 encoded string. Password used to encrypt JWK provisioner. | `Cg==` | 318 | | `inject.secrets.x509.intermediate_ca_key` | Plain text PEM representation of the intermediate CA private key. | `""` | 319 | | `inject.secrets.x509.root_ca_key` | Plain text PEM representation of the root CA private key. | `""` | 320 | | `inject.secrets.ssh.host_ca_key` | Plain text representation of the ssh host CA private key. | `""` | 321 | | `inject.secrets.ssh.user_ca_key` | Plain text representation of the ssh user CA private key. | `""` | 322 | | `existingSecrets.enabled` | Use secrets and configurations from existing secrets created outside of this chart. | `false` | 323 | | `existingSecrets.ca` | When `true`use existing secret for the ca-password. | `false` | 324 | | `existingSecrets.issuer` | When `true`use existing secret for the issuer. | `false` | 325 | | `existingSecrets.sshHostCa` | When `true`use existing secret for the ssh host CA public key. | `false` | 326 | | `existingSecrets.sshUserCa` | When `true`use existing secret for the ssh user CA public key. | `false` | 327 | | `existingSecrets.certsAsSecret` | When `true`use existing secret for certs instead of ConfigMap. | `false` | 328 | | `existingSecrets.configAsSecret` | When `true`use existing secret for configuration instead of ConfigMap. | `false` | 329 | | `podSecurityContext` | Set SecurityContext on POD level for STEP CA and STEP CA bootstrap job. | See [values.yaml](./values.yaml) | 330 | | `shareProcessNamespace` | Share a single process namespace between all of the containers in a pod. | `false` | 331 | | `hostAliases` | Additional entries for `/etc/hosts`. | [] | 332 | 333 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm 334 | install`. For example, 335 | 336 | ```console 337 | helm install --set provisioner.password=secretpassword,provisioner.name=Foo \ 338 | my-release smallstep/step-certificates 339 | ``` 340 | 341 | The above command sets the Step Certificates main provisioner `Foo` with the key 342 | password `secretpassword`. 343 | 344 | If you provide a custom value for `ca.dns`, be sure to append 345 | `,{{fullname}}.{{namespace}}.svc.cluster.local,127.0.0.1` to the end, otherwise 346 | accessing the CA by those DNS/IPs will fail (services internal to the cluster): 347 | 348 | ```console 349 | helm install --set ca.dns="ca.example.com\,my-release-step-certificates.default.svc.cluster.local\,127.0.0.1" \ 350 | my-release smallstep/step-certificates 351 | ``` 352 | 353 | Alternatively, a YAML file that specifies the values for the parameters can be 354 | provided while installing the chart. For example, 355 | 356 | ```console 357 | helm install -f values.yaml my-release smallstep/step-certificates 358 | ``` 359 | 360 | > **Tip**: You can use the default [values.yaml](values.yaml) 361 | 362 | ## Notes 363 | 364 | At this moment only one replica is supported, step certificates supports 365 | multiple ones using MariaDB or MySQL. 366 | 367 | # Development 368 | 369 | Testing chart by using an example yaml file: 370 | ``` 371 | helm template . -f examples/existing_secrets/value.yaml | kubectl apply -f - --dry-run=client 372 | ``` 373 | -------------------------------------------------------------------------------- /step-certificates/examples/README.md: -------------------------------------------------------------------------------- 1 | # Helm Configuration Examples 2 | 3 | ## Self Hosted Single Instance Certificate Authority 4 | 5 | 1. Edit `./certificate_authority_single_instance/ca.config` to reflect your CA environment. 6 | 7 | ```json 8 | { 9 | "root_ca_name": "example-root-ca", 10 | "intermediate_ca_name": "example-intermediate-ca", 11 | "ca_org_name": "Example CA Org", 12 | "ca_country_name": "US", 13 | "ca_locality_name": "Minnesota", 14 | "ca_dns_names": [ 15 | "ca.example.com", 16 | "mysteprelease-step-certificates.default.svc.cluster.local", 17 | "127.0.0.1" 18 | ] 19 | } 20 | ``` 21 | 22 | 2. Run the following bash script 23 | 24 | ```bash 25 | # Navigate to the example directory. 26 | cd ./certificate_authority_single_instance 27 | 28 | # Generate key material and inject into values.yaml 29 | ./generate-values.sh 30 | 31 | # Add the smallstep helm repo, if not already added 32 | helm repo add smallstep https://smallstep.github.io/helm-charts/ 33 | 34 | # Update helm repos to ensure you have the latest version 35 | helm repo update 36 | 37 | # Install the step-certificates helm chart. 38 | helm install mysteprelease -f ./values.yml smallstep/step-certificate 39 | 40 | # Save generated files somewhere safe then remove from your local machine 41 | rm -f ./*.yml ./*.json ./*.crt ./*.key ./*.pub ./*.password 42 | ``` 43 | 44 | ## Registration Authority Connected to Smallstep Certificate Manager Hosted Certificate Authority. 45 | 46 | ```bash 47 | CA_NAME='example-ca' 48 | CA_FINGERPRINT='ca-fingerprint' 49 | ORG_NAME='example-org' 50 | 51 | # Install Step If Not already installed. 52 | brew install step 53 | 54 | # Bootstrap Step against the CA if not already bootstrapped. 55 | step ca bootstrap --ca-url https://${CA_NAME}.${ORG_NAME}.ca.smallstep.com --fingerprint ${CA_FINGERPRINT} 56 | 57 | # Create a registration-authority JWK Provisioner 58 | step beta ca provisioner add registration-authority --create 59 | 60 | # Encode the JWK Provisioner password in base64 61 | JWK_ISSUER_PASSWORD=`echo 'your-password-here' | base64` 62 | 63 | # Download the example values.yml 64 | curl -o step_values.yml https://raw.githubusercontent.com/smallstep/helm-charts/master/step-certificates/examples/registration_authority/values.yml 65 | 66 | # Replace dummy values with your own values 67 | sed -e "s/your-ca-name/${CA_NAME}/g" -i step_values.yml 68 | sed -e "s/your-org/${ORG_NAME}/g" -i step_values.yml 69 | sed -e "s/your-ca-fingerprint-here/${CA_FINGERPRINT}/g" -i step_values.yml 70 | sed -e "s/your-base-64-encoded-key-password/${JWK_ISSUER_PASSWORD}/g" -i step_values.yml 71 | 72 | # Add the smallstep helm repo, if not already added 73 | helm repo add smallstep https://smallstep.github.io/helm-charts/ 74 | 75 | # Update helm repos to ensure you have the latest version 76 | helm repo update 77 | 78 | # Install the step-certificates helm chart. 79 | helm install -f step_values.yml smallstep/step-certificates 80 | ``` -------------------------------------------------------------------------------- /step-certificates/examples/certificate_authority_single_instance/.gitignore: -------------------------------------------------------------------------------- 1 | *.json 2 | *.crt 3 | *.key 4 | *.pub 5 | *.password 6 | *.yml -------------------------------------------------------------------------------- /step-certificates/examples/certificate_authority_single_instance/ca.config: -------------------------------------------------------------------------------- 1 | { 2 | "root_ca_name": "example-root-ca", 3 | "intermediate_ca_name": "example-intermediate-ca", 4 | "ca_org_name": "Example CA Org", 5 | "ca_country_name": "US", 6 | "ca_locality_name": "Minnesota", 7 | "ca_dns_names": [ 8 | "ca.example.com", 9 | "mysteprelease-step-certificates.default.svc.cluster.local", 10 | "127.0.0.1" 11 | ], 12 | "jwk_provisioner_name": "admin", 13 | "ca_url": "mysteprelease-step-certificates.default.svc.cluster.local" 14 | } -------------------------------------------------------------------------------- /step-certificates/examples/certificate_authority_single_instance/generate-values.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ROOT_CA_NAME=`jq -r '.root_ca_name' ca.config` 4 | INTERMEDIATE_CA_NAME=`jq -r '.intermediate_ca_name' ca.config` 5 | CA_ORG_NAME=`jq -r '.ca_org_name' ca.config` 6 | CA_COUNTRY_NAME=`jq -r '.ca_country_name' ca.config` 7 | CA_LOCALITY_NAME=`jq -r '.ca_locality_name' ca.config` 8 | CA_DNS_NAMES=`jq -c .ca_dns_names ca.config` 9 | CA_URL=`jq -r .ca_url ca.config` 10 | JWK_PROVISIONER_NAME=`jq -r .jwk_provisioner_name ca.config` 11 | 12 | export ROOT_CA_NAME INTERMEDIATE_CA_NAME CA_ORG_NAME CA_COUNTRY_NAME CA_LOCALITY_NAME CA_DNS_NAMES CA_URL JWK_PROVISIONER_NAME 13 | 14 | # Write Out Root and Intermediate Certificate Templates 15 | cat root-tls.json.tpl | envsubst | tee root-tls.json 16 | cat intermediate-tls.json.tpl | envsubst | tee intermediate-tls.json 17 | 18 | # Generate Root and Intermediate Passwords 19 | ROOT_TLS_PASSWORD_B64=`tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_\`{|}~' ?@[\]^_\`{|}~' ?@[\]^_\`{|}~' ?@[\]^_\`{|}~' ?@[\]^_\`{|}~' $TMP_CA_PASSWORD 155 | echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD 156 | 157 | step ca init \ 158 | --name "{{.Values.ca.name}}" \ 159 | {{- if .Values.ca.ssh.enabled }}--ssh \{{ end }} 160 | --dns "{{include "step-certificates.dns" .}}" \ 161 | --address "{{.Values.ca.address}}" \ 162 | --provisioner "{{.Values.ca.provisioner.name}}" \ 163 | --with-ca-url "{{include "step-certificates.url" .}}" \ 164 | --password-file "$TMP_CA_PASSWORD" \ 165 | --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }} 166 | {{- if not (eq .Values.ca.kms.type "") }}--kms="{{.Values.ca.kms.type}}" {{ end }} 167 | 168 | rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD 169 | 170 | {{- if .Values.ca.bootstrap.postInitHook }} 171 | {{ .Values.ca.bootstrap.postInitHook | nindent 4 }} 172 | {{- end }} 173 | 174 | echo -e "\n\e[1mCreating configmaps and secrets in {{ .Release.Namespace }} namespace ...\e[0m" 175 | 176 | # Replace secrets created on helm install 177 | # It allows to properly remove them on helm delete 178 | kbreplace -n {{ .Release.Namespace }} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config 179 | kbreplace -n {{ .Release.Namespace }} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs 180 | kbreplace -n {{ .Release.Namespace }} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets 181 | {{- if .Values.ca.ssh.enabled }} 182 | kbreplace -n {{ .Release.Namespace }} create configmap {{ include "step-certificates.fullname" . }}-templates-ssh --from-file $(step path)/templates/ssh 183 | {{- end }} 184 | 185 | kbreplace -n {{ .Release.Namespace }} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}" 186 | kbreplace -n {{ .Release.Namespace }} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}" 187 | 188 | # Label all configmaps and secrets 189 | kubectl -n {{ .Release.Namespace }} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }} 190 | kubectl -n {{ .Release.Namespace }} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }} 191 | kubectl -n {{ .Release.Namespace }} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }} 192 | {{- if .Values.ca.ssh.enabled }} 193 | kubectl -n {{ .Release.Namespace }} label configmap {{ include "step-certificates.fullname" . }}-templates-ssh {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }} 194 | {{- end }} 195 | kubectl -n {{ .Release.Namespace }} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }} 196 | kubectl -n {{ .Release.Namespace }} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }} 197 | 198 | # Patch webhook if autocert is enabled 199 | {{- if .Values.autocert.enabled }} 200 | CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n') 201 | kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \ 202 | --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]" 203 | {{- end }} 204 | 205 | echo -e "\n\e[1mStep Certificates installed!\e[0m" 206 | echo 207 | echo "CA URL: {{include "step-certificates.url" .}}" 208 | echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)" 209 | echo 210 | {{- end }} 211 | -------------------------------------------------------------------------------- /step-certificates/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "step-certificates.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- $apiVersion := .Capabilities.KubeVersion.GitVersion }} 5 | {{- if semverCompare ">=1.19-0" $apiVersion -}} 6 | apiVersion: networking.k8s.io/v1 7 | {{- else if semverCompare ">=1.14-0" $apiVersion -}} 8 | apiVersion: networking.k8s.io/v1beta1 9 | {{- else -}} 10 | apiVersion: extensions/v1beta1 11 | {{- end }} 12 | kind: Ingress 13 | metadata: 14 | name: {{ $fullName }} 15 | namespace: {{ .Release.Namespace }} 16 | labels: 17 | {{- include "step-certificates.labels" . | nindent 4 }} 18 | {{- with .Values.ingress.annotations }} 19 | annotations: 20 | {{- toYaml . | nindent 4 }} 21 | {{- end }} 22 | spec: 23 | {{- if .Values.ingress.ingressClassName }} 24 | ingressClassName: {{ .Values.ingress.ingressClassName }} 25 | {{- end }} 26 | {{- if .Values.ingress.tls }} 27 | tls: 28 | {{- range .Values.ingress.tls }} 29 | - hosts: 30 | {{- range .hosts }} 31 | - {{ . | quote }} 32 | {{- end }} 33 | secretName: {{ .secretName }} 34 | {{- end }} 35 | {{- end }} 36 | rules: 37 | {{- range .Values.ingress.hosts }} 38 | - host: {{ .host | quote }} 39 | http: 40 | paths: 41 | {{- range .paths }} 42 | {{- if eq (typeOf .) "string" }} 43 | - path: {{ . }} 44 | pathType: ImplementationSpecific 45 | {{- else }} 46 | - path: {{ .path }} 47 | pathType: {{ default "ImplementationSpecific" .type }} 48 | {{- end }} 49 | backend: 50 | {{- if semverCompare ">=1.19-0" $apiVersion }} 51 | service: 52 | name: {{ $fullName }} 53 | port: 54 | number: {{ $svcPort }} 55 | {{- else }} 56 | serviceName: {{ $fullName }} 57 | servicePort: {{ $svcPort }} 58 | {{- end }} 59 | {{- end }} 60 | {{- end }} 61 | {{- end }} 62 | -------------------------------------------------------------------------------- /step-certificates/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Release.IsInstall -}} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: {{ include "step-certificates.fullname" . }}-config 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | helm.sh/chart: {{ include "step-certificates.chart" . }} 9 | app.kubernetes.io/name: {{ include "step-certificates.name" . }} 10 | app.kubernetes.io/instance: {{ .Release.Name }} 11 | app.kubernetes.io/managed-by: {{ .Release.Service }} 12 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 13 | rules: 14 | - apiGroups: [""] 15 | resources: ["secrets", "configmaps"] 16 | verbs: ["get", "create", "update", "patch"] 17 | --- 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | kind: RoleBinding 20 | metadata: 21 | name: {{ include "step-certificates.fullname" . }}-config 22 | namespace: {{ .Release.Namespace }} 23 | labels: 24 | helm.sh/chart: {{ include "step-certificates.chart" . }} 25 | app.kubernetes.io/name: {{ include "step-certificates.name" . }} 26 | app.kubernetes.io/instance: {{ .Release.Name }} 27 | app.kubernetes.io/managed-by: {{ .Release.Service }} 28 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 29 | subjects: 30 | - kind: ServiceAccount 31 | name: {{ include "step-certificates.fullname" . }}-config 32 | namespace: {{ .Release.Namespace }} 33 | roleRef: 34 | kind: Role 35 | name: {{ include "step-certificates.fullname" . }}-config 36 | apiGroup: rbac.authorization.k8s.io 37 | --- 38 | {{ if .Values.autocert.enabled }} 39 | apiVersion: rbac.authorization.k8s.io/v1 40 | kind: ClusterRole 41 | metadata: 42 | name: {{ include "step-certificates.fullname" . }}-config 43 | labels: 44 | helm.sh/chart: {{ include "step-certificates.chart" . }} 45 | app.kubernetes.io/name: {{ include "step-certificates.name" . }} 46 | app.kubernetes.io/instance: {{ .Release.Name }} 47 | app.kubernetes.io/managed-by: {{ .Release.Service }} 48 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 49 | rules: 50 | - apiGroups: ["admissionregistration.k8s.io"] 51 | resources: ["mutatingwebhookconfigurations"] 52 | verbs: ["get", "create", "update", "patch"] 53 | --- 54 | apiVersion: rbac.authorization.k8s.io/v1 55 | kind: ClusterRoleBinding 56 | metadata: 57 | name: {{ include "step-certificates.fullname" . }}-config 58 | namespace: {{ .Release.Namespace }} 59 | labels: 60 | helm.sh/chart: {{ include "step-certificates.chart" . }} 61 | app.kubernetes.io/name: {{ include "step-certificates.name" . }} 62 | app.kubernetes.io/instance: {{ .Release.Name }} 63 | app.kubernetes.io/managed-by: {{ .Release.Service }} 64 | app.kubernetes.io/version: {{ .Chart.AppVersion }} 65 | subjects: 66 | - kind: ServiceAccount 67 | name: {{ include "step-certificates.fullname" . }}-config 68 | namespace: {{ .Release.Namespace }} 69 | roleRef: 70 | kind: ClusterRole 71 | name: {{ include "step-certificates.fullname" . }}-config 72 | apiGroup: rbac.authorization.k8s.io 73 | {{- end }} # if .Values.autocert.enabled 74 | {{- end }} 75 | -------------------------------------------------------------------------------- /step-certificates/templates/secrets.yaml: -------------------------------------------------------------------------------- 1 | # Secrets that will be updated by the configuration job: 2 | # 1. CA keys password. 3 | # 2. Provisioner password. 4 | 5 | {{- if or (and .Values.bootstrap.enabled .Values.bootstrap.secrets) (and .Values.inject.enabled (not (eq .Values.inject.secrets.ca_password ""))) }} 6 | apiVersion: v1 7 | kind: Secret 8 | {{- if .Values.inject.enabled }} 9 | type: smallstep.com/ca-password 10 | {{- end }} 11 | metadata: 12 | name: {{ include "step-certificates.fullname" . }}-ca-password 13 | namespace: {{ .Release.Namespace }} 14 | {{- if .Values.inject.enabled }} 15 | data: 16 | password: {{ .Values.inject.secrets.ca_password }} 17 | {{- end }} 18 | {{- end }} 19 | --- 20 | {{- if or (and .Values.bootstrap.enabled .Values.bootstrap.secrets) (and .Values.inject.enabled (not (eq .Values.inject.secrets.provisioner_password ""))) }} 21 | apiVersion: v1 22 | kind: Secret 23 | {{- if .Values.inject.enabled }} 24 | type: smallstep.com/provisioner-password 25 | {{- end }} 26 | metadata: 27 | name: {{ include "step-certificates.fullname" . }}-provisioner-password 28 | namespace: {{ .Release.Namespace }} 29 | {{- if .Values.inject.enabled }} 30 | data: 31 | password: {{ .Values.inject.secrets.provisioner_password }} 32 | {{- end }} 33 | {{- end }} 34 | --- 35 | {{- if and .Values.inject.enabled (and .Values.inject.secrets.certificate_issuer.enabled (not (eq .Values.inject.secrets.certificate_issuer.password ""))) }} 36 | apiVersion: v1 37 | kind: Secret 38 | type: smallstep.com/certificate-issuer-password 39 | metadata: 40 | name: {{ include "step-certificates.fullname" . }}-certificate-issuer-password 41 | namespace: {{ .Release.Namespace }} 42 | data: 43 | password: {{ .Values.inject.secrets.certificate_issuer.password }} 44 | {{- end }} 45 | --- 46 | {{- if and .Values.inject.enabled (and .Values.inject.secrets.ssh.enabled (not (eq .Values.inject.secrets.ssh.host_ca_password ""))) }} 47 | apiVersion: v1 48 | kind: Secret 49 | type: smallstep.com/ssh-host-ca-password 50 | metadata: 51 | name: {{ include "step-certificates.fullname" . }}-ssh-host-ca-password 52 | namespace: {{ .Release.Namespace }} 53 | data: 54 | password: {{ .Values.inject.secrets.ssh.host_ca_password }} 55 | {{- end }} 56 | --- 57 | {{- if and .Values.inject.enabled (and .Values.inject.secrets.ssh.enabled (not (eq .Values.inject.secrets.ssh.user_ca_password ""))) }} 58 | apiVersion: v1 59 | kind: Secret 60 | type: smallstep.com/ssh-user-ca-password 61 | metadata: 62 | name: {{ include "step-certificates.fullname" . }}-ssh-user-ca-password 63 | namespace: {{ .Release.Namespace }} 64 | data: 65 | password: {{ .Values.inject.secrets.ssh.user_ca_password }} 66 | {{- end }} 67 | --- 68 | {{- if and .Values.inject.enabled .Values.bootstrap.secrets}} 69 | apiVersion: v1 70 | kind: Secret 71 | type: smallstep.com/private-keys 72 | metadata: 73 | name: {{ include "step-certificates.fullname" . }}-secrets 74 | namespace: {{ .Release.Namespace }} 75 | stringData: 76 | {{- if and .Values.inject.secrets.certificate_issuer.enabled (not (eq .Values.inject.secrets.certificate_issuer.key "")) }} 77 | certificate_issuer_key: |- 78 | {{- .Values.inject.secrets.certificate_issuer.key | nindent 4 }} 79 | {{- end }} 80 | {{- if .Values.inject.secrets.x509.enabled }} 81 | intermediate_ca_key: |- 82 | {{- .Values.inject.secrets.x509.intermediate_ca_key | nindent 4 }} 83 | root_ca_key: |- 84 | {{- .Values.inject.secrets.x509.root_ca_key | nindent 4 }} 85 | {{- end }} 86 | {{- if .Values.inject.secrets.ssh.enabled }} 87 | {{- if not (eq "" .Values.inject.secrets.ssh.host_ca_key) }} 88 | ssh_host_ca_key: |- 89 | {{- .Values.inject.secrets.ssh.host_ca_key | nindent 4 }} 90 | {{- end }} 91 | {{- if not (eq "" .Values.inject.secrets.ssh.user_ca_key) }} 92 | ssh_user_ca_key: |- 93 | {{- .Values.inject.secrets.ssh.user_ca_key | nindent 4 }} 94 | {{- end }} 95 | {{- end}} 96 | {{- end }} 97 | --- 98 | {{- if .Values.linkedca.token }} 99 | apiVersion: v1 100 | kind: Secret 101 | type: smallstep.com/step-ca-token 102 | metadata: 103 | name: {{ include "step-certificates.fullname" . }}-step-ca-token 104 | namespace: {{ .Release.Namespace }} 105 | data: 106 | token: {{ .Values.linkedca.token }} 107 | {{- end }} 108 | -------------------------------------------------------------------------------- /step-certificates/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "step-certificates.fullname" . }} 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | {{- include "step-certificates.labels" . | nindent 4 }} 8 | {{- with .Values.service.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | spec: 13 | type: {{ .Values.service.type }} 14 | {{- with .Values.service.externalIPs }} 15 | externalIPs: 16 | {{- toYaml . | nindent 4 }} 17 | {{- end }} 18 | ports: 19 | - port: {{ .Values.service.port }} 20 | targetPort: {{ .Values.service.targetPort }} 21 | protocol: TCP 22 | name: https 23 | {{- if eq .Values.service.type "NodePort" }} 24 | nodePort: {{ .Values.service.nodePort }} 25 | {{- end }} 26 | selector: 27 | app.kubernetes.io/name: {{ include "step-certificates.name" . }} 28 | app.kubernetes.io/instance: {{ .Release.Name }} 29 | -------------------------------------------------------------------------------- /step-certificates/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceaccount.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "step-certificates.serviceaccountname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "step-certificates.labels" . | nindent 4 }} 9 | {{- with .Values.serviceaccount.labels }} 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- with .Values.serviceaccount.annotations }} 13 | annotations: 14 | {{- toYaml . | nindent 4 }} 15 | {{- end }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /step-certificates/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "step-certificates.fullname" . }}-test-connection" 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | {{- include "step-certificates.labels" . | nindent 4 }} 8 | annotations: 9 | "helm.sh/hook": test 10 | spec: 11 | containers: 12 | - name: curl 13 | image: alpine/curl:latest 14 | command: 15 | - 'curl' 16 | args: 17 | - '-s' 18 | - '-k' 19 | - 'https://{{ include "step-certificates.fullname" . }}:{{ .Values.service.port }}/health' 20 | restartPolicy: Never 21 | -------------------------------------------------------------------------------- /step-certificates/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for step-certificates. 2 | 3 | # kind is the type of object to use when deploying the CA. 4 | # Changing the deployment type is experimental. 5 | kind: StatefulSet 6 | 7 | # replicaCount is the number of replicas of step-certificates. 8 | # Only one replica is supported at this time. 9 | replicaCount: 1 10 | 11 | # nameOverride overrides the name of the chart. 12 | nameOverride: "" 13 | # fullnameOverride overrides the full name of the chart. 14 | fullnameOverride: "" 15 | 16 | # image contains the docker image for step-certificates. 17 | image: 18 | repository: cr.smallstep.com/smallstep/step-ca 19 | initContainerRepository: busybox:latest 20 | pullPolicy: IfNotPresent 21 | # Overrides the image tag whose default is the chart appVersion. 22 | tag: "" 23 | 24 | # commands allows to override the default command. 25 | command: [] 26 | # args allows to override the default arguments. 27 | args: [] 28 | # workingDir specifies the ca container working directory 29 | workingDir: "/home/step" 30 | 31 | # Use existing secrets instead of 'bootstrap' init-container or 'inject'-element from helm chart 32 | # Note, the MutatingWebhookConfiguration created by autocert is not patched with CA bundle as the bootstrap init-container is not run 33 | existingSecrets: 34 | enabled: false 35 | ca: false 36 | issuer: false 37 | certsAsSecret: false 38 | configAsSecret: false 39 | sshHostCa: false 40 | sshUserCa: false 41 | sshTemplates: false 42 | 43 | # bootstrap contains the docker image for bootstrapping the configurations. 44 | # 45 | # It's also possible to disable the creation of secrets and configmaps. 46 | bootstrap: 47 | image: 48 | repository: cr.smallstep.com/smallstep/step-ca-bootstrap 49 | tag: latest 50 | pullPolicy: IfNotPresent 51 | # enabled defines if the bootstrap job is created. 52 | enabled: true 53 | # configmaps defines if the configmaps are created. 54 | configmaps: true 55 | # secrets defines if the secrets are created. 56 | secrets: true 57 | containerSecurityContext: 58 | allowPrivilegeEscalation: false 59 | readOnlyRootFilesystem: false 60 | runAsUser: 1000 61 | capabilities: 62 | drop: ["ALL"] 63 | runAsNonRoot: true 64 | # seccompProfile: 65 | # type: RuntimeDefault 66 | 67 | # Extra labels 68 | podExtraLabels: {} 69 | 70 | # inject contains values to be injected into config maps and secrets 71 | inject: 72 | enabled: false 73 | config: 74 | files: 75 | ca.json: 76 | root: /home/step/certs/root_ca.crt 77 | federateRoots: [] 78 | crt: /home/step/certs/intermediate_ca.crt 79 | key: /home/step/secrets/intermediate_ca_key 80 | address: 0.0.0.0:9000 81 | dnsNames: 82 | - ca.example.com 83 | - mysteprelease-step-certificates.default.svc.cluster.local 84 | - 127.0.0.1 85 | logger: 86 | format: json 87 | db: 88 | type: badger 89 | dataSource: /home/step/db 90 | authority: 91 | claims: 92 | minTLSCertDuration: 5m 93 | maxTLSCertDuration: 24h 94 | defaultTLSCertDuration: 24h 95 | disableRenewal: false 96 | minHostSSHCertDuration: 5m 97 | maxHostSSHCertDuration: 1680h 98 | defaultHostSSHCertDuration: 720h 99 | minUserSSHCertDuration: 5m 100 | maxUserSSHCertDuration: 24h 101 | defaultUserSSHCertDuration: 24h 102 | provisioners: 103 | - type: ACME 104 | name: acme 105 | forceCN: true 106 | claims: {} 107 | tls: 108 | cipherSuites: 109 | - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 110 | - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 111 | - TLS_AES_128_GCM_SHA256 112 | minVersion: 1.2 113 | maxVersion: 1.3 114 | renegotiation: false 115 | defaults.json: 116 | ca-url: https://mysteprelease-step-certificates.default.svc.cluster.local 117 | ca-config: /home/step/config/ca.json 118 | fingerprint: fingerprint 119 | root: /home/step/certs/root_ca.crt 120 | templates: 121 | x509_leaf.tpl: | 122 | { 123 | "subject": {{ toJson .Subject }}, 124 | "sans": {{ toJson .SANs }}, 125 | {{- if typeIs "*rsa.PublicKey" .Insecure.CR.PublicKey }} 126 | "keyUsage": ["keyEncipherment", "digitalSignature"], 127 | {{- else }} 128 | "keyUsage": ["digitalSignature"], 129 | {{- end }} 130 | "extKeyUsage": ["serverAuth", "clientAuth"] 131 | } 132 | ssh.tpl: | 133 | { 134 | "type": {{ toJson .Type }}, 135 | "keyId": {{ toJson .KeyID }}, 136 | "principals": {{ toJson .Principals }}, 137 | "extensions": {{ toJson .Extensions }}, 138 | "criticalOptions": {{ toJson .CriticalOptions }} 139 | } 140 | 141 | certificates: 142 | # certificate_issuer contains the text of the Certificate Issuer certificate in PEM format. 143 | # when set to "", certificate issuer crt is not injected, this is the default for the JWK provisioner. 144 | # Provide a value if using the X5C provisioner. 145 | certificate_issuer: "" 146 | # certificate_issuer: | 147 | # -----BEGIN CERTIFICATE----- 148 | # ... 149 | # -----END CERTIFICATE----- 150 | 151 | # intermediate_ca contains the text of the intermediate CA Certificate 152 | intermediate_ca: "" 153 | # intermediate_ca: | 154 | # -----BEGIN CERTIFICATE----- 155 | # ... 156 | # -----END CERTIFICATE----- 157 | 158 | # root_ca contains the text of the root CA Certificate 159 | root_ca: "" 160 | # root_ca: | 161 | # -----BEGIN CERTIFICATE----- 162 | # ... 163 | # -----END CERTIFICATE----- 164 | 165 | # ssh_host_ca contains the text of the public ssh key for the SSH root CA 166 | ssh_host_ca: "" 167 | # ssh_host_ca: "ecdsa-sha2-nistp384 public-key-here==" 168 | 169 | # ssh_user_ca contains the text of the public ssh key for the SSH root CA 170 | ssh_user_ca: "" 171 | # ssh_user_ca: "ecdsa-sha2-nistp384 public-key-here==" 172 | 173 | secrets: 174 | # ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key 175 | # This value must be base64 encoded. 176 | ca_password: "" 177 | provisioner_password: "" 178 | 179 | certificate_issuer: 180 | # enabled enables injection of certificate issuer certificates and keys when set to true. 181 | enabled: false 182 | key: "" 183 | # key: | 184 | # -----BEGIN ENCRYPTED PRIVATE KEY----- 185 | # ... 186 | # -----END ENCRYPTED PRIVATE KEY----- 187 | # password sets the certificate issuer password that decrypts the encrypted certificate issuer key. Must be base64 encoded. 188 | password: "" 189 | 190 | x509: 191 | # enabled enables injection of x509 certificates and keys when set to true. 192 | enabled: true 193 | # intermediate_ca_key contains the contents of your encrypted intermediate CA key 194 | intermediate_ca_key: "" 195 | # intermediate_ca_key: | 196 | # -----BEGIN EC PRIVATE KEY----- 197 | # ... 198 | # -----END EC PRIVATE KEY----- 199 | 200 | # root_ca_key contains the contents of your encrypted root CA key 201 | # Note that this value can be omitted without impacting the functionality of step-certificates 202 | # If supplied, this should be encrypted using a unique password that is not used for encrypting 203 | # the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key. 204 | root_ca_key: "" 205 | # root_ca_key: | 206 | # -----BEGIN EC PRIVATE KEY----- 207 | # ... 208 | # -----END EC PRIVATE KEY----- 209 | 210 | ssh: 211 | # enabled enables injection of ssh certificates and keys when set to true. 212 | enabled: true 213 | # ssh_host_ca_key contains the contents of your encrypted SSH Host CA key 214 | host_ca_key: "" 215 | # host_ca_key: | 216 | # -----BEGIN OPENSSH PRIVATE KEY----- 217 | # ... 218 | # -----END OPENSSH PRIVATE KEY----- 219 | host_ca_password: "" 220 | 221 | # ssh_user_ca_key contains the contents of your encrypted SSH User CA key 222 | user_ca_key: "" 223 | # user_ca_key: | 224 | # -----BEGIN OPENSSH PRIVATE KEY----- 225 | # ... 226 | # -----END OPENSSH PRIVATE KEY----- 227 | user_ca_password: "" 228 | 229 | 230 | # service contains configuration for the kubernetes service. 231 | service: 232 | type: ClusterIP 233 | port: 443 234 | targetPort: 9000 235 | nodePort: "" 236 | annotations: {} 237 | externalIPs: [] 238 | 239 | # linkedca contains the token to configure step-ca using the linkedca mode. 240 | # 241 | # The linked ca token can be provided using the linkedca.token value or using a 242 | # reference to a secret. 243 | linkedca: 244 | # the linked ca token. 245 | token: 246 | # Reference to a secret name and key. 247 | secretKeyRef: 248 | name: 249 | key: 250 | 251 | # ca contains the certificate authority configuration. 252 | ca: 253 | # name is new public key infrastructure (PKI) names. 254 | name: Step Certificates 255 | # address is the HTTP listener address of step-certificates. 256 | address: :9000 257 | # dns is the comma separated dns names to use. Leave it empty to use the format: 258 | # {include "step-certificates.fullname" .}.{ .Release.Namespace}.svc.cluster.local,127.0.0.1 259 | dns: 260 | # url is the http url where step-certificates will listen at. Leave it empty to use the format 261 | # https://{{ include "step-certificates.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local 262 | url: 263 | # password is the password used to encrypt the keys. Leave it empty to generate a random one. 264 | password: 265 | # provisioner contains the step-certificates provisioner configuration. 266 | provisioner: 267 | # name is the new provisioner name. 268 | name: admin 269 | # password is the password used to encrypt the provisioner private key. 270 | password: 271 | # db contains the step-certificate database configuration. 272 | db: 273 | # enabled defines if the database is enabled. 274 | enabled: true 275 | # persistent defines if a Persistent Volume Claim is used, if false and emptyDir will be used. 276 | persistent: true 277 | # storeageClass is Persistent Volume Storage Class 278 | # If defined, storageClassName: . 279 | # If set to "-", storageClassName: "", which disables dynamic provisioning. 280 | # If undefined or set to null, no storageClassName spec is set, choosing the 281 | # default provisioner (gp2 on AWS, standard on GKE, AWS & OpenStack). 282 | storageClass: 283 | ## Persistent Volume existing claim name 284 | ## Requires ca.db.persistent: true 285 | ## If defined, PVC must be created manually before volume will be bound 286 | # existingClaim: "" 287 | # accessModes defines the Persistent Volume Access Mode. 288 | accessModes: 289 | - ReadWriteOnce 290 | # size is the Persistent Volume size. 291 | size: 10Gi 292 | # Whether to enable ssh support for step-ca 293 | ssh: 294 | enabled: false 295 | # kms type to utilize 296 | kms: 297 | type: "" 298 | # additional environment variables to set in the step-certificates container 299 | env: [] 300 | bootstrap: 301 | # Add script snippets here to be executed after the step ca init has been run 302 | postInitHook: "" 303 | # Use existing secret for ca-password 304 | existingSecrets: 305 | enabled: false 306 | init: 307 | containerSecurityContext: 308 | allowPrivilegeEscalation: false 309 | readOnlyRootFilesystem: true 310 | runAsUser: 1000 311 | capabilities: 312 | drop: ["ALL"] 313 | runAsNonRoot: true 314 | # seccompProfile: 315 | # type: RuntimeDefault 316 | containerSecurityContext: 317 | allowPrivilegeEscalation: false 318 | readOnlyRootFilesystem: true 319 | runAsUser: 1000 320 | # runAsRoot: 0 runs the ca as root instead of the step user. This is required in 321 | # some storage provisioners. 322 | # runAsUser: 0 323 | capabilities: 324 | drop: ["ALL"] 325 | add: ["NET_BIND_SERVICE"] 326 | runAsNonRoot: true 327 | # seccompProfile: 328 | # type: RuntimeDefault 329 | 330 | # autocert is used to configure the autocert chart that depends on step-certificates. 331 | autocert: 332 | enabled: false 333 | 334 | # ingress contains the configuration for an ingress controller. 335 | ingress: 336 | enabled: false 337 | annotations: {} 338 | ingressClassName: "" 339 | hosts: [] 340 | tls: [] 341 | 342 | # resources contains the CPU/memory resource requests/limits. 343 | resources: {} 344 | # We usually recommend not to specify default resources and to leave this as a conscious 345 | # choice for the user. This also increases chances charts run on environments with little 346 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 347 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 348 | # limits: 349 | # cpu: 100m 350 | # memory: 128Mi 351 | # requests: 352 | # cpu: 100m 353 | # memory: 128Mi 354 | 355 | # Configure extra volumes and volume mounts as YAML expressions. 356 | # And example that will mount an extra volume would be: 357 | # extraVolumes: 358 | # - name: custom-ca 359 | # configMap: 360 | # name: custom-ca-certs 361 | # extraVolumeMounts: 362 | # - name: custom-ca 363 | # mountPath: /etc/ssl/certs/custom-ca.pem 364 | extraVolumes: [] 365 | extraVolumeMounts: [] 366 | 367 | ## extraInitContainers: 368 | ## - name: do-something 369 | ## image: busybox 370 | ## command: ['do', 'something'] 371 | ## 372 | extraInitContainers: [] 373 | 374 | ## extraContainers: 375 | ## - name: do-something 376 | ## image: busybox 377 | ## command: ['do', 'something'] 378 | ## 379 | extraContainers: [] 380 | 381 | ## Configure additional entries for /etc/hosts. 382 | ## hostAliases: 383 | ## - ip: 10.0.0.1 384 | ## hostnames: 385 | ## - host.domain.com 386 | hostAliases: [] 387 | 388 | # shareProcessNamespace share a single process namespace between all of the 389 | # containers in a pod. 390 | shareProcessNamespace: false 391 | 392 | # nodeSelector contains the node labels for pod assignment. 393 | nodeSelector: {} 394 | 395 | # tolerations contains the toleration labels for pod assignment. 396 | tolerations: [] 397 | 398 | # affinity contains the affinity settings for pod assignment. 399 | affinity: {} 400 | 401 | # create or use a service account for running the ca. Useful for oidc access to kms for example 402 | serviceaccount: 403 | create: false 404 | name: "" 405 | labels: {} 406 | annotations: {} 407 | 408 | # default SecurityContext for pods, can be altered for containers via containerSecurityContext 409 | podSecurityContext: 410 | runAsUser: 1000 411 | runAsNonRoot: true 412 | runAsGroup: 1000 413 | fsGroup: 1000 414 | # seccompProfile: 415 | # type: RuntimeDefault 416 | -------------------------------------------------------------------------------- /step-issuer/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /step-issuer/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: step-issuer 3 | type: application 4 | version: 1.9.8 5 | appVersion: 0.9.8 6 | description: Step-issuer helm chart for kubernetes. 7 | home: https://smallstep.com 8 | keywords: 9 | - authority 10 | - ca 11 | - cert-manager 12 | - certificate 13 | - certificate-authority 14 | - certificates 15 | - kubernetes 16 | - pki 17 | - security 18 | - security-tools 19 | - smallstep 20 | - ssh 21 | - step 22 | - step-ca 23 | - step-issuer 24 | - tls 25 | - x509 26 | maintainers: 27 | - name: Mariano Cano 28 | email: mariano@smallstep.com 29 | - name: Irwan Shofwan 30 | email: abigaelse2@gmail.com 31 | - name: Muhammad Fauzan Razandi 32 | email: muhammad.fauzan.razandi.16@gmail.com 33 | -------------------------------------------------------------------------------- /step-issuer/README.md: -------------------------------------------------------------------------------- 1 | # Step Issuer 2 | 3 | ⚙️ A certificate issuer for cert-manager using step certificates CA. 4 | 5 | For complete install instructions, visit . 6 | 7 | ## TL;DR 8 | 9 | ```console 10 | helm repo add smallstep https://smallstep.github.io/helm-charts 11 | helm repo update 12 | helm install step-issuer smallstep/step-issuer 13 | ``` 14 | 15 | ## Prerequisites 16 | 17 | - Kubernetes 1.10+ 18 | 19 | ## Installing the Chart 20 | 21 | To install the chart with the release name `step-issuer`: 22 | 23 | ```console 24 | helm install step-issuer smallstep/step-issuer 25 | ``` 26 | 27 | The command deploys step-issuer on the Kubernetes cluster with the default configuration. 28 | 29 | > **Tip**: List all releases using `helm list` 30 | 31 | ## Uninstalling the Chart 32 | 33 | To uninstall/delete the `step-issuer` deployment: 34 | 35 | ```console 36 | helm uninstall step-issuer 37 | ``` 38 | 39 | The command removes all the Kubernetes components associated with the chart and 40 | deletes the release. 41 | 42 | ## Configuration 43 | 44 | The following table lists the configurable parameters of the Step Issuer chart 45 | and their default values. 46 | 47 | | Parameter | Description | Default | 48 | | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- | ----------------------------------- | 49 | | `replicaCount` | Number of Step Issuer replicas. | `1` | 50 | | `image.repository` | Repository of the Step Issuer image. | `cr.step.sm/smallstep/step-issuer` | 51 | | `image.tag` | Tag of the image. If empty it will use .Chart.appVersion. | `""` | 52 | | `image.pullPolicy` | Step Issuer image pull policy | `IfNotPresent` | 53 | | `deployment.args.enableLeaderElection` | Enable k8s controller leader election. | `true` | 54 | | `deployment.args.disableApprovalCheck` | To disable cert-manager approvals on old version of cert-manager. | `false` | 55 | | `deployment.strategy` | To change the deployment strategy. | `{}` | 56 | | `stepIssuer.create` | If we should automatically create a StepIssuer | `false` | 57 | | `stepIssuer.caUrl` | Step Certificates CA URL. This is usually the step certificates service FQDN. | `""` | 58 | | `stepIssuer.caBundle` | Step Certificates root certificate in a single-line base64 string. | `""` | 59 | | `stepIssuer.provisioner.name` | Name of the provisioner used for authorizing the sign of certificates. | `""` | 60 | | `stepIssuer.provisioner.kid` | Key id of the provisioner used for authorizing the sign of certificates. | `""` | 61 | | `stepIssuer.provisioner.passwordRef.name` | Name of the secret with the provisioner password. | `""` | 62 | | `stepIssuer.provisioner.passwordRef.key` | Key name in the the secret with the provisioner password. | `""` | 63 | | `stepClusterIssuer.create` | If we should automatically create a StepClusterIssuer | `false` | 64 | | `stepClusterIssuer.caUrl` | Step Certificates CA URL. This is usually the step certificates service FQDN. | `""` | 65 | | `stepClusterIssuer.caBundle` | Step Certificates root certificate in a single-line base64 string. | `""` | 66 | | `stepClusterIssuer.provisioner.name` | Name of the provisioner used for authorizing the sign of certificates. | `""` | 67 | | `stepClusterIssuer.provisioner.kid` | Key id of the provisioner used for authorizing the sign of certificates. | `""` | 68 | | `stepClusterIssuer.provisioner.passwordRef.name` | Name of the secret with the provisioner password. | `""` | 69 | | `stepClusterIssuer.provisioner.passwordRef.key` | Key name in the the secret with the provisioner password. | `""` | 70 | | `stepClusterIssuer.provisioner.passwordRef.namespace` | Namespace where the provisioner password secret resides. | `""` | 71 | -------------------------------------------------------------------------------- /step-issuer/crds/certmanager.step.sm_stepclusterissuers.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.10.0 7 | name: stepclusterissuers.certmanager.step.sm 8 | spec: 9 | group: certmanager.step.sm 10 | names: 11 | kind: StepClusterIssuer 12 | listKind: StepClusterIssuerList 13 | plural: stepclusterissuers 14 | singular: stepclusterissuer 15 | scope: Cluster 16 | versions: 17 | - name: v1beta1 18 | schema: 19 | openAPIV3Schema: 20 | description: StepClusterIssuer is the Schema for the stepclusterissuers API 21 | properties: 22 | apiVersion: 23 | description: 'APIVersion defines the versioned schema of this representation 24 | of an object. Servers should convert recognized schemas to the latest 25 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 26 | type: string 27 | kind: 28 | description: 'Kind is a string value representing the REST resource this 29 | object represents. Servers may infer this from the endpoint the client 30 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 31 | type: string 32 | metadata: 33 | type: object 34 | spec: 35 | description: StepClusterIssuerSpec defines the desired state of StepClusterIssuer 36 | properties: 37 | caBundle: 38 | description: CABundle is a base64 encoded TLS certificate used to 39 | verify connections to the step certificates server. If not set the 40 | system root certificates are used to validate the TLS connection. 41 | format: byte 42 | type: string 43 | provisioner: 44 | description: Provisioner contains the step certificates provisioner 45 | configuration. 46 | properties: 47 | kid: 48 | description: KeyID is the kid property of the JWK provisioner. 49 | type: string 50 | name: 51 | description: Names is the name of the JWK provisioner. 52 | type: string 53 | passwordRef: 54 | description: PasswordRef is a reference to a Secret containing 55 | the provisioner password used to decrypt the provisioner private 56 | key. 57 | properties: 58 | key: 59 | description: The key of the secret to select from. Must be 60 | a valid secret key. 61 | type: string 62 | name: 63 | description: The name of the secret in the pod's namespace 64 | to select from. 65 | type: string 66 | namespace: 67 | description: The namespace of the secret in the pod's namespace 68 | to select from. 69 | type: string 70 | required: 71 | - name 72 | - namespace 73 | type: object 74 | required: 75 | - kid 76 | - name 77 | - passwordRef 78 | type: object 79 | url: 80 | description: URL is the base URL for the step certificates instance. 81 | type: string 82 | required: 83 | - caBundle 84 | - provisioner 85 | - url 86 | type: object 87 | status: 88 | description: StepClusterIssuerStatus defines the observed state of StepClusterIssuer 89 | properties: 90 | conditions: 91 | items: 92 | description: StepClusterIssuerCondition contains condition information 93 | for the step issuer. 94 | properties: 95 | lastTransitionTime: 96 | description: LastTransitionTime is the timestamp corresponding 97 | to the last status change of this condition. 98 | format: date-time 99 | type: string 100 | message: 101 | description: Message is a human readable description of the 102 | details of the last transition, complementing reason. 103 | type: string 104 | reason: 105 | description: Reason is a brief machine readable explanation 106 | for the condition's last transition. 107 | type: string 108 | status: 109 | allOf: 110 | - enum: 111 | - "True" 112 | - "False" 113 | - Unknown 114 | - enum: 115 | - "True" 116 | - "False" 117 | - Unknown 118 | description: Status of the condition, one of ('True', 'False', 119 | 'Unknown'). 120 | type: string 121 | type: 122 | description: Type of the condition, currently ('Ready'). 123 | enum: 124 | - Ready 125 | type: string 126 | required: 127 | - status 128 | - type 129 | type: object 130 | type: array 131 | type: object 132 | type: object 133 | served: true 134 | storage: true 135 | subresources: 136 | status: {} 137 | -------------------------------------------------------------------------------- /step-issuer/crds/certmanager.step.sm_stepissuers.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.10.0 7 | name: stepissuers.certmanager.step.sm 8 | spec: 9 | group: certmanager.step.sm 10 | names: 11 | kind: StepIssuer 12 | listKind: StepIssuerList 13 | plural: stepissuers 14 | singular: stepissuer 15 | scope: Namespaced 16 | versions: 17 | - name: v1beta1 18 | schema: 19 | openAPIV3Schema: 20 | description: StepIssuer is the Schema for the stepissuers API 21 | properties: 22 | apiVersion: 23 | description: 'APIVersion defines the versioned schema of this representation 24 | of an object. Servers should convert recognized schemas to the latest 25 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 26 | type: string 27 | kind: 28 | description: 'Kind is a string value representing the REST resource this 29 | object represents. Servers may infer this from the endpoint the client 30 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 31 | type: string 32 | metadata: 33 | type: object 34 | spec: 35 | description: StepIssuerSpec defines the desired state of StepIssuer 36 | properties: 37 | caBundle: 38 | description: CABundle is a base64 encoded TLS certificate used to 39 | verify connections to the step certificates server. If not set the 40 | system root certificates are used to validate the TLS connection. 41 | format: byte 42 | type: string 43 | provisioner: 44 | description: Provisioner contains the step certificates provisioner 45 | configuration. 46 | properties: 47 | kid: 48 | description: KeyID is the kid property of the JWK provisioner. 49 | type: string 50 | name: 51 | description: Names is the name of the JWK provisioner. 52 | type: string 53 | passwordRef: 54 | description: PasswordRef is a reference to a Secret containing 55 | the provisioner password used to decrypt the provisioner private 56 | key. 57 | properties: 58 | key: 59 | description: The key of the secret to select from. Must be 60 | a valid secret key. 61 | type: string 62 | name: 63 | description: The name of the secret in the pod's namespace 64 | to select from. 65 | type: string 66 | required: 67 | - name 68 | type: object 69 | required: 70 | - kid 71 | - name 72 | - passwordRef 73 | type: object 74 | url: 75 | description: URL is the base URL for the step certificates instance. 76 | type: string 77 | required: 78 | - caBundle 79 | - provisioner 80 | - url 81 | type: object 82 | status: 83 | description: StepIssuerStatus defines the observed state of StepIssuer 84 | properties: 85 | conditions: 86 | items: 87 | description: StepIssuerCondition contains condition information 88 | for the step issuer. 89 | properties: 90 | lastTransitionTime: 91 | description: LastTransitionTime is the timestamp corresponding 92 | to the last status change of this condition. 93 | format: date-time 94 | type: string 95 | message: 96 | description: Message is a human readable description of the 97 | details of the last transition, complementing reason. 98 | type: string 99 | reason: 100 | description: Reason is a brief machine readable explanation 101 | for the condition's last transition. 102 | type: string 103 | status: 104 | allOf: 105 | - enum: 106 | - "True" 107 | - "False" 108 | - Unknown 109 | - enum: 110 | - "True" 111 | - "False" 112 | - Unknown 113 | description: Status of the condition, one of ('True', 'False', 114 | 'Unknown'). 115 | type: string 116 | type: 117 | description: Type of the condition, currently ('Ready'). 118 | enum: 119 | - Ready 120 | type: string 121 | required: 122 | - status 123 | - type 124 | type: object 125 | type: array 126 | type: object 127 | type: object 128 | served: true 129 | storage: true 130 | subresources: 131 | status: {} 132 | -------------------------------------------------------------------------------- /step-issuer/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | ⚙️ Thanks for installing step-issuer. 2 | 3 | step-issuer is ideal for issuing certificates 4 | from your own private Certificate Authority (CA). 5 | 6 | To start issuing certificates, you will need: 7 | 8 | 👉 A cert-manager installation 9 | 👉 A step-ca Certificate Authority (CA) or a Smallstep Certificate Manager authority 10 | 👉 A StepIssuer resource that links step-issuer to your CA 11 | 12 | To continue, follow the instructions here: 13 | 14 | https://u.step.sm/step-issuer 15 | 16 | -------------------------------------------------------------------------------- /step-issuer/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "step-issuer.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "step-issuer.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "step-issuer.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "step-issuer.labels" -}} 38 | helm.sh/chart: {{ include "step-issuer.chart" . }} 39 | {{ include "step-issuer.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end -}} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "step-issuer.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "step-issuer.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end -}} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "step-issuer.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create -}} 59 | {{ default (include "step-issuer.fullname" .) .Values.serviceAccount.name }} 60 | {{- else -}} 61 | {{ default "default" .Values.serviceAccount.name }} 62 | {{- end -}} 63 | {{- end -}} 64 | -------------------------------------------------------------------------------- /step-issuer/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: "{{ template "step-issuer.fullname" . }}" 5 | namespace: {{ .Release.Namespace }} 6 | labels: 7 | control-plane: {{ .Values.service.controlPlane }} 8 | {{- include "step-issuer.labels" . | nindent 4 }} 9 | spec: 10 | {{- if .Values.deployment.strategy }} 11 | strategy: {{ toYaml .Values.deployment.strategy | nindent 4 }} 12 | {{- end }} 13 | replicas: {{ .Values.replicaCount }} 14 | selector: 15 | matchLabels: 16 | control-plane: {{ .Values.service.controlPlane }} 17 | {{- include "step-issuer.selectorLabels" . | nindent 6 }} 18 | template: 19 | metadata: 20 | labels: 21 | control-plane: {{ .Values.service.controlPlane }} 22 | {{- include "step-issuer.labels" . | nindent 8 }} 23 | spec: 24 | {{- if $.Values.imagePullSecrets }} 25 | imagePullSecrets: 26 | {{- range $key := $.Values.imagePullSecrets }} 27 | - name: {{ $key }} 28 | {{- end }} 29 | {{- end }} 30 | {{- if .Values.serviceAccount.create }} 31 | serviceAccountName: {{ include "step-issuer.serviceAccountName" . }} 32 | {{- end }} 33 | containers: 34 | - image: "{{ .Values.kubeRBACproxy.image.repository }}:{{ .Values.kubeRBACproxy.image.tag }}" 35 | imagePullPolicy: {{ .Values.kubeRBACproxy.image.pullPolicy }} 36 | name: kube-rbac-proxy 37 | args: ["--secure-listen-address=0.0.0.0:8443", "--upstream=http://127.0.0.1:8080/", "--logtostderr=true", "--v=10"] 38 | ports: 39 | - containerPort: {{ .Values.service.port }} 40 | name: {{ .Values.service.targetPorts }} 41 | securityContext: 42 | {{- toYaml .Values.kubeRBACproxy.securityContext | nindent 10 }} 43 | - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 44 | imagePullPolicy: {{ .Values.image.pullPolicy }} 45 | name: manager 46 | args: [ 47 | "--metrics-addr=127.0.0.1:8080", 48 | {{- if .Values.deployment.args.enableLeaderElection }} 49 | "--enable-leader-election", 50 | {{- end }} 51 | {{- if .Values.deployment.args.disableApprovalCheck }} 52 | "--disable-approval-check", 53 | {{- end }} 54 | ] 55 | command: ["/manager"] 56 | securityContext: 57 | {{- toYaml .Values.securityContext | nindent 10 }} 58 | {{- if .Values.tunnel.enabled }} 59 | env: 60 | - name: STEP_TLS_TUNNEL 61 | value: /opt/config/tunnel.json 62 | {{- end }} 63 | resources: 64 | {{- toYaml .Values.resources | nindent 10 }} 65 | volumeMounts: 66 | {{- if .Values.tunnel.enabled }} 67 | # Tunnel configuration 68 | - name: tunnel-config 69 | mountPath: /opt/config 70 | readOnly: true 71 | - name: tunnel-tls 72 | mountPath: /opt/tunnel 73 | readOnly: true 74 | {{- end }} 75 | {{- with .Values.volumeMounts }} 76 | # Extra volumeMounts 77 | {{ toYaml . | indent 10 }} 78 | {{- end }} 79 | volumes: 80 | {{- if or .Values.tunnel.enabled }} 81 | # Tunnel configuration 82 | - name: tunnel-config 83 | configMap: 84 | name: {{ include "step-issuer.fullname" . }}-tunnel 85 | - name: tunnel-tls 86 | {{ toYaml .Values.tunnel.tlsCertsRef | indent 10 }} 87 | {{- end }} 88 | {{- with .Values.volumes }} 89 | # Extra volumes 90 | {{ toYaml . | indent 8 }} 91 | {{- end }} 92 | {{- with .Values.nodeSelector }} 93 | nodeSelector: 94 | {{- toYaml . | nindent 8 }} 95 | {{- end }} 96 | {{- with .Values.affinity }} 97 | affinity: 98 | {{- toYaml . | nindent 8 }} 99 | {{- end }} 100 | {{- with .Values.tolerations }} 101 | tolerations: 102 | {{- toYaml . | nindent 8 }} 103 | {{- end }} 104 | terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }} 105 | securityContext: 106 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 107 | -------------------------------------------------------------------------------- /step-issuer/templates/rbac/clusterRole.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: "{{ template "step-issuer.fullname" . }}-manager-role" 6 | rules: 7 | - apiGroups: [""] 8 | resources: ["events"] 9 | verbs: ["create", "patch"] 10 | - apiGroups: [""] 11 | resources: ["secrets"] 12 | verbs: ["get", "list", "watch"] 13 | - apiGroups: ["cert-manager.io"] 14 | resources: ["certificaterequests"] 15 | verbs: ["get", "list", "update", "watch"] 16 | - apiGroups: ["cert-manager.io"] 17 | resources: ["certificaterequests/status"] 18 | verbs: ["get", "patch", "update"] 19 | - apiGroups: ["certmanager.step.sm"] 20 | resources: ["stepissuers"] 21 | verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] 22 | - apiGroups: ["certmanager.step.sm"] 23 | resources: ["stepclusterissuers"] 24 | verbs: ["create", "delete", "get", "list", "patch", "update", "watch"] 25 | - apiGroups: ["certmanager.step.sm"] 26 | resources: ["stepissuers/status"] 27 | verbs: ["get", "patch", "update"] 28 | - apiGroups: ["certmanager.step.sm"] 29 | resources: ["stepclusterissuers/status"] 30 | verbs: ["get", "patch", "update"] 31 | - apiGroups: ["cert-manager.io"] 32 | resources: ["signers"] 33 | verbs: ["approve"] 34 | resourceNames: 35 | - stepissuers.certmanager.step.sm/* 36 | - stepclusterissuers.certmanager.step.sm/* 37 | - apiGroups: [ "coordination.k8s.io" ] 38 | resources: [ "leases" ] 39 | verbs: [ "create", "get", "list", "update" ] 40 | --- 41 | apiVersion: rbac.authorization.k8s.io/v1 42 | kind: ClusterRole 43 | metadata: 44 | name: "{{ template "step-issuer.fullname" . }}-proxy-role" 45 | rules: 46 | - apiGroups: ["authentication.k8s.io"] 47 | resources: ["tokenreviews"] 48 | verbs: ["create"] 49 | - apiGroups: ["authorization.k8s.io"] 50 | resources: ["subjectaccessreviews"] 51 | verbs: ["create"] 52 | --- 53 | apiVersion: rbac.authorization.k8s.io/v1 54 | kind: ClusterRole 55 | metadata: 56 | name: "{{ template "step-issuer.fullname" . }}-approver-role" 57 | rules: 58 | - apiGroups: 59 | - cert-manager.io 60 | resources: 61 | - signers 62 | verbs: 63 | - approve 64 | resourceNames: 65 | - stepissuers.certmanager.step.sm/* 66 | - stepclusterissuers.certmanager.step.sm/* 67 | -------------------------------------------------------------------------------- /step-issuer/templates/rbac/clusterRoleBinding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: "{{ template "step-issuer.fullname" . }}-manager-rolebinding" 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: "{{ template "step-issuer.fullname" . }}-manager-role" 10 | subjects: 11 | - kind: ServiceAccount 12 | name: {{ include "step-issuer.serviceAccountName" . }} 13 | namespace: {{ .Release.Namespace }} 14 | --- 15 | apiVersion: rbac.authorization.k8s.io/v1 16 | kind: ClusterRoleBinding 17 | metadata: 18 | name: "{{ template "step-issuer.fullname" . }}-proxy-rolebinding" 19 | roleRef: 20 | apiGroup: rbac.authorization.k8s.io 21 | kind: ClusterRole 22 | name: "{{ template "step-issuer.fullname" . }}-proxy-role" 23 | subjects: 24 | - kind: ServiceAccount 25 | name: {{ include "step-issuer.serviceAccountName" . }} 26 | namespace: {{ .Release.Namespace }} 27 | --- 28 | apiVersion: rbac.authorization.k8s.io/v1 29 | kind: ClusterRoleBinding 30 | metadata: 31 | name: "{{ template "step-issuer.fullname" . }}-approver-rolebinding" 32 | roleRef: 33 | apiGroup: rbac.authorization.k8s.io 34 | kind: ClusterRole 35 | name: "{{ template "step-issuer.fullname" . }}-approver-role" 36 | subjects: 37 | - kind: ServiceAccount 38 | name: {{ .Values.certManager.serviceAccount.name }} 39 | namespace: {{ .Values.certManager.serviceAccount.namespace }} 40 | -------------------------------------------------------------------------------- /step-issuer/templates/rbac/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: "{{ template "step-issuer.fullname" . }}-leader-election-role" 5 | namespace: {{ .Release.Namespace }} 6 | rules: 7 | - apiGroups: [""] 8 | resources: ["configmaps"] 9 | verbs: ["get" ,"list" ,"watch" ,"create" ,"update" ,"patch" ,"delete"] 10 | - apiGroups: [""] 11 | resources: ["configmaps/status"] 12 | verbs: ["get", "update", "patch"] 13 | - apiGroups: [""] 14 | resources: ["events"] 15 | verbs: ["create"] 16 | - apiGroups: ["coordination.k8s.io"] 17 | resources: ["leases"] 18 | verbs: ["get", "create", "update"] 19 | -------------------------------------------------------------------------------- /step-issuer/templates/rbac/roleBinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: "{{ template "step-issuer.fullname" . }}-leader-election-rolebinding" 5 | namespace: {{ .Release.Namespace }} 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: Role 9 | name: "{{ template "step-issuer.fullname" . }}-leader-election-role" 10 | subjects: 11 | - kind: ServiceAccount 12 | name: {{ include "step-issuer.serviceAccountName" . }} 13 | namespace: {{ .Release.Namespace }} -------------------------------------------------------------------------------- /step-issuer/templates/rbac/sa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "step-issuer.serviceAccountName" . }} 6 | labels: 7 | {{- include "step-issuer.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} -------------------------------------------------------------------------------- /step-issuer/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: "{{ template "step-issuer.fullname" . }}" 5 | namespace: {{ .Release.Namespace }} 6 | annotations: 7 | prometheus.io/port: "{{ .Values.service.scrapePort }}" 8 | prometheus.io/scheme: "{{ .Values.service.targetPorts }}" 9 | prometheus.io/scrape: "{{ .Values.service.scrape }}" 10 | labels: 11 | control-plane: {{ .Values.service.controlPlane }} 12 | {{- include "step-issuer.labels" . | nindent 4 }} 13 | spec: 14 | ports: 15 | - name: {{ .Values.service.targetPorts }} 16 | port: {{ .Values.service.port }} 17 | targetPort: {{ .Values.service.targetPorts }} 18 | selector: 19 | {{- include "step-issuer.selectorLabels" . | nindent 4 }} 20 | control-plane: {{ .Values.service.controlPlane }} 21 | -------------------------------------------------------------------------------- /step-issuer/templates/stepclusterissuer.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.stepClusterIssuer.create }} 2 | apiVersion: certmanager.step.sm/v1beta1 3 | kind: StepClusterIssuer 4 | metadata: 5 | name: "{{ template "step-issuer.fullname" . }}" 6 | spec: 7 | # The CA URL. 8 | {{- if .Values.stepClusterIssuer.caUrl }} 9 | url: {{ .Values.stepClusterIssuer.caUrl }} 10 | {{- else }} 11 | url: https://step-certificates.{{ .Release.Namespace }}.svc.cluster.local 12 | {{- end }} 13 | # The base64 encoded version of the CA root certificate in PEM format. 14 | caBundle: {{ .Values.stepClusterIssuer.caBundle }} 15 | # The provisioner name, kid, and a reference to the provisioner password secret. 16 | provisioner: 17 | name: {{ .Values.stepClusterIssuer.provisioner.name }} 18 | kid: {{ .Values.stepClusterIssuer.provisioner.kid }} 19 | passwordRef: 20 | name: {{ .Values.stepClusterIssuer.provisioner.passwordRef.name }} 21 | namespace: {{ .Values.stepClusterIssuer.provisioner.passwordRef.namespace }} 22 | key: {{ .Values.stepClusterIssuer.provisioner.passwordRef.key }} 23 | {{- end }} -------------------------------------------------------------------------------- /step-issuer/templates/stepissuer.yml: -------------------------------------------------------------------------------- 1 | {{- if .Values.stepIssuer.create }} 2 | apiVersion: certmanager.step.sm/v1beta1 3 | kind: StepIssuer 4 | metadata: 5 | name: "{{ template "step-issuer.fullname" . }}" 6 | namespace: {{ .Release.Namespace }} 7 | spec: 8 | # The CA URL. 9 | {{- if .Values.stepIssuer.caUrl }} 10 | url: {{ .Values.stepIssuer.caUrl }} 11 | {{- else }} 12 | url: https://step-certificates.{{ .Release.Namespace }}.svc.cluster.local 13 | {{- end }} 14 | # The base64 encoded version of the CA root certificate in PEM format. 15 | caBundle: {{ .Values.stepIssuer.caBundle }} 16 | # The provisioner name, kid, and a reference to the provisioner password secret. 17 | provisioner: 18 | name: {{ .Values.stepIssuer.provisioner.name }} 19 | kid: {{ .Values.stepIssuer.provisioner.kid }} 20 | passwordRef: 21 | name: {{ .Values.stepIssuer.provisioner.passwordRef.name }} 22 | key: {{ .Values.stepIssuer.provisioner.passwordRef.key }} 23 | {{- end }} -------------------------------------------------------------------------------- /step-issuer/templates/tunnel.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.tunnel.enabled }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "step-issuer.fullname" . }}-tunnel 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "step-issuer.labels" . | nindent 4 }} 9 | data: 10 | tunnel.json: |- 11 | { 12 | "type": "tTLS", 13 | "crt": "{{ .Values.tunnel.crt }}", 14 | "key": "{{ .Values.tunnel.key }}", 15 | "host": "{{ .Values.tunnel.host }}", 16 | "root": "{{ .Values.tunnel.root }}" 17 | } 18 | {{- end }} -------------------------------------------------------------------------------- /step-issuer/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for step-issuer. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: cr.step.sm/smallstep/step-issuer 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | kubeRBACproxy: 14 | image: 15 | repository: gcr.io/kubebuilder/kube-rbac-proxy 16 | pullPolicy: IfNotPresent 17 | tag: v0.15.0 18 | # security context for container 19 | securityContext: 20 | runAsUser: 1000 21 | runAsGroup: 1000 22 | # seccompProfile: 23 | # type: RuntimeDefault 24 | 25 | # List of secret keys used to pull images from private registries. 26 | imagePullSecrets: [] 27 | nameOverride: "" 28 | fullnameOverride: "" 29 | 30 | deployment: 31 | # Configure arguments to pass to the step issuer 32 | args: 33 | enableLeaderElection: true 34 | disableApprovalCheck: false 35 | terminationGracePeriodSeconds: 10 36 | # Strategy used for the deployment 37 | strategy: {} 38 | 39 | resources: 40 | limits: 41 | cpu: 100m 42 | memory: 128Mi 43 | requests: 44 | cpu: 100m 45 | memory: 50Mi 46 | 47 | service: 48 | type: ClusterIP 49 | port: 8443 50 | targetPorts: https 51 | controlPlane: controller-manager 52 | scrape: true 53 | scrapePort: 8080 54 | 55 | # Security Context for the pod 56 | podSecurityContext: {} 57 | # fsGroup: 2000 58 | 59 | # security context for container 60 | securityContext: 61 | runAsUser: 1000 62 | runAsGroup: 1000 63 | # seccompProfile: 64 | # type: RuntimeDefault 65 | 66 | serviceAccount: 67 | # Specifies whether a service account should be created 68 | create: false 69 | # Annotations to add to the service account 70 | annotations: {} 71 | # The name of the service account to use. 72 | # If not set and create is true, a name is generated using the fullname template 73 | name: "" 74 | 75 | # mandatory values to generate stepIssuer resource 76 | # please follow the https://github.com/smallstep/step-issuer#getting-started to setup step-ca and get step-issuer values 77 | stepIssuer: 78 | create: false 79 | caUrl: "" 80 | caBundle: "" 81 | provisioner: 82 | name: "" 83 | kid: "" 84 | passwordRef: 85 | name: "" 86 | key: "" 87 | 88 | # mandatory values to generate stepClusterIssuer resource 89 | # please follow the https://github.com/smallstep/step-issuer#getting-started to setup step-ca and get step-issuer values 90 | stepClusterIssuer: 91 | create: false 92 | caUrl: "" 93 | caBundle: "" 94 | provisioner: 95 | name: "" 96 | kid: "" 97 | passwordRef: 98 | name: "" 99 | namespace: "" 100 | key: "" 101 | 102 | # For the cert-manager approver 103 | certManager: 104 | serviceAccount: 105 | name: cert-manager 106 | namespace: cert-manager 107 | 108 | # Experimental support for the TLS-over-TLS tunnel in the step-ca client. 109 | # Do not enable this unless you know what to use. 110 | tunnel: 111 | enabled: false 112 | crt: "/opt/tunnel/tls.crt" 113 | key: "/opt/tunnel/tls.key" 114 | host: "" # host:port 115 | root: "/opt/tunnel/ca.crt" 116 | tlsCertsRef: 117 | secret: 118 | secretName: "" 119 | 120 | # Configure extra volumes and volume mounts as YAML expressions. 121 | volumes: false 122 | volumeMounts: false 123 | 124 | # nodeSelector contains the node labels for pod assignment. 125 | nodeSelector: {} 126 | 127 | # tolerations contains the toleration labels for pod assignment. 128 | tolerations: [] 129 | 130 | # affinity contains the affinity settings for pod assignment. 131 | affinity: {} 132 | --------------------------------------------------------------------------------