diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f49a4e1..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/fr/index.html b/fr/index.html index 003297e..89b40d9 100644 --- a/fr/index.html +++ b/fr/index.html @@ -1053,7 +1053,7 @@

Getting Started

Contributing

We welcome contributions from the community! Please see our Contribution Guidelines for more information on how to get involved.

License

-

This project is licensed under the terms of the MIT license. See the LICENSE file for details.

+

This project is licensed under the terms of the Apache-2.0 license. See the LICENSE file for details.

Contact

For any questions or support, please reach out to our team at directly by creating an issue on the project.

diff --git a/index.html b/index.html index 0bdc4d4..f027743 100644 --- a/index.html +++ b/index.html @@ -1053,7 +1053,7 @@

Getting Started

Contributing

We welcome contributions from the community! Please see our Contribution Guidelines for more information on how to get involved.

License

-

This project is licensed under the terms of the MIT license. See the LICENSE file for details.

+

This project is licensed under the terms of the Apache-2.0 license. See the LICENSE file for details.

Contact

For any questions or support, please reach out to our team at directly by creating an issue on the project.

diff --git a/search/search_index.json b/search/search_index.json index 9cf5cf1..c65849d 100644 --- a/search/search_index.json +++ b/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en","fr"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Vault DB Injector","text":""},{"location":"#overview","title":"Overview","text":"

The Vault DB Injector is a Kubernetes-based application designed to dynamically generate database credentials using HashiCorp Vault and provide them as environment variables to Kubernetes Pods. The application leverages a Mutating Webhook to achieve this functionality, ensuring secure and automated management of database credentials.

"},{"location":"#key-features","title":"Key Features","text":""},{"location":"#1-dynamic-database-credential-injection","title":"1. Dynamic Database Credential Injection","text":""},{"location":"#2-mutating-webhook","title":"2. Mutating Webhook","text":""},{"location":"#3-configuration-management","title":"3. Configuration Management","text":""},{"location":"#4-error-monitoring-with-sentry","title":"4. Error Monitoring with Sentry","text":""},{"location":"#5-logging","title":"5. Logging","text":""},{"location":"#6-kubernetes-integration","title":"6. Kubernetes Integration","text":""},{"location":"#7-leader-election","title":"7. Leader Election","text":""},{"location":"#8-health-checks","title":"8. Health Checks","text":""},{"location":"#9-prometheus-metrics","title":"9. Prometheus Metrics","text":""},{"location":"#getting-started","title":"Getting Started","text":"

To get started with Vault DB Injector, refer to the Installation Guide and Configuration Guide for detailed instructions on setting up and configuring the application.

For a deeper understanding of how the application works, visit the How It Works section.

"},{"location":"#contributing","title":"Contributing","text":"

We welcome contributions from the community! Please see our Contribution Guidelines for more information on how to get involved.

"},{"location":"#license","title":"License","text":"

This project is licensed under the terms of the MIT license. See the LICENSE file for details.

"},{"location":"#contact","title":"Contact","text":"

For any questions or support, please reach out to our team at directly by creating an issue on the project.

"},{"location":"getting-started/build/","title":"Build","text":""},{"location":"getting-started/build/#build","title":"Build","text":"

Requirements for building

A Makefile is provided for building tasks. The options are as follows

Getting started is as simple as:

go get -u github.com/numberly/vault-db-injector\ncd $GOPATH/src/github.com/numberly/vault-db-injector\nmake setup\nmake\n
"},{"location":"getting-started/getting-started/","title":"getting-started","text":""},{"location":"getting-started/getting-started/#1-requirements","title":"1. Requirements","text":"

To work correctly, the vault db injector need the following :

In this documentation, we assume that both of those following requirements are already installed.

"},{"location":"getting-started/getting-started/#2-vocabulary","title":"2. Vocabulary","text":"

Here are some vocabulary that you need before starting the installation.

name description default K/V Vault Vault KVv2 path for injector state vault-injector vault policy Vault Injector policy to work properly all-rw vault databases mount Vault database engine used to connect to our database databases vault databases backend connection Vault databases backend connection where we allow role to generate credentials rw-pgsql2-pr vault databases backend role Vault databases role used to allow application on specific database test-role kubernetes auth backend Vault Backend used by Kubernetes Application to authenticate under Vault kubernetes kubernetes auth backend role Vault Backend Role used by injector to authenticate under Vault all-rw postgresql Database engine used to connecte under vault rw-pgsql2-pr database database name to connect into test"},{"location":"getting-started/getting-started/#3-vault-configuration","title":"3. Vault Configuration","text":"

First, we need to configure Vault to allow the injector to generate credentials on the databases engine and to store them inside the dedicated K/V Vault.

"},{"location":"getting-started/getting-started/#31-create-all-rw-vault-policy","title":"3.1. Create all-rw vault-policy","text":"

We are going to start by create the all-rw vault policy that the injector will use :

path \"vault-injector/*\" {\n  capabilities = [\"read\", \"list\", \"update\", \"create\", \"delete\", \"sudo\"]\n}\npath \"vault-injector/data/*\" {\n  capabilities = [\"read\", \"list\", \"update\", \"create\", \"delete\", \"sudo\"]\n}\npath \"vault-injector/metadata/*\" {\n  capabilities = [\"read\", \"list\", \"update\", \"create\", \"delete\", \"sudo\"]\n}\npath \"rw-pgsql2-pr/creds/*\" {\n  capabilities = [\"read\"]\n}\npath \"auth/kubernetes/role/*\" {\n  capabilities = [\"read\"]\n}\npath \"sys/leases/renew\" {\n  capabilities = [\"create\"]\n}\npath \"auth/token/renew-self\" {\n  capabilities = [\"create\"]\n}\npath \"auth/token/renew\" {\n  capabilities = [\"create\", \"update\"]\n}\npath \"auth/token/revoke\" {\n  capabilities = [\"create\", \"update\"]\n}\npath \"auth/token/create\" {\n  capabilities = [\"create\", \"update\", \"read\"]\n}\npath \"auth/token/create-orphan\" {\n  capabilities = [\"create\", \"update\", \"read\", \"sudo\"]\n}\npath \"auth/token/revoke-orphan\" {\n  capabilities = [\"create\", \"update\", \"sudo\"]\n}\n
"},{"location":"getting-started/getting-started/#32-create-kv-vault","title":"3.2. Create K/V Vault","text":"

We need to create the K/V Vault in version v2 named vault-injector.

You can use the following documentation : vault-injector

"},{"location":"getting-started/getting-started/#33-create-vault-databases-mount","title":"3.3. Create vault databases mount","text":"

We need to create a vault databases mount engine named databases.

Here is a terraform example :

resource \"vault_mount\" \"databases\" {\n  path                  = \"databases\"\n  type                  = \"database\"\n  description           = \"databases authentication automation\"\n  max_lease_ttl_seconds = \"31536000\"\n}\n

"},{"location":"getting-started/getting-started/#34-create-vault-databases-backend-connection","title":"3.4. Create vault databases backend connection","text":"

We need to create a vault databases backend connection on the vault databases engine. As you can see below, we allow the test-role role.

Here is a terraform example :

resource \"vault_database_secret_backend_connection\" \"pgsql2\" {\n  backend = vault_mount.databases.path\n  name    = \"pgsql2\"\n  allowed_roles = [\n    \"test-role\",\n  ]\n\n  postgresql {\n    connection_url    = \"postgres://{{username}}:{{password}}@rw-pgsql2-pr:5432/postgres?sslmode=verify-full\"\n    username          = \"postgres\"\n    password          = \"my-password\"\n    username_template = \"{{.RoleName}}-{{unix_time}}-{{random 8}}\"\n  }\n}\n

"},{"location":"getting-started/getting-started/#35-create-a-kubernetes-auth-backend","title":"3.5. Create a kubernetes auth backend","text":"

We need to create a kubernetes auth backend to allow serviceAccount to connect under Vault.

You can use the following documentation : kubernetes

"},{"location":"getting-started/getting-started/#36-create-a-kubernetes-auth-backend-role","title":"3.6. Create a kubernetes auth backend role","text":"

We need to create a kubernetes auth backend role to allow the service account of the vault-db-injector to connect under Vault.

Here is a terraform example :

resource \"vault_kubernetes_auth_backend_role\" \"all_rw\" {\n  backend                          = \"kubernetes\"\n  role_name                        = \"all-rw\"\n  bound_service_account_names      = [\"vault-db-injector\"]\n  bound_service_account_namespaces = [\"vault-db-injector\"]\n  token_ttl                        = 3600\n  token_policies                   = [vault_policy.all_rw.name] # remember the one created before\n  token_bound_cidrs                = [\"10.17.0.0/16\"] # Your pod CIDR\n}\n

We need to create a kubernetes auth backend role to allow the service account of our application to get generated credentials from vault Here is a terraform example :

resource \"vault_policy\" \"policy\" {\n  provider = vault.main\n  name     = var.service_account\n\n  policy = <<EOT\npath \"pgsql2/creds/test-role\" {\n  capabilities = [\"read\"]\n}\nEOT\n}\n\nresource \"vault_kubernetes_auth_backend_role\" \"role\" {\n  provider                         = vault.main\n  backend                          = kubernetes\n  role_name                        = \"test\"\n  bound_service_account_names      = [\"test\"]\n  bound_service_account_namespaces = [\"test\"]\n  token_ttl                        = 3600\n  token_policies                   = [vault_policy.policy.name]\n  token_bound_cidrs                = [\"10.17.0.0/16\"]\n}\n

"},{"location":"getting-started/getting-started/#37-create-vault-databases-backend-role","title":"3.7. Create vault databases backend role","text":"

We need to create a vault databases backend role to allow our application to consume vault databases backend connection

Here is a terraform example :

resource \"vault_database_secret_backend_role\" \"role\" {\n  provider    = vault.main\n  backend     = \"databases\"\n  name        = test-role\n  db_name     = test\n  default_ttl = 3600\n  creation_statements = [\n    \"CREATE ROLE \\\"{{name}}\\\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}' IN ROLE \\\"test\\\";\",\n    \"ALTER ROLE \\\"{{name}}\\\" SET ROLE \\\"test\\\";\",\n  ]\n  revocation_statements = [\n    \"DROP ROLE \\\"{{name}}\\\";\"\n  ]\n}\n
"},{"location":"getting-started/getting-started/#4-database-configuration","title":"4. Database configuration","text":"

You need to create you database under postgres, here is an example for postgres :

CREATE DATABASE test;\nCREATE ROLE test;\nrevoke all on database test from public cascade;\ngrant connect on database test to test;\n\\c test\ngrant create, usage on schema public to test;\ngrant temporary on database test to test;\nALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO test;\nREVOKE ALL ON pg_user FROM public;\nREVOKE ALL ON pg_roles FROM public;\nREVOKE ALL ON pg_group FROM public;\nREVOKE ALL ON pg_authid FROM public;\nREVOKE ALL ON pg_auth_members FROM public;\nREVOKE ALL ON pg_database FROM public;\nREVOKE ALL ON pg_tablespace FROM public;\nREVOKE ALL ON pg_settings FROM public;\n
"},{"location":"getting-started/getting-started/#5-deploy-the-vault-db-injector","title":"5. Deploy the vault db injector","text":"

Now that you have a vault correctly configured and a database ready to be used, we can deploy our vault-db-injector application :

For this, its quit easy, you just need to use the help chart.

kubectl create namespace vault-db-injector\nhelm upgrade --install vault-db-injector . --namespace vault-db-injector\n

When everything is Okay, you should have something like this :

NAME                                         READY   STATUS    RESTARTS   AGE\nvault-db-injector-7f74977b7c-88vvg           1/1     Running   0          29s\nvault-db-injector-7f74977b7c-rq6mt           1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-77skb    1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-96zz4    1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-tdp4r    1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-wpd8x    1/1     Running   0          29s\nvault-db-injector-revoker-7965857f75-2m5qp   1/1     Running   0          28s\nvault-db-injector-revoker-7965857f75-5msv6   1/1     Running   0          29s\nvault-db-injector-revoker-7965857f75-n29wp   1/1     Running   0          29s\nvault-db-injector-revoker-7965857f75-th9vs   1/1     Running   0          28s\n

"},{"location":"getting-started/getting-started/#6-deploy-an-example-application","title":"6. Deploy an example application :","text":"

Here is an example application deploy on the namespace test that will connect to our database test with the service account test.

apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: test\n  namespace: test\n---\napiVersion: v1\nkind: Pod\nmetadata:\n  annotations:\n    db-creds-injector.numberly.io/test.env-key-uri: POSTGRES_URL\n    db-creds-injector.numberly.io/test.template: postgresql://@rw-pgsql2-pr:5432/test?sslmode=require\n    db-creds-injector.numberly.io/test.mode: uri\n    db-creds-injector.numberly.io/test.role: test-role\n  labels:\n    client: numberly\n    vault-db-injector: \"true\"\n  name: test\n  namespace: test\nspec:\n  containers:\n  - image: postgres:15.5\n    command: [\"/bin/bash\", \"-c\"]\n    args: [\"sleep 3000000\"]\n    name: test\n    resources: {}\n    securityContext:\n      allowPrivilegeEscalation: false\n      capabilities:\n        drop:\n        - ALL\n      readOnlyRootFilesystem: true\n      runAsNonRoot: true\n      runAsUser: 65534\n  dnsPolicy: ClusterFirst\n  restartPolicy: Always\n  serviceAccount: test\n  serviceAccountName: test\n

To deploy it :

kubectl apply -f test.yaml\n

Wait until your application is ready and you should be able to exec inside the pods and connect to the database.

"},{"location":"how-it-works/configuration/","title":"Configuration","text":"
* 1. [Configuration](#Configuration)\n    * 1.1. [Mode Injector](#ModeInjector)\n    * 1.2. [Mode token-renewer](#Modetoken-renewer)\n    * 1.3. [Mode token-renewer](#Modetoken-renewer-1)\n

Here is the configuration for Vault Injector:

"},{"location":"how-it-works/configuration/#11-mode-injector","title":"1.1. Mode Injector","text":"

The Injector mode is basic one that will handle all api-server request and handle all requests to vault to generate credentials to our DB The config file path can be parse by adding the path with : - \"--config=/injector/config.yaml\"

certFile: /tls/tls.crt\nkeyFile: /tls/tls.key\nvaultAddress: https://vault1.tld:8200\nvaultAuthPath: pgsql2-dv-kubernetes1-dv-par5\nlogLevel: info\nkubeRole: all-rw\ntokenTTL: 768h\nvaultSecretName: vault-injector\nvaultSecretPrefix: kubernetes1-dv-par5\nmode: injector\nsentry: true\nsentryDsn: https://my-sentry-url@sentry.tld/660\ninjectorLabel: vault-db-injector\ndefaultEngine: databases\n

"},{"location":"how-it-works/configuration/#12-mode-token-renewer","title":"1.2. Mode token-renewer","text":"

The Renewer one is a process that will run every hour and validate that all orphan token won't expire before pod is deleted The config file path can be parse by adding the path with : - \"--config=/renewer/config.yaml\"

vaultAddress: https://vault1.tld:8200\nvaultAuthPath: pgsql2-dv-kubernetes1-dv-par5\nlogLevel: info\nkubeRole: all-rw\ntokenTTL: 768h\nvaultSecretName: vault-injector\nvaultSecretPrefix: kubernetes1-dv-par5\nmode: renewer\nsentry: true\nsentryDsn: https://my-sentry-url@sentry.tld/660\nSyncTTLSecond: 300\ninjectorLabel: vault-db-injector\ndefaultEngine: databases\n

"},{"location":"how-it-works/configuration/#13-mode-token-renewer","title":"1.3. Mode token-renewer","text":"

The Revoker one is a process that is going to watch pod deletion Kubernetes events filtered with the label vault-db-injector: true and will revoke token attached to the pod when it is deleted The config file path can be parse by adding the path with : - \"--config=/revoker/config.yaml\"

vaultAddress: https://vault1.tld:8200\nvaultAuthPath: pgsql2-dv-kubernetes1-dv-par5\nlogLevel: info\nkubeRole: all-rw\ntokenTTL: 768h\nvaultSecretName: vault-injector\nvaultSecretPrefix: kubernetes1-dv-par5\nmode: revoker\nsentry: true\nsentryDsn: https://my-sentry-url@sentry.tld/660\ninjectorLabel: vault-db-injector\ndefaultEngine: databases\n

"},{"location":"how-it-works/healthcheck/","title":"Health Checks","text":"

Key File: pkg/healthcheck/healthcheck.go

"},{"location":"how-it-works/healthcheck/#1-how-it-works","title":"1. How It Works:","text":"

Health Checks are a crucial feature that monitors the application's status and readiness, ensuring it is functioning correctly and is ready to handle requests. This feature provides endpoints that external systems can query to check the health and readiness of the application.

"},{"location":"how-it-works/healthcheck/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Health Check Endpoints:
  2. The application exposes HTTP endpoints for health (/healthz) and readiness (/readyz). These endpoints provide information about the application's operational status.

  3. Regular Monitoring:

  4. The health check service regularly monitors the internal state of the application and updates the health and readiness status accordingly.

  5. Integration with Kubernetes:

  6. In a Kubernetes environment, these health check endpoints are used by Kubernetes to manage the application's lifecycle. Kubernetes can restart pods that fail health checks, ensuring continuous availability.
"},{"location":"how-it-works/healthcheck/#3-benefits","title":"3. Benefits:","text":""},{"location":"how-it-works/how-it-work/","title":"How it Work","text":""},{"location":"how-it-works/how-it-work/#1-vault-injector","title":"1. Vault-Injector","text":"

The Vault DB Injector is a Go program that is design to retrieve databases credentials from Hashicorp Vault, it use Kubernetes Mutating Webhook to intercept pod creation activated with a label and configured with annotations. After the credentials are provided, it will store them in a specific Vault KV and will handle the lifecycle of them such as : - Renew them periodically - Revoke them after the pod is deleted

"},{"location":"how-it-works/how-it-work/#11-mechanism","title":"1.1. Mechanism","text":""},{"location":"how-it-works/how-it-work/#111-vault-injector","title":"1.1.1. Vault Injector:","text":"
  1. Connects to Vault to generate credentials.
  2. Vault will create a temporary role in PostgreSQL for the database.
  3. Retrieves the credentials via Vault.
  4. Modifies the pod by adding the credentials in the form of environment variables.
  5. The pod can now connect to the database.
  6. Handle token / lease renewing and revokation.
"},{"location":"how-it-works/how-it-work/#12-diagram","title":"1.2. Diagram","text":""},{"location":"how-it-works/how-it-work/#13-vault-usage","title":"1.3. Vault Usage","text":"

Their is also a fonctionnality that permit to rotate token directly from the injector. Objectif is to keep token as secure as possible. For this purpose, we have made the choice to store the token directly on Vault in a specific KV. We provide a generated random UUID to every pod which will be use as a unique identifier. As long as the pod is alive, the injector will rotate his token 5 minutes by default. If the pods is deleted, the revoker will revoke the token and the lease and the renewer which is design to keep the state will also delete the secret in the KV.

If the injector reboot or fail for any reason, the token can stil be renewed manually or by restarting the injector correctly. He can retrieve all token that was created previously. The renewer will renew all tokens and leases every 5 minutes by default.

We are using periodic token for this purpose which need absolutely \"sudo\" policy. Periodic token permit to add a max_ttl and to have infinite token that can be renewed until the pod is deleted. Token TTL permit to fix the max_ttl of the token which mean : \"How many time my token can belong without been renewed.\" By default, if the token is not renewed, hes timelife is 32 days, that mean, if the injector fail, you have 31 days and 23 hours before all your token will expire, which i think is enough to understand why and repair it to a working state.

With this setup, the advantage is that now, vault is the only real SPOF. The Injector in renewer mode will only renew TOKEN and LEASE and cleanup KV/STORE that has been created by the Injector. The Injector in revoker mode will only revoke TOKEN when a pod has been deleted If the revoker fail to revoke a Token, the renewer can do it periodically every 5 minutes (This will be probably removed in future version.)

"},{"location":"how-it-works/how-it-work/#14-authentication","title":"1.4. Authentication","text":"

It uses a service account and the Kubernetes mount point to retrieve and generate its information. It then sends the following information to the application:

It will store on a specific vault KV/Store the following :

"},{"location":"how-it-works/how-it-work/#15-how-token-are-handled","title":"1.5. How token are handled ?","text":"

They are two kind of token that are created in the lifecycle of the Vault injector :

  1. Token created for the Injector using kubeRole: in the yaml config
  2. Permit to generate OrphanToken for our pods that will access to DB
  3. Permit to renew and revoke all the OrphanToken
  4. Permit to store data token inside the KV from vaultSecretName: vault-injector and prefix : vaultSecretPrefix: kubernetes1-dv-par5
  5. TTL is 1h but will always be revoked after the tasks is completed.
  6. This token will be revoked after the webhook is generated.
  7. OrphanToken created on a webhook request which are stored on Vault with the pods UUID and configured by annotation db-creds-injector.numberly.io/role: and db-creds-injector.numberly.io/dbname.role:
  8. Permit to generate the LeaseId that will be provided to the pod
  9. Permit to generate the DB credentials
  10. Will be revoked when the pod is deleted
  11. Is a periodic token with TTL : tokenTTL: 768h
"},{"location":"how-it-works/how-it-work/#16-how-does-injector-work-then","title":"1.6. How does injector work then ?","text":"
  1. A new pod is created with label vault-db-injector: \"true\", annotations db-creds-injector.numberly.io/cluster: & db-creds-injector.numberly.io/role: and a serviceaccount
  2. The api-server use mutating-webhook to send the pods template to the injector
  3. The injector will generate a new orphan token and do thoses steps :
  4. Does the serviceaccount attached to my pod is allowed to assume my role on Vault. If the SA or the namespace is no't allowed, it will return an error, else, it will continue the process.
  5. Generate a new orphan token with a specific period and the policy provided in the annotation by the pod.
  6. Generate an UUID and add a specific annotation on the pod with IT
  7. Ask vault to generate DB Credentials for the pods with the new Orphan Token
  8. Store on vault on the specific KV the LeaseId, TokenId, namespace in a folder named with the pod UUID
  9. Revoke all intermediate Token
  10. The injector will return back to the api-server with a modified pod template
  11. The api-server will create the new pods with modified informations

The available annotations can be declare like this :

"},{"location":"how-it-works/how-it-work/#17-usage","title":"1.7. Usage :","text":""},{"location":"how-it-works/how-it-work/#171-in-mode-classic","title":"1.7.1. In mode classic","text":"
# To be added in the pod spec\nannotations:\n  db-creds-injector.numberly.io/cluster: databases\n  db-creds-injector.numberly.io/dbname.env-key-dbpassword: DB_PASSWORD\n  db-creds-injector.numberly.io/dbname.env-key-dbuser: DB_USER\n  db-creds-injector.numberly.io/dbname.role: db-role # the one created from vault with terraform\n  db-creds-injector.numberly.io/dbname.mode: classic\nlabels:\n  vault-db-injector: \"true\"\n
"},{"location":"how-it-works/how-it-work/#172-in-mode-uri","title":"1.7.2. In mode URI","text":"
annotations:\n  db-creds-injector.numberly.io/cluster: databases\n  db-creds-injector.numberly.io/dbname.template: postgres://@postgres-server.tld:5432/dbname?sslmode=require\n  db-creds-injector.numberly.io/dbname.role: db-role\n  db-creds-injector.numberly.io/dbname.env-key-uri: POSTGRES_URL\n  db-creds-injector.numberly.io/dbname.mode: uri\nlabels:\n  vault-db-injector: \"true\"\n
"},{"location":"how-it-works/how-it-work/#173-with-multiple-databases","title":"1.7.3. With multiple databases","text":"

annotations:\n  db-creds-injector.numberly.io/cluster: databases\n  db-creds-injector.numberly.io/dbname.env-key-dbpassword: DB_PASSWORD\n  db-creds-injector.numberly.io/dbname.env-key-dbuser: DB_USER\n  db-creds-injector.numberly.io/dbname.role: db-role # the one created from vault with terraform\n  db-creds-injector.numberly.io/dbname.mode: classic\n  db-creds-injector.numberly.io/other_dbname.template: postgres://@postgres-server.tld:5432/dbname?sslmode=require\n  db-creds-injector.numberly.io/other_dbname.role: another-vault-role\n  db-creds-injector.numberly.io/other_dbname.env-key-uri: POSTGRES_URL,ANOTHER_ENV\n  db-creds-injector.numberly.io/other_dbname.mode: uri\nlabels:\n  vault-db-injector: \"true\"\n
Here, as you can see, we can connect to 2 databases dbname and other_dbname.

"},{"location":"how-it-works/injector/","title":"Injector","text":"

Key File: pkg/injector/injector.go

"},{"location":"how-it-works/injector/#1-how-it-works","title":"1. How It Works:","text":"

The injector is responsible for injecting database credentials into Kubernetes Pods using a Mutating Admission Webhook.

"},{"location":"how-it-works/injector/#2-benefits","title":"2. Benefits:","text":""},{"location":"how-it-works/kubernetes/","title":"Kubernetes Integration","text":"

Key Files: pkg/k8s/connect.go, pkg/k8s/pod_utils.go, pkg/k8s/parse_annotations.go

"},{"location":"how-it-works/kubernetes/#1-how-it-works","title":"1. How It Works:","text":"

Kubernetes Integration is a fundamental feature that enables the application to interact with the Kubernetes API. This integration allows the application to manage and manipulate Kubernetes resources, facilitating tasks such as credential injection, pod management, and more.

"},{"location":"how-it-works/kubernetes/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Kubernetes Client Initialization:
  2. The application initializes a Kubernetes client that can interact with the Kubernetes API. This client is used to perform various operations such as reading pod annotations, accessing secrets, and more.

  3. Service Account Token Retrieval:

  4. The application retrieves the service account token from the Kubernetes environment. This token is used for authenticating API requests made by the application.

  5. CA Certificate Retrieval:

  6. The application retrieves the Kubernetes CA certificate. This certificate is used to establish secure communication with the Kubernetes API server.

  7. Pod Annotation Parsing:

  8. The application reads and parses annotations from Kubernetes pods. These annotations can include instructions for credential injection and other custom configurations.
"},{"location":"how-it-works/kubernetes/#3-benefits","title":"3. Benefits:","text":""},{"location":"how-it-works/kubernetes/#31-annotations","title":"3.1. Annotations :","text":"

Each injector annotation are read by the Injector pod and permit to configure properly how Database Credetials need to be handled.

"},{"location":"how-it-works/leaderelection/","title":"Leader Election","text":"

Key File: pkg/leadership/leadership.go

"},{"location":"how-it-works/leaderelection/#1-how-it-works","title":"1. How It Works:","text":"

Leader Election is a mechanism that ensures high availability and fault tolerance by designating a single instance of the application to perform critical tasks at any given time. This feature is particularly important in distributed systems where multiple instances of an application might be running concurrently.

"},{"location":"how-it-works/leaderelection/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Resource Locking:
  2. Leader Election uses Kubernetes resource locks to manage which instance of the application is the current leader. The application instances compete for a lock, and the one that acquires it becomes the leader.

  3. Performing Critical Tasks:

  4. The leader is responsible for performing tasks that should not be duplicated. These tasks could include credential renewal, revocation, and other maintenance activities that need to be managed centrally.

  5. Failover Handling:

  6. If the current leader fails or goes offline, another instance of the application can take over by acquiring the lock. This ensures continuous operation and minimal downtime for critical tasks.
"},{"location":"how-it-works/leaderelection/#3-benefits","title":"3. Benefits:","text":"

This feature is essential for applications deployed in Kubernetes clusters, where ensuring that critical tasks are managed by a single, designated instance enhances both reliability and performance.

"},{"location":"how-it-works/renewer/","title":"Renewer","text":"

Key File: pkg/renewer/renewer.go

"},{"location":"how-it-works/renewer/#1-how-it-works","title":"1. How It Works:","text":"

The Renewer is a crucial component responsible for ensuring that database credentials remain valid over time. It periodically checks the status of the credentials and renews them before they expire. This process is critical in environments where credentials have a limited lifespan and need to be refreshed to maintain access.

"},{"location":"how-it-works/renewer/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Periodic Checks:
  2. The Renewer periodically checks the expiration status of the current database credentials. It ensures that credentials are always valid and do not reach their expiration date unnoticed.

  3. Credential Renewal:

  4. Credentials are Renewed using Periodic Token so it ensure that during his whole lifetime, the application never need to restarted.
"},{"location":"how-it-works/renewer/#3-benefits","title":"3. Benefits:","text":"

This feature is particularly useful for maintaining secure and continuous database access in dynamic cloud environments, where credential rotation is a best practice for security.

"},{"location":"how-it-works/revoker/","title":"Revoker","text":"

Key File: pkg/revoker/revoker.go

"},{"location":"how-it-works/revoker/#1-how-it-works","title":"1. How It Works:","text":"

The Revoker is responsible for ensuring that unused or stale database credentials are properly revoked. This process is essential for maintaining the security of your system by ensuring that credentials that are no longer needed are not left active.

"},{"location":"how-it-works/revoker/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Identifying Stale Credentials:
  2. The Revoker identifies credentials that are no longer in use or have become stale. This could be because the application instance that was using them has been terminated, or the credentials have exceeded their intended lifespan.

  3. Revoking Credentials:

  4. Once stale or unused credentials are identified, the Revoker sends a request to HashiCorp Vault to revoke these credentials. This action ensures that these credentials can no longer be used to access the database.

  5. Updating System State:

  6. The Revoker updates the system's state to reflect that certain credentials have been revoked. This helps in maintaining an accurate and secure overview of active and inactive credentials.

  7. Automatic revocation:

  8. The Revoker is watching Kubernetes event and especially DELETE event on pod so it can revoke the credentials direcly after the pod is Deleted, this permit to be sure credentials are not revoked before the pods completely deleted.
"},{"location":"how-it-works/revoker/#3-benefits","title":"3. Benefits:","text":"

This feature is particularly important in dynamic environments where resources and their associated credentials are frequently created and destroyed. It ensures that credentials do not linger beyond their useful life, thereby maintaining a high standard of security.

"},{"location":"how-it-works/vault/","title":"Vault Integration","text":"

Key Files: pkg/vault/handle_token.go, pkg/vault/vault.go

"},{"location":"how-it-works/vault/#1-how-it-works","title":"1. How It Works:","text":"

Vault Integration is a crucial feature that handles interactions with HashiCorp Vault for generating and managing database credentials. This integration ensures that the application can securely request and use credentials from Vault.

"},{"location":"how-it-works/vault/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Vault Client Initialization:
  2. The application initializes a Vault client using the provided configuration. This client is used to authenticate and communicate with the Vault server.

  3. Authentication with Vault:

  4. The application authenticates with Vault using a Kubernetes authentication method

  5. Requesting Credentials:

  6. When the application needs database credentials, it sends a request to Vault. Vault generates the credentials and returns them to the application.

  7. Handling Tokens:

  8. The application manages the tokens used to authenticate with Vault, including handling token renewal and revocation as needed.
"},{"location":"how-it-works/vault/#3-benefits","title":"3. Benefits:","text":""},{"location":"monitoring/alertmanager/","title":"Alertmanager Configuration for VaultDb Injector","text":"

This configuration defines a set of alerts for monitoring the VaultDb Injector within a Kubernetes environment. Each alert is designed to notify the team of potential issues that could impact the availability, security, or functionality of the services relying on Vault for secret management.

"},{"location":"monitoring/alertmanager/#1-alerts-configuration","title":"1. Alerts Configuration","text":""},{"location":"monitoring/alertmanager/#11-service-account-denied","title":"1.1. Service Account Denied","text":"
- alert: VaultDbInjectorServiceAccountDenied\n  annotations:\n    description: \"Service Account (SA) `{{ $labels.service_account_name }}` in namespace `{{ $labels.exported_namespace }}` was denied access to db_role `{{ $labels.db_role }}` due to `{{ $labels.cause }}` on cluster `{{ $labels.k8s_cluster }}`. Immediate investigation is recommended to ensure proper access controls and service configurations.\"\n    summary: \"Service Account `{{ $labels.service_account_name }}` in namespace `{{ $labels.exported_namespace }}` was denied by the injector.\"\n  expr: increase(vault_injector_service_account_denied_count{}[2m]) > 0\n  for: 1m\n  labels:\n    severity: critical\n

Response Actions: - Verify the service account permissions and roles. - Check the db_role configurations to ensure they are correctly set up. - Investigate the cause for denial to prevent future occurrences.

"},{"location":"monitoring/alertmanager/#12-token-renewal-failure","title":"1.2. Token Renewal Failure","text":"
- alert: VaultDbInjectorFailToRenewToken\n  annotations:\n    description: \"VaultDbInjector encountered an error while attempting to renew a token. This might affect the continuous operation of dependent services. Check for errors and ensure the token renewal process is configured correctly.\"\n    summary: \"VaultDbInjector token renewal failure for namespace `{{ $labels.exported_namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: increase(vault_injector_renew_token_count_error{}[2m]) > 0\n  for: 1m\n  labels:\n    severity: warning\n

Response Actions: - Review the injector logs for errors related to token renewal. - Ensure the Vault policies allow for token renewal by the injector. - Check for network issues that might prevent the injector from communicating with Vault.

"},{"location":"monitoring/alertmanager/#13-lease-renewal-failure","title":"1.3. Lease Renewal Failure","text":"
- alert: VaultDbInjectorFailToRenewLease\n  annotations:\n    description: \"VaultDbInjector encountered an error while attempting to renew a lease. Similar to token renewal failures, this can disrupt service operations if not addressed.\"\n    summary: \"VaultDbInjector lease renewal failure for namespace `{{ $labels.exported_namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: increase(vault_injector_renew_lease_count_error{}[2m]) > 0\n  for: 1m\n  labels:\n    severity: warning\n

Response Actions: - Inspect the injector logs for specific errors related to lease renewal. - Confirm that the Vault configuration allows the injector to renew leases. - Investigate any network or configuration issues that might affect communication with Vault.

"},{"location":"monitoring/alertmanager/#14-token-expiration-warnings","title":"1.4. Token Expiration Warnings","text":"
- alert: VaultDbInjectorTokenExpirationLessThan14Days\n  annotations:\n    description: \"A token is nearing expiration (less than 2 weeks). Renewing or rotating the token promptly ensures continuous service operation without interruption.\"\n    summary: \"Token nearing expiration in namespace `{{ $labels.exported_namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: vault_injector_token_expiration - time() < 1209600\n  for: 90m\n  labels:\n    severity: warning\n\n- alert: VaultDbInjectorTokenExpirationLessThan7Days\n  annotations:\n    description: \"A token will expire in less than 7 days. Immediate action is required to renew or rotate the token to avoid service disruption.\"\n    summary: \"Urgent: Token expiration warning for namespace `{{ $labels.exported_namespace }}`.\"\n  expr: vault_injector_token_expiration - time() < 604800\n  for: 5m\n  labels:\n    severity: critical\n

Response Actions: - For both alerts, identify the service or application using the token. - Initiate the token renewal or rotation process. - Review token policies to ensure they're aligned with security and operational requirements.

"},{"location":"monitoring/alertmanager/#15-lease-expiration-warnings","title":"1.5. Lease Expiration Warnings","text":"
- alert: VaultDbInjectorLeaseExpirationLessThan4Days\n  annotations:\n    description: \"A lease is nearing expiration (less than 4 days). Addressing this promptly can prevent potential access issues for services relying on leased credentials or secrets.\"\n    summary: \"Lease nearing expiration for namespace `{{ $labels.namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: vault_injector_lease_expiration - time() < 345600\n  for: 3m\n  labels:\n    severity: warning\n\n- alert: VaultDbInjectorLeaseExpirationLessThan1Day\n  annotations:\n    description: \"A lease will expire in less than 1 day. Immediate renewal is critical to maintaining access for the dependent services.\"\n    summary: \"Critical: Lease expiration imminent for namespace `{{ $labels.namespace }}`.\"\n  expr: vault_injector_lease_expiration - time() < 86400\n  for: 3m\n  labels:\n    severity: critical\n

Response Actions: - Quickly identify and renew the leases for the affected services or credentials. - Review the lease durations and renewal policies to prevent future alerts.

"},{"location":"monitoring/alertmanager/#2-conclusion","title":"2. Conclusion","text":"

Monitoring VaultDb Injector with these alerts helps ensure the reliability and security of services depending on Vault for secret management and access control. Each alert is designed to provide actionable insights for maintaining operational efficiency and security compliance. Responding promptly to these alerts will mitigate potential risks and disruptions to your services.

"},{"location":"monitoring/grafana/","title":"Grafana","text":"

A grafana dashboard is available on the repository and permit you to easily monitore you vault-db-injector infrastructure.

"},{"location":"monitoring/grafana/#dashboard","title":"Dashboard","text":""},{"location":"monitoring/prometheus/","title":"1. Prometheus Metrics","text":"

Our application exports several Prometheus metrics for monitoring and observability purposes. Below are the details of the available metrics:

Metric Name Description Labels vault_injector_renew_token_count_success Vault injector token renewed with success count uuid, namespace vault_injector_renew_token_count_error Vault injector token renewed with error count uuid, namespace vault_injector_renew_lease_count_success Vault injector lease renewed with success count uuid, namespace vault_injector_renew_lease_count_error Vault injector lease renewed with error count uuid, namespace vault_injector_revoke_token_count_success Vault injector token revoked with success count uuid, namespace vault_injector_revoke_token_count_error Vault injector token revoked with error count uuid, namespace vault_injector_token_expiration Vault injector expiration time for tokens uuid, namespace vault_injector_lease_expiration Vault injector expiration time for leases uuid, namespace vault_injector_token_last_renewed Last vault token successful renewal uuid, namespace vault_injector_synchronization_count_success Vault injector synchronization with success vault_injector_synchronization_count_error Vault injector synchronization with error vault_injector_pod_cleanup_count_success Vault injector PodCleanup with success vault_injector_pod_cleanup_count_error Vault injector PodCleanup with error vault_injector_last_synchronization_success Last vault token successful renewal vault_injector_orphan_ticket_created_count_success Vault injector orphan ticket created with success vault_injector_orphan_ticket_created_count_error Vault injector orphan ticket created with error vault_injector_store_data_count_success Vault injector data stored with success uuid, namespace vault_injector_store_data_count_error Vault injector data stored with error uuid, namespace vault_injector_delete_data_count_success Vault injector data delete with success uuid, namespace vault_injector_delete_data_count_error Vault injector data deleted with error uuid, namespace vault_injector_connect_vault_count_success Vault injector connect to vault with success vault_injector_connect_vault_count_error Vault injector connect to vault with error vault_injector_service_account_authorized_count Vault injector service account is authorized to assume dbRole vault_injector_service_account_denied_count Vault injector service account is not authorized to assume dbRole service_account_name, namespace, db_role, cause vault_injector_last_synchronization_duration Vault injector last duration of synchronization vault_injector_is_leader Return 1 if the vault injector is leader, else 0 lease_name vault_injector_leader_election_attempts_total Total number of attempts to acquire leadership lease_name vault_injector_leader_election_duration_seconds Duration in seconds that this instance has been the leader lease_name, leader_name, mode vault_injector_fetch_pods_success_count Count that increase when their is no error retrieving pods vault_injector_fetch_pods_error_count Count that increase when their is an error retrieving pods vault_injector_mutated_pods_error_count Count that increase when their is an error mutating pods vault_injector_mutated_pods_error_count Count that increase when their is an error mutating pods"},{"location":"fr/getting-started/build/#construction","title":"Construction","text":"

Exigences pour la construction

Un Makefile est fourni pour les t\u00e2ches de construction. Les options sont les suivantes :

Pour commencer, c'est aussi simple que :

go get -u github.com/numberly/vault-db-injector\ncd $GOPATH/src/github.com/numberly/vault-db-injector\nmake setup\nmake\n
"}]} \ No newline at end of file +{"config":{"lang":["en","fr"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Vault DB Injector","text":""},{"location":"#overview","title":"Overview","text":"

The Vault DB Injector is a Kubernetes-based application designed to dynamically generate database credentials using HashiCorp Vault and provide them as environment variables to Kubernetes Pods. The application leverages a Mutating Webhook to achieve this functionality, ensuring secure and automated management of database credentials.

"},{"location":"#key-features","title":"Key Features","text":""},{"location":"#1-dynamic-database-credential-injection","title":"1. Dynamic Database Credential Injection","text":""},{"location":"#2-mutating-webhook","title":"2. Mutating Webhook","text":""},{"location":"#3-configuration-management","title":"3. Configuration Management","text":""},{"location":"#4-error-monitoring-with-sentry","title":"4. Error Monitoring with Sentry","text":""},{"location":"#5-logging","title":"5. Logging","text":""},{"location":"#6-kubernetes-integration","title":"6. Kubernetes Integration","text":""},{"location":"#7-leader-election","title":"7. Leader Election","text":""},{"location":"#8-health-checks","title":"8. Health Checks","text":""},{"location":"#9-prometheus-metrics","title":"9. Prometheus Metrics","text":""},{"location":"#getting-started","title":"Getting Started","text":"

To get started with Vault DB Injector, refer to the Installation Guide and Configuration Guide for detailed instructions on setting up and configuring the application.

For a deeper understanding of how the application works, visit the How It Works section.

"},{"location":"#contributing","title":"Contributing","text":"

We welcome contributions from the community! Please see our Contribution Guidelines for more information on how to get involved.

"},{"location":"#license","title":"License","text":"

This project is licensed under the terms of the Apache-2.0 license. See the LICENSE file for details.

"},{"location":"#contact","title":"Contact","text":"

For any questions or support, please reach out to our team at directly by creating an issue on the project.

"},{"location":"getting-started/build/","title":"Build","text":""},{"location":"getting-started/build/#build","title":"Build","text":"

Requirements for building

A Makefile is provided for building tasks. The options are as follows

Getting started is as simple as:

go get -u github.com/numberly/vault-db-injector\ncd $GOPATH/src/github.com/numberly/vault-db-injector\nmake setup\nmake\n
"},{"location":"getting-started/getting-started/","title":"getting-started","text":""},{"location":"getting-started/getting-started/#1-requirements","title":"1. Requirements","text":"

To work correctly, the vault db injector need the following :

In this documentation, we assume that both of those following requirements are already installed.

"},{"location":"getting-started/getting-started/#2-vocabulary","title":"2. Vocabulary","text":"

Here are some vocabulary that you need before starting the installation.

name description default K/V Vault Vault KVv2 path for injector state vault-injector vault policy Vault Injector policy to work properly all-rw vault databases mount Vault database engine used to connect to our database databases vault databases backend connection Vault databases backend connection where we allow role to generate credentials rw-pgsql2-pr vault databases backend role Vault databases role used to allow application on specific database test-role kubernetes auth backend Vault Backend used by Kubernetes Application to authenticate under Vault kubernetes kubernetes auth backend role Vault Backend Role used by injector to authenticate under Vault all-rw postgresql Database engine used to connecte under vault rw-pgsql2-pr database database name to connect into test"},{"location":"getting-started/getting-started/#3-vault-configuration","title":"3. Vault Configuration","text":"

First, we need to configure Vault to allow the injector to generate credentials on the databases engine and to store them inside the dedicated K/V Vault.

"},{"location":"getting-started/getting-started/#31-create-all-rw-vault-policy","title":"3.1. Create all-rw vault-policy","text":"

We are going to start by create the all-rw vault policy that the injector will use :

path \"vault-injector/*\" {\n  capabilities = [\"read\", \"list\", \"update\", \"create\", \"delete\", \"sudo\"]\n}\npath \"vault-injector/data/*\" {\n  capabilities = [\"read\", \"list\", \"update\", \"create\", \"delete\", \"sudo\"]\n}\npath \"vault-injector/metadata/*\" {\n  capabilities = [\"read\", \"list\", \"update\", \"create\", \"delete\", \"sudo\"]\n}\npath \"rw-pgsql2-pr/creds/*\" {\n  capabilities = [\"read\"]\n}\npath \"auth/kubernetes/role/*\" {\n  capabilities = [\"read\"]\n}\npath \"sys/leases/renew\" {\n  capabilities = [\"create\"]\n}\npath \"auth/token/renew-self\" {\n  capabilities = [\"create\"]\n}\npath \"auth/token/renew\" {\n  capabilities = [\"create\", \"update\"]\n}\npath \"auth/token/revoke\" {\n  capabilities = [\"create\", \"update\"]\n}\npath \"auth/token/create\" {\n  capabilities = [\"create\", \"update\", \"read\"]\n}\npath \"auth/token/create-orphan\" {\n  capabilities = [\"create\", \"update\", \"read\", \"sudo\"]\n}\npath \"auth/token/revoke-orphan\" {\n  capabilities = [\"create\", \"update\", \"sudo\"]\n}\n
"},{"location":"getting-started/getting-started/#32-create-kv-vault","title":"3.2. Create K/V Vault","text":"

We need to create the K/V Vault in version v2 named vault-injector.

You can use the following documentation : vault-injector

"},{"location":"getting-started/getting-started/#33-create-vault-databases-mount","title":"3.3. Create vault databases mount","text":"

We need to create a vault databases mount engine named databases.

Here is a terraform example :

resource \"vault_mount\" \"databases\" {\n  path                  = \"databases\"\n  type                  = \"database\"\n  description           = \"databases authentication automation\"\n  max_lease_ttl_seconds = \"31536000\"\n}\n

"},{"location":"getting-started/getting-started/#34-create-vault-databases-backend-connection","title":"3.4. Create vault databases backend connection","text":"

We need to create a vault databases backend connection on the vault databases engine. As you can see below, we allow the test-role role.

Here is a terraform example :

resource \"vault_database_secret_backend_connection\" \"pgsql2\" {\n  backend = vault_mount.databases.path\n  name    = \"pgsql2\"\n  allowed_roles = [\n    \"test-role\",\n  ]\n\n  postgresql {\n    connection_url    = \"postgres://{{username}}:{{password}}@rw-pgsql2-pr:5432/postgres?sslmode=verify-full\"\n    username          = \"postgres\"\n    password          = \"my-password\"\n    username_template = \"{{.RoleName}}-{{unix_time}}-{{random 8}}\"\n  }\n}\n

"},{"location":"getting-started/getting-started/#35-create-a-kubernetes-auth-backend","title":"3.5. Create a kubernetes auth backend","text":"

We need to create a kubernetes auth backend to allow serviceAccount to connect under Vault.

You can use the following documentation : kubernetes

"},{"location":"getting-started/getting-started/#36-create-a-kubernetes-auth-backend-role","title":"3.6. Create a kubernetes auth backend role","text":"

We need to create a kubernetes auth backend role to allow the service account of the vault-db-injector to connect under Vault.

Here is a terraform example :

resource \"vault_kubernetes_auth_backend_role\" \"all_rw\" {\n  backend                          = \"kubernetes\"\n  role_name                        = \"all-rw\"\n  bound_service_account_names      = [\"vault-db-injector\"]\n  bound_service_account_namespaces = [\"vault-db-injector\"]\n  token_ttl                        = 3600\n  token_policies                   = [vault_policy.all_rw.name] # remember the one created before\n  token_bound_cidrs                = [\"10.17.0.0/16\"] # Your pod CIDR\n}\n

We need to create a kubernetes auth backend role to allow the service account of our application to get generated credentials from vault Here is a terraform example :

resource \"vault_policy\" \"policy\" {\n  provider = vault.main\n  name     = var.service_account\n\n  policy = <<EOT\npath \"pgsql2/creds/test-role\" {\n  capabilities = [\"read\"]\n}\nEOT\n}\n\nresource \"vault_kubernetes_auth_backend_role\" \"role\" {\n  provider                         = vault.main\n  backend                          = kubernetes\n  role_name                        = \"test\"\n  bound_service_account_names      = [\"test\"]\n  bound_service_account_namespaces = [\"test\"]\n  token_ttl                        = 3600\n  token_policies                   = [vault_policy.policy.name]\n  token_bound_cidrs                = [\"10.17.0.0/16\"]\n}\n

"},{"location":"getting-started/getting-started/#37-create-vault-databases-backend-role","title":"3.7. Create vault databases backend role","text":"

We need to create a vault databases backend role to allow our application to consume vault databases backend connection

Here is a terraform example :

resource \"vault_database_secret_backend_role\" \"role\" {\n  provider    = vault.main\n  backend     = \"databases\"\n  name        = test-role\n  db_name     = test\n  default_ttl = 3600\n  creation_statements = [\n    \"CREATE ROLE \\\"{{name}}\\\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}' IN ROLE \\\"test\\\";\",\n    \"ALTER ROLE \\\"{{name}}\\\" SET ROLE \\\"test\\\";\",\n  ]\n  revocation_statements = [\n    \"DROP ROLE \\\"{{name}}\\\";\"\n  ]\n}\n
"},{"location":"getting-started/getting-started/#4-database-configuration","title":"4. Database configuration","text":"

You need to create you database under postgres, here is an example for postgres :

CREATE DATABASE test;\nCREATE ROLE test;\nrevoke all on database test from public cascade;\ngrant connect on database test to test;\n\\c test\ngrant create, usage on schema public to test;\ngrant temporary on database test to test;\nALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO test;\nREVOKE ALL ON pg_user FROM public;\nREVOKE ALL ON pg_roles FROM public;\nREVOKE ALL ON pg_group FROM public;\nREVOKE ALL ON pg_authid FROM public;\nREVOKE ALL ON pg_auth_members FROM public;\nREVOKE ALL ON pg_database FROM public;\nREVOKE ALL ON pg_tablespace FROM public;\nREVOKE ALL ON pg_settings FROM public;\n
"},{"location":"getting-started/getting-started/#5-deploy-the-vault-db-injector","title":"5. Deploy the vault db injector","text":"

Now that you have a vault correctly configured and a database ready to be used, we can deploy our vault-db-injector application :

For this, its quit easy, you just need to use the help chart.

kubectl create namespace vault-db-injector\nhelm upgrade --install vault-db-injector . --namespace vault-db-injector\n

When everything is Okay, you should have something like this :

NAME                                         READY   STATUS    RESTARTS   AGE\nvault-db-injector-7f74977b7c-88vvg           1/1     Running   0          29s\nvault-db-injector-7f74977b7c-rq6mt           1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-77skb    1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-96zz4    1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-tdp4r    1/1     Running   0          29s\nvault-db-injector-renewer-6496b84df-wpd8x    1/1     Running   0          29s\nvault-db-injector-revoker-7965857f75-2m5qp   1/1     Running   0          28s\nvault-db-injector-revoker-7965857f75-5msv6   1/1     Running   0          29s\nvault-db-injector-revoker-7965857f75-n29wp   1/1     Running   0          29s\nvault-db-injector-revoker-7965857f75-th9vs   1/1     Running   0          28s\n

"},{"location":"getting-started/getting-started/#6-deploy-an-example-application","title":"6. Deploy an example application :","text":"

Here is an example application deploy on the namespace test that will connect to our database test with the service account test.

apiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: test\n  namespace: test\n---\napiVersion: v1\nkind: Pod\nmetadata:\n  annotations:\n    db-creds-injector.numberly.io/test.env-key-uri: POSTGRES_URL\n    db-creds-injector.numberly.io/test.template: postgresql://@rw-pgsql2-pr:5432/test?sslmode=require\n    db-creds-injector.numberly.io/test.mode: uri\n    db-creds-injector.numberly.io/test.role: test-role\n  labels:\n    client: numberly\n    vault-db-injector: \"true\"\n  name: test\n  namespace: test\nspec:\n  containers:\n  - image: postgres:15.5\n    command: [\"/bin/bash\", \"-c\"]\n    args: [\"sleep 3000000\"]\n    name: test\n    resources: {}\n    securityContext:\n      allowPrivilegeEscalation: false\n      capabilities:\n        drop:\n        - ALL\n      readOnlyRootFilesystem: true\n      runAsNonRoot: true\n      runAsUser: 65534\n  dnsPolicy: ClusterFirst\n  restartPolicy: Always\n  serviceAccount: test\n  serviceAccountName: test\n

To deploy it :

kubectl apply -f test.yaml\n

Wait until your application is ready and you should be able to exec inside the pods and connect to the database.

"},{"location":"how-it-works/configuration/","title":"Configuration","text":"
* 1. [Configuration](#Configuration)\n    * 1.1. [Mode Injector](#ModeInjector)\n    * 1.2. [Mode token-renewer](#Modetoken-renewer)\n    * 1.3. [Mode token-renewer](#Modetoken-renewer-1)\n

Here is the configuration for Vault Injector:

"},{"location":"how-it-works/configuration/#11-mode-injector","title":"1.1. Mode Injector","text":"

The Injector mode is basic one that will handle all api-server request and handle all requests to vault to generate credentials to our DB The config file path can be parse by adding the path with : - \"--config=/injector/config.yaml\"

certFile: /tls/tls.crt\nkeyFile: /tls/tls.key\nvaultAddress: https://vault1.tld:8200\nvaultAuthPath: pgsql2-dv-kubernetes1-dv-par5\nlogLevel: info\nkubeRole: all-rw\ntokenTTL: 768h\nvaultSecretName: vault-injector\nvaultSecretPrefix: kubernetes1-dv-par5\nmode: injector\nsentry: true\nsentryDsn: https://my-sentry-url@sentry.tld/660\ninjectorLabel: vault-db-injector\ndefaultEngine: databases\n

"},{"location":"how-it-works/configuration/#12-mode-token-renewer","title":"1.2. Mode token-renewer","text":"

The Renewer one is a process that will run every hour and validate that all orphan token won't expire before pod is deleted The config file path can be parse by adding the path with : - \"--config=/renewer/config.yaml\"

vaultAddress: https://vault1.tld:8200\nvaultAuthPath: pgsql2-dv-kubernetes1-dv-par5\nlogLevel: info\nkubeRole: all-rw\ntokenTTL: 768h\nvaultSecretName: vault-injector\nvaultSecretPrefix: kubernetes1-dv-par5\nmode: renewer\nsentry: true\nsentryDsn: https://my-sentry-url@sentry.tld/660\nSyncTTLSecond: 300\ninjectorLabel: vault-db-injector\ndefaultEngine: databases\n

"},{"location":"how-it-works/configuration/#13-mode-token-renewer","title":"1.3. Mode token-renewer","text":"

The Revoker one is a process that is going to watch pod deletion Kubernetes events filtered with the label vault-db-injector: true and will revoke token attached to the pod when it is deleted The config file path can be parse by adding the path with : - \"--config=/revoker/config.yaml\"

vaultAddress: https://vault1.tld:8200\nvaultAuthPath: pgsql2-dv-kubernetes1-dv-par5\nlogLevel: info\nkubeRole: all-rw\ntokenTTL: 768h\nvaultSecretName: vault-injector\nvaultSecretPrefix: kubernetes1-dv-par5\nmode: revoker\nsentry: true\nsentryDsn: https://my-sentry-url@sentry.tld/660\ninjectorLabel: vault-db-injector\ndefaultEngine: databases\n

"},{"location":"how-it-works/healthcheck/","title":"Health Checks","text":"

Key File: pkg/healthcheck/healthcheck.go

"},{"location":"how-it-works/healthcheck/#1-how-it-works","title":"1. How It Works:","text":"

Health Checks are a crucial feature that monitors the application's status and readiness, ensuring it is functioning correctly and is ready to handle requests. This feature provides endpoints that external systems can query to check the health and readiness of the application.

"},{"location":"how-it-works/healthcheck/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Health Check Endpoints:
  2. The application exposes HTTP endpoints for health (/healthz) and readiness (/readyz). These endpoints provide information about the application's operational status.

  3. Regular Monitoring:

  4. The health check service regularly monitors the internal state of the application and updates the health and readiness status accordingly.

  5. Integration with Kubernetes:

  6. In a Kubernetes environment, these health check endpoints are used by Kubernetes to manage the application's lifecycle. Kubernetes can restart pods that fail health checks, ensuring continuous availability.
"},{"location":"how-it-works/healthcheck/#3-benefits","title":"3. Benefits:","text":""},{"location":"how-it-works/how-it-work/","title":"How it Work","text":""},{"location":"how-it-works/how-it-work/#1-vault-injector","title":"1. Vault-Injector","text":"

The Vault DB Injector is a Go program that is design to retrieve databases credentials from Hashicorp Vault, it use Kubernetes Mutating Webhook to intercept pod creation activated with a label and configured with annotations. After the credentials are provided, it will store them in a specific Vault KV and will handle the lifecycle of them such as : - Renew them periodically - Revoke them after the pod is deleted

"},{"location":"how-it-works/how-it-work/#11-mechanism","title":"1.1. Mechanism","text":""},{"location":"how-it-works/how-it-work/#111-vault-injector","title":"1.1.1. Vault Injector:","text":"
  1. Connects to Vault to generate credentials.
  2. Vault will create a temporary role in PostgreSQL for the database.
  3. Retrieves the credentials via Vault.
  4. Modifies the pod by adding the credentials in the form of environment variables.
  5. The pod can now connect to the database.
  6. Handle token / lease renewing and revokation.
"},{"location":"how-it-works/how-it-work/#12-diagram","title":"1.2. Diagram","text":""},{"location":"how-it-works/how-it-work/#13-vault-usage","title":"1.3. Vault Usage","text":"

Their is also a fonctionnality that permit to rotate token directly from the injector. Objectif is to keep token as secure as possible. For this purpose, we have made the choice to store the token directly on Vault in a specific KV. We provide a generated random UUID to every pod which will be use as a unique identifier. As long as the pod is alive, the injector will rotate his token 5 minutes by default. If the pods is deleted, the revoker will revoke the token and the lease and the renewer which is design to keep the state will also delete the secret in the KV.

If the injector reboot or fail for any reason, the token can stil be renewed manually or by restarting the injector correctly. He can retrieve all token that was created previously. The renewer will renew all tokens and leases every 5 minutes by default.

We are using periodic token for this purpose which need absolutely \"sudo\" policy. Periodic token permit to add a max_ttl and to have infinite token that can be renewed until the pod is deleted. Token TTL permit to fix the max_ttl of the token which mean : \"How many time my token can belong without been renewed.\" By default, if the token is not renewed, hes timelife is 32 days, that mean, if the injector fail, you have 31 days and 23 hours before all your token will expire, which i think is enough to understand why and repair it to a working state.

With this setup, the advantage is that now, vault is the only real SPOF. The Injector in renewer mode will only renew TOKEN and LEASE and cleanup KV/STORE that has been created by the Injector. The Injector in revoker mode will only revoke TOKEN when a pod has been deleted If the revoker fail to revoke a Token, the renewer can do it periodically every 5 minutes (This will be probably removed in future version.)

"},{"location":"how-it-works/how-it-work/#14-authentication","title":"1.4. Authentication","text":"

It uses a service account and the Kubernetes mount point to retrieve and generate its information. It then sends the following information to the application:

It will store on a specific vault KV/Store the following :

"},{"location":"how-it-works/how-it-work/#15-how-token-are-handled","title":"1.5. How token are handled ?","text":"

They are two kind of token that are created in the lifecycle of the Vault injector :

  1. Token created for the Injector using kubeRole: in the yaml config
  2. Permit to generate OrphanToken for our pods that will access to DB
  3. Permit to renew and revoke all the OrphanToken
  4. Permit to store data token inside the KV from vaultSecretName: vault-injector and prefix : vaultSecretPrefix: kubernetes1-dv-par5
  5. TTL is 1h but will always be revoked after the tasks is completed.
  6. This token will be revoked after the webhook is generated.
  7. OrphanToken created on a webhook request which are stored on Vault with the pods UUID and configured by annotation db-creds-injector.numberly.io/role: and db-creds-injector.numberly.io/dbname.role:
  8. Permit to generate the LeaseId that will be provided to the pod
  9. Permit to generate the DB credentials
  10. Will be revoked when the pod is deleted
  11. Is a periodic token with TTL : tokenTTL: 768h
"},{"location":"how-it-works/how-it-work/#16-how-does-injector-work-then","title":"1.6. How does injector work then ?","text":"
  1. A new pod is created with label vault-db-injector: \"true\", annotations db-creds-injector.numberly.io/cluster: & db-creds-injector.numberly.io/role: and a serviceaccount
  2. The api-server use mutating-webhook to send the pods template to the injector
  3. The injector will generate a new orphan token and do thoses steps :
  4. Does the serviceaccount attached to my pod is allowed to assume my role on Vault. If the SA or the namespace is no't allowed, it will return an error, else, it will continue the process.
  5. Generate a new orphan token with a specific period and the policy provided in the annotation by the pod.
  6. Generate an UUID and add a specific annotation on the pod with IT
  7. Ask vault to generate DB Credentials for the pods with the new Orphan Token
  8. Store on vault on the specific KV the LeaseId, TokenId, namespace in a folder named with the pod UUID
  9. Revoke all intermediate Token
  10. The injector will return back to the api-server with a modified pod template
  11. The api-server will create the new pods with modified informations

The available annotations can be declare like this :

"},{"location":"how-it-works/how-it-work/#17-usage","title":"1.7. Usage :","text":""},{"location":"how-it-works/how-it-work/#171-in-mode-classic","title":"1.7.1. In mode classic","text":"
# To be added in the pod spec\nannotations:\n  db-creds-injector.numberly.io/cluster: databases\n  db-creds-injector.numberly.io/dbname.env-key-dbpassword: DB_PASSWORD\n  db-creds-injector.numberly.io/dbname.env-key-dbuser: DB_USER\n  db-creds-injector.numberly.io/dbname.role: db-role # the one created from vault with terraform\n  db-creds-injector.numberly.io/dbname.mode: classic\nlabels:\n  vault-db-injector: \"true\"\n
"},{"location":"how-it-works/how-it-work/#172-in-mode-uri","title":"1.7.2. In mode URI","text":"
annotations:\n  db-creds-injector.numberly.io/cluster: databases\n  db-creds-injector.numberly.io/dbname.template: postgres://@postgres-server.tld:5432/dbname?sslmode=require\n  db-creds-injector.numberly.io/dbname.role: db-role\n  db-creds-injector.numberly.io/dbname.env-key-uri: POSTGRES_URL\n  db-creds-injector.numberly.io/dbname.mode: uri\nlabels:\n  vault-db-injector: \"true\"\n
"},{"location":"how-it-works/how-it-work/#173-with-multiple-databases","title":"1.7.3. With multiple databases","text":"

annotations:\n  db-creds-injector.numberly.io/cluster: databases\n  db-creds-injector.numberly.io/dbname.env-key-dbpassword: DB_PASSWORD\n  db-creds-injector.numberly.io/dbname.env-key-dbuser: DB_USER\n  db-creds-injector.numberly.io/dbname.role: db-role # the one created from vault with terraform\n  db-creds-injector.numberly.io/dbname.mode: classic\n  db-creds-injector.numberly.io/other_dbname.template: postgres://@postgres-server.tld:5432/dbname?sslmode=require\n  db-creds-injector.numberly.io/other_dbname.role: another-vault-role\n  db-creds-injector.numberly.io/other_dbname.env-key-uri: POSTGRES_URL,ANOTHER_ENV\n  db-creds-injector.numberly.io/other_dbname.mode: uri\nlabels:\n  vault-db-injector: \"true\"\n
Here, as you can see, we can connect to 2 databases dbname and other_dbname.

"},{"location":"how-it-works/injector/","title":"Injector","text":"

Key File: pkg/injector/injector.go

"},{"location":"how-it-works/injector/#1-how-it-works","title":"1. How It Works:","text":"

The injector is responsible for injecting database credentials into Kubernetes Pods using a Mutating Admission Webhook.

"},{"location":"how-it-works/injector/#2-benefits","title":"2. Benefits:","text":""},{"location":"how-it-works/kubernetes/","title":"Kubernetes Integration","text":"

Key Files: pkg/k8s/connect.go, pkg/k8s/pod_utils.go, pkg/k8s/parse_annotations.go

"},{"location":"how-it-works/kubernetes/#1-how-it-works","title":"1. How It Works:","text":"

Kubernetes Integration is a fundamental feature that enables the application to interact with the Kubernetes API. This integration allows the application to manage and manipulate Kubernetes resources, facilitating tasks such as credential injection, pod management, and more.

"},{"location":"how-it-works/kubernetes/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Kubernetes Client Initialization:
  2. The application initializes a Kubernetes client that can interact with the Kubernetes API. This client is used to perform various operations such as reading pod annotations, accessing secrets, and more.

  3. Service Account Token Retrieval:

  4. The application retrieves the service account token from the Kubernetes environment. This token is used for authenticating API requests made by the application.

  5. CA Certificate Retrieval:

  6. The application retrieves the Kubernetes CA certificate. This certificate is used to establish secure communication with the Kubernetes API server.

  7. Pod Annotation Parsing:

  8. The application reads and parses annotations from Kubernetes pods. These annotations can include instructions for credential injection and other custom configurations.
"},{"location":"how-it-works/kubernetes/#3-benefits","title":"3. Benefits:","text":""},{"location":"how-it-works/kubernetes/#31-annotations","title":"3.1. Annotations :","text":"

Each injector annotation are read by the Injector pod and permit to configure properly how Database Credetials need to be handled.

"},{"location":"how-it-works/leaderelection/","title":"Leader Election","text":"

Key File: pkg/leadership/leadership.go

"},{"location":"how-it-works/leaderelection/#1-how-it-works","title":"1. How It Works:","text":"

Leader Election is a mechanism that ensures high availability and fault tolerance by designating a single instance of the application to perform critical tasks at any given time. This feature is particularly important in distributed systems where multiple instances of an application might be running concurrently.

"},{"location":"how-it-works/leaderelection/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Resource Locking:
  2. Leader Election uses Kubernetes resource locks to manage which instance of the application is the current leader. The application instances compete for a lock, and the one that acquires it becomes the leader.

  3. Performing Critical Tasks:

  4. The leader is responsible for performing tasks that should not be duplicated. These tasks could include credential renewal, revocation, and other maintenance activities that need to be managed centrally.

  5. Failover Handling:

  6. If the current leader fails or goes offline, another instance of the application can take over by acquiring the lock. This ensures continuous operation and minimal downtime for critical tasks.
"},{"location":"how-it-works/leaderelection/#3-benefits","title":"3. Benefits:","text":"

This feature is essential for applications deployed in Kubernetes clusters, where ensuring that critical tasks are managed by a single, designated instance enhances both reliability and performance.

"},{"location":"how-it-works/renewer/","title":"Renewer","text":"

Key File: pkg/renewer/renewer.go

"},{"location":"how-it-works/renewer/#1-how-it-works","title":"1. How It Works:","text":"

The Renewer is a crucial component responsible for ensuring that database credentials remain valid over time. It periodically checks the status of the credentials and renews them before they expire. This process is critical in environments where credentials have a limited lifespan and need to be refreshed to maintain access.

"},{"location":"how-it-works/renewer/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Periodic Checks:
  2. The Renewer periodically checks the expiration status of the current database credentials. It ensures that credentials are always valid and do not reach their expiration date unnoticed.

  3. Credential Renewal:

  4. Credentials are Renewed using Periodic Token so it ensure that during his whole lifetime, the application never need to restarted.
"},{"location":"how-it-works/renewer/#3-benefits","title":"3. Benefits:","text":"

This feature is particularly useful for maintaining secure and continuous database access in dynamic cloud environments, where credential rotation is a best practice for security.

"},{"location":"how-it-works/revoker/","title":"Revoker","text":"

Key File: pkg/revoker/revoker.go

"},{"location":"how-it-works/revoker/#1-how-it-works","title":"1. How It Works:","text":"

The Revoker is responsible for ensuring that unused or stale database credentials are properly revoked. This process is essential for maintaining the security of your system by ensuring that credentials that are no longer needed are not left active.

"},{"location":"how-it-works/revoker/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Identifying Stale Credentials:
  2. The Revoker identifies credentials that are no longer in use or have become stale. This could be because the application instance that was using them has been terminated, or the credentials have exceeded their intended lifespan.

  3. Revoking Credentials:

  4. Once stale or unused credentials are identified, the Revoker sends a request to HashiCorp Vault to revoke these credentials. This action ensures that these credentials can no longer be used to access the database.

  5. Updating System State:

  6. The Revoker updates the system's state to reflect that certain credentials have been revoked. This helps in maintaining an accurate and secure overview of active and inactive credentials.

  7. Automatic revocation:

  8. The Revoker is watching Kubernetes event and especially DELETE event on pod so it can revoke the credentials direcly after the pod is Deleted, this permit to be sure credentials are not revoked before the pods completely deleted.
"},{"location":"how-it-works/revoker/#3-benefits","title":"3. Benefits:","text":"

This feature is particularly important in dynamic environments where resources and their associated credentials are frequently created and destroyed. It ensures that credentials do not linger beyond their useful life, thereby maintaining a high standard of security.

"},{"location":"how-it-works/vault/","title":"Vault Integration","text":"

Key Files: pkg/vault/handle_token.go, pkg/vault/vault.go

"},{"location":"how-it-works/vault/#1-how-it-works","title":"1. How It Works:","text":"

Vault Integration is a crucial feature that handles interactions with HashiCorp Vault for generating and managing database credentials. This integration ensures that the application can securely request and use credentials from Vault.

"},{"location":"how-it-works/vault/#2-key-responsibilities","title":"2. Key Responsibilities:","text":"
  1. Vault Client Initialization:
  2. The application initializes a Vault client using the provided configuration. This client is used to authenticate and communicate with the Vault server.

  3. Authentication with Vault:

  4. The application authenticates with Vault using a Kubernetes authentication method

  5. Requesting Credentials:

  6. When the application needs database credentials, it sends a request to Vault. Vault generates the credentials and returns them to the application.

  7. Handling Tokens:

  8. The application manages the tokens used to authenticate with Vault, including handling token renewal and revocation as needed.
"},{"location":"how-it-works/vault/#3-benefits","title":"3. Benefits:","text":""},{"location":"monitoring/alertmanager/","title":"Alertmanager Configuration for VaultDb Injector","text":"

This configuration defines a set of alerts for monitoring the VaultDb Injector within a Kubernetes environment. Each alert is designed to notify the team of potential issues that could impact the availability, security, or functionality of the services relying on Vault for secret management.

"},{"location":"monitoring/alertmanager/#1-alerts-configuration","title":"1. Alerts Configuration","text":""},{"location":"monitoring/alertmanager/#11-service-account-denied","title":"1.1. Service Account Denied","text":"
- alert: VaultDbInjectorServiceAccountDenied\n  annotations:\n    description: \"Service Account (SA) `{{ $labels.service_account_name }}` in namespace `{{ $labels.exported_namespace }}` was denied access to db_role `{{ $labels.db_role }}` due to `{{ $labels.cause }}` on cluster `{{ $labels.k8s_cluster }}`. Immediate investigation is recommended to ensure proper access controls and service configurations.\"\n    summary: \"Service Account `{{ $labels.service_account_name }}` in namespace `{{ $labels.exported_namespace }}` was denied by the injector.\"\n  expr: increase(vault_injector_service_account_denied_count{}[2m]) > 0\n  for: 1m\n  labels:\n    severity: critical\n

Response Actions: - Verify the service account permissions and roles. - Check the db_role configurations to ensure they are correctly set up. - Investigate the cause for denial to prevent future occurrences.

"},{"location":"monitoring/alertmanager/#12-token-renewal-failure","title":"1.2. Token Renewal Failure","text":"
- alert: VaultDbInjectorFailToRenewToken\n  annotations:\n    description: \"VaultDbInjector encountered an error while attempting to renew a token. This might affect the continuous operation of dependent services. Check for errors and ensure the token renewal process is configured correctly.\"\n    summary: \"VaultDbInjector token renewal failure for namespace `{{ $labels.exported_namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: increase(vault_injector_renew_token_count_error{}[2m]) > 0\n  for: 1m\n  labels:\n    severity: warning\n

Response Actions: - Review the injector logs for errors related to token renewal. - Ensure the Vault policies allow for token renewal by the injector. - Check for network issues that might prevent the injector from communicating with Vault.

"},{"location":"monitoring/alertmanager/#13-lease-renewal-failure","title":"1.3. Lease Renewal Failure","text":"
- alert: VaultDbInjectorFailToRenewLease\n  annotations:\n    description: \"VaultDbInjector encountered an error while attempting to renew a lease. Similar to token renewal failures, this can disrupt service operations if not addressed.\"\n    summary: \"VaultDbInjector lease renewal failure for namespace `{{ $labels.exported_namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: increase(vault_injector_renew_lease_count_error{}[2m]) > 0\n  for: 1m\n  labels:\n    severity: warning\n

Response Actions: - Inspect the injector logs for specific errors related to lease renewal. - Confirm that the Vault configuration allows the injector to renew leases. - Investigate any network or configuration issues that might affect communication with Vault.

"},{"location":"monitoring/alertmanager/#14-token-expiration-warnings","title":"1.4. Token Expiration Warnings","text":"
- alert: VaultDbInjectorTokenExpirationLessThan14Days\n  annotations:\n    description: \"A token is nearing expiration (less than 2 weeks). Renewing or rotating the token promptly ensures continuous service operation without interruption.\"\n    summary: \"Token nearing expiration in namespace `{{ $labels.exported_namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: vault_injector_token_expiration - time() < 1209600\n  for: 90m\n  labels:\n    severity: warning\n\n- alert: VaultDbInjectorTokenExpirationLessThan7Days\n  annotations:\n    description: \"A token will expire in less than 7 days. Immediate action is required to renew or rotate the token to avoid service disruption.\"\n    summary: \"Urgent: Token expiration warning for namespace `{{ $labels.exported_namespace }}`.\"\n  expr: vault_injector_token_expiration - time() < 604800\n  for: 5m\n  labels:\n    severity: critical\n

Response Actions: - For both alerts, identify the service or application using the token. - Initiate the token renewal or rotation process. - Review token policies to ensure they're aligned with security and operational requirements.

"},{"location":"monitoring/alertmanager/#15-lease-expiration-warnings","title":"1.5. Lease Expiration Warnings","text":"
- alert: VaultDbInjectorLeaseExpirationLessThan4Days\n  annotations:\n    description: \"A lease is nearing expiration (less than 4 days). Addressing this promptly can prevent potential access issues for services relying on leased credentials or secrets.\"\n    summary: \"Lease nearing expiration for namespace `{{ $labels.namespace }}` on cluster `{{ $labels.k8s_cluster }}`.\"\n  expr: vault_injector_lease_expiration - time() < 345600\n  for: 3m\n  labels:\n    severity: warning\n\n- alert: VaultDbInjectorLeaseExpirationLessThan1Day\n  annotations:\n    description: \"A lease will expire in less than 1 day. Immediate renewal is critical to maintaining access for the dependent services.\"\n    summary: \"Critical: Lease expiration imminent for namespace `{{ $labels.namespace }}`.\"\n  expr: vault_injector_lease_expiration - time() < 86400\n  for: 3m\n  labels:\n    severity: critical\n

Response Actions: - Quickly identify and renew the leases for the affected services or credentials. - Review the lease durations and renewal policies to prevent future alerts.

"},{"location":"monitoring/alertmanager/#2-conclusion","title":"2. Conclusion","text":"

Monitoring VaultDb Injector with these alerts helps ensure the reliability and security of services depending on Vault for secret management and access control. Each alert is designed to provide actionable insights for maintaining operational efficiency and security compliance. Responding promptly to these alerts will mitigate potential risks and disruptions to your services.

"},{"location":"monitoring/grafana/","title":"Grafana","text":"

A grafana dashboard is available on the repository and permit you to easily monitore you vault-db-injector infrastructure.

"},{"location":"monitoring/grafana/#dashboard","title":"Dashboard","text":""},{"location":"monitoring/prometheus/","title":"1. Prometheus Metrics","text":"

Our application exports several Prometheus metrics for monitoring and observability purposes. Below are the details of the available metrics:

Metric Name Description Labels vault_injector_renew_token_count_success Vault injector token renewed with success count uuid, namespace vault_injector_renew_token_count_error Vault injector token renewed with error count uuid, namespace vault_injector_renew_lease_count_success Vault injector lease renewed with success count uuid, namespace vault_injector_renew_lease_count_error Vault injector lease renewed with error count uuid, namespace vault_injector_revoke_token_count_success Vault injector token revoked with success count uuid, namespace vault_injector_revoke_token_count_error Vault injector token revoked with error count uuid, namespace vault_injector_token_expiration Vault injector expiration time for tokens uuid, namespace vault_injector_lease_expiration Vault injector expiration time for leases uuid, namespace vault_injector_token_last_renewed Last vault token successful renewal uuid, namespace vault_injector_synchronization_count_success Vault injector synchronization with success vault_injector_synchronization_count_error Vault injector synchronization with error vault_injector_pod_cleanup_count_success Vault injector PodCleanup with success vault_injector_pod_cleanup_count_error Vault injector PodCleanup with error vault_injector_last_synchronization_success Last vault token successful renewal vault_injector_orphan_ticket_created_count_success Vault injector orphan ticket created with success vault_injector_orphan_ticket_created_count_error Vault injector orphan ticket created with error vault_injector_store_data_count_success Vault injector data stored with success uuid, namespace vault_injector_store_data_count_error Vault injector data stored with error uuid, namespace vault_injector_delete_data_count_success Vault injector data delete with success uuid, namespace vault_injector_delete_data_count_error Vault injector data deleted with error uuid, namespace vault_injector_connect_vault_count_success Vault injector connect to vault with success vault_injector_connect_vault_count_error Vault injector connect to vault with error vault_injector_service_account_authorized_count Vault injector service account is authorized to assume dbRole vault_injector_service_account_denied_count Vault injector service account is not authorized to assume dbRole service_account_name, namespace, db_role, cause vault_injector_last_synchronization_duration Vault injector last duration of synchronization vault_injector_is_leader Return 1 if the vault injector is leader, else 0 lease_name vault_injector_leader_election_attempts_total Total number of attempts to acquire leadership lease_name vault_injector_leader_election_duration_seconds Duration in seconds that this instance has been the leader lease_name, leader_name, mode vault_injector_fetch_pods_success_count Count that increase when their is no error retrieving pods vault_injector_fetch_pods_error_count Count that increase when their is an error retrieving pods vault_injector_mutated_pods_error_count Count that increase when their is an error mutating pods vault_injector_mutated_pods_error_count Count that increase when their is an error mutating pods"},{"location":"fr/getting-started/build/#construction","title":"Construction","text":"

Exigences pour la construction

Un Makefile est fourni pour les t\u00e2ches de construction. Les options sont les suivantes :

Pour commencer, c'est aussi simple que :

go get -u github.com/numberly/vault-db-injector\ncd $GOPATH/src/github.com/numberly/vault-db-injector\nmake setup\nmake\n
"}]} \ No newline at end of file