{"id":19748676,"url":"https://github.com/doitintl/kube-secrets-init","last_synced_at":"2025-04-07T12:09:43.595Z","repository":{"id":41138345,"uuid":"221716821","full_name":"doitintl/kube-secrets-init","owner":"doitintl","description":"Kubernetes mutating webhook for `secrets-init` injection","archived":false,"fork":false,"pushed_at":"2024-07-30T10:27:24.000Z","size":285,"stargazers_count":155,"open_issues_count":6,"forks_count":33,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-31T10:09:41.055Z","etag":null,"topics":["admission-webhook","aws","aws-parameter-store","aws-secrets-manager","gcp","google-cloud","google-secret","google-secret-manager","iam-role","kubernetes","kubernetes-mutating-webhook","secret-management","secrets-management"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/doitintl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-14T14:30:12.000Z","updated_at":"2025-03-15T21:30:43.000Z","dependencies_parsed_at":"2024-01-13T06:54:13.032Z","dependency_job_id":"888e6dfb-c261-4801-bc99-334d6b337795","html_url":"https://github.com/doitintl/kube-secrets-init","commit_stats":{"total_commits":48,"total_committers":3,"mean_commits":16.0,"dds":"0.16666666666666663","last_synced_commit":"c35b84f80d71306eff2c4feae42a008e0386ae91"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doitintl%2Fkube-secrets-init","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doitintl%2Fkube-secrets-init/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doitintl%2Fkube-secrets-init/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doitintl%2Fkube-secrets-init/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doitintl","download_url":"https://codeload.github.com/doitintl/kube-secrets-init/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247648977,"owners_count":20972945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admission-webhook","aws","aws-parameter-store","aws-secrets-manager","gcp","google-cloud","google-secret","google-secret-manager","iam-role","kubernetes","kubernetes-mutating-webhook","secret-management","secrets-management"],"created_at":"2024-11-12T02:22:55.709Z","updated_at":"2025-04-07T12:09:43.577Z","avatar_url":"https://github.com/doitintl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![code](https://github.com/doitintl/kube-secrets-init/actions/workflows/test.yaml/badge.svg)](https://github.com/doitintl/kube-secrets-init/actions/workflows/test.yaml) [![Docker Pulls](https://img.shields.io/docker/pulls/doitintl/kube-secrets-init.svg?style=popout)](https://hub.docker.com/r/doitintl/kube-secrets-init) [![](https://images.microbadger.com/badges/image/doitintl/kube-secrets-init.svg)](https://microbadger.com/images/doitintl/kube-secrets-init \"Get your own image badge on microbadger.com\")\n\n## Blog Post\n\n[Kubernetes and Secrets Management In The Cloud](https://blog.doit-intl.com/kubernetes-and-secrets-management-in-cloud-part-2-6c37c1238a87?source=friends_link\u0026sk=58405cbafc191a2d7ea2eabbc9d9553e)\n\n# `kube-secrets-init`\n\nThe `kube-secrets-init` is a Kubernetes mutating admission webhook, that mutates any K8s Pod that is using specially prefixed environment variables, directly or from Kubernetes as Secret or ConfigMap.\n\n## `kube-secrets-init` mutation\n\nThe `kube-secrets-init` injects a `copy-secrets-init` `initContainer` into a target Pod, mounts `/helper/bin` (default; can be changed with the `volume-path` flag) and copies the [`secrets-init`](https://github.com/doitintl/secrets-init) tool into the mounted volume. It also modifies Pod `entrypoint` to `secrets-init` init system, following original command and arguments, extracted either from Pod specification or from Docker image.\n\n### skip injection\n\nThe `kube-secrets-init` can be configured to skip injection for all Pods in the specific Namespace by adding the `admission.secrets-init/ignore` label to the Namespace.\n\n## What `secrets-init` does\n\n`secrets-init` runs as `PID 1`, acting like a simple init system. It launches a single process and then proxies all received signals to a session rooted at that child process.\n\n`secrets-init` also passes almost all environment variables without modification, replacing _secret variables_ with values from secret management services.\n\n### Integration with AWS Secrets Manager\n\nUser can put AWS secret ARN as environment variable value. The `secrets-init` will resolve any environment value, using specified ARN, to referenced secret value.\n\n```sh\n# environment variable passed to `secrets-init`\nMY_DB_PASSWORD=arn:aws:secretsmanager:$AWS_REGION:$AWS_ACCOUNT_ID:secret:mydbpassword-cdma3\n\n# environment variable passed to child process, resolved by `secrets-init`\nMY_DB_PASSWORD=very-secret-password\n```\n\n### Integration with AWS Systems Manager Parameter Store\n\nIt is possible to use AWS Systems Manager Parameter Store to store application parameters and secrets.\n\nUser can put AWS Parameter Store ARN as environment variable value. The `secrets-init` will resolve any environment value, using specified ARN, to referenced parameter value.\n\n```sh\n# environment variable passed to `secrets-init`\nMY_API_KEY=arn:aws:ssm:$AWS_REGION:$AWS_ACCOUNT_ID:parameter/api/key\n\n# environment variable passed to child process, resolved by `secrets-init`\nMY_API_KEY=key-123456789\n```\n\n### Integration with Google Secret Manager\n\nUser can put Google secret name (prefixed with `gcp:secretmanager:`) as environment variable value. The `secrets-init` will resolve any environment value, using specified name, to referenced secret value.\n\n```sh\n# environment variable passed to `secrets-init`\nMY_DB_PASSWORD=gcp:secretmanager:projects/$PROJECT_ID/secrets/mydbpassword\n# OR versioned secret (with version or 'latest')\nMY_DB_PASSWORD=gcp:secretmanager:projects/$PROJECT_ID/secrets/mydbpassword/versions/2\n\n# environment variable passed to child process, resolved by `secrets-init`\nMY_DB_PASSWORD=very-secret-password\n```\n\n### Requirement\n\n#### AWS\n\nIn order to resolve AWS secrets from AWS Secrets Manager and Parameter Store, `secrets-init` should run under IAM role that has permission to access desired secrets.\n\nThis can be achieved by assigning IAM Role to Kubernetes Pod. It's possible to assign IAM Role to EC2 instance, where container is running, but this option is less secure.\n\n#### Google Cloud\n\nIn order to resolve Google secrets from Google Secret Manager, `secrets-init` should run under IAM role that has permission to access desired secrets. For example, you can assign the following 2 predefined Google IAM roles to a Google Service Account: `Secret Manager Viewer` and `Secret Manager Secret Accessor` role.\n\nThis can be achieved by assigning IAM Role to Kubernetes Pod with [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity). It's possible to assign IAM Role to GCE instance, where container is running, but this option is less secure.\n\nUncomment `--provider=google` flag in the [deployment.yaml](https://github.com/doitintl/kube-secrets-init/blob/master/deployment/deployment.yaml) file.\n\n## The `kube-secrets-init` deployment\n\n### Deploy with Helm Chart\n\nConsider using the `kube-secrets-init` Helm Chart, authored and managed by [Márk Sági-Kazár](https://github.com/sagikazarmark).\n\n```sh\nhelm repo add skm https://charts.sagikazarmark.dev\nhelm install --generate-name --wait skm/kube-secrets-init\n```\n\nCheck chart GitHub [repository](https://github.com/sagikazarmark/helm-charts/tree/master/charts/kube-secrets-init)\n\n### Manual Deployment\n\n1. To deploy the `kube-secrets-init` server, we need to create a webhook service and a deployment in our Kubernetes cluster. It’s pretty straightforward, except one thing, which is the server’s TLS configuration. If you’d care to examine the [deployment.yaml](https://github.com/doitintl/kube-secrets-init/blob/master/deployment/deployment.yaml) file, you’ll find that the certificate and corresponding private key files are read from command line arguments, and that the path to these files comes from a volume mount that points to a Kubernetes secret:\n\n```yaml\n[...]\n      args:\n      [...]\n      - --tls-cert-file=/etc/webhook/certs/cert.pem\n      - --tls-private-key-file=/etc/webhook/certs/key.pem\n      volumeMounts:\n      - name: webhook-certs\n        mountPath: /etc/webhook/certs\n        readOnly: true\n[...]\n   volumes:\n   - name: webhook-certs\n     secret:\n       secretName: secrets-init-webhook-certs\n```\n\nThe most important thing to remember is to set the corresponding CA certificate later in the webhook configuration, so the `apiserver` will know that it should be accepted. For now, we’ll reuse the script originally written by the Istio team to generate a certificate signing request. Then we’ll send the request to the Kubernetes API, fetch the certificate, and create the required secret from the result.\n\nFirst, run [webhook-create-signed-cert.sh](https://github.com/doitintl/kube-secrets-init/blob/master/deployment/webhook-create-signed-cert.sh) script and check if the secret holding the certificate and key has been created:\n\n```text\n./deployment/webhook-create-signed-cert.sh\n\ncreating certs in tmpdir /var/folders/vl/gxsw2kf13jsf7s8xrqzcybb00000gp/T/tmp.xsatrckI71\nGenerating RSA private key, 2048 bit long modulus\n.........................+++\n....................+++\ne is 65537 (0x10001)\ncertificatesigningrequest.certificates.k8s.io/secrets-init-webhook-svc.default created\nNAME                         AGE   REQUESTOR              CONDITION\nsecrets-init-webhook-svc.default   1s    alexei@doit-intl.com   Pending\ncertificatesigningrequest.certificates.k8s.io/secrets-init-webhook-svc.default approved\nsecret/secrets-init-webhook-certs configured\n```\n\n**Note** For the GKE Autopilot, run the [webhook-create-self-signed-cert.sh](https://github.com/doitintl/kube-secrets-init/blob/master/deployment/webhook-create-self-signed-cert.sh) script to generate a self-signed certificate.\n\nExport the CA Bundle as a new environment variable `CA_BUNDLE`:\n\n```sh\nexport CA_BUNDLE=[output value of the previous script \"Encoded CA:\"]\n```\n\nOnce the secret is created, we can create deployment and service. These are standard Kubernetes deployment and service resources. Up until this point we’ve produced nothing but an HTTP server that’s accepting requests through a service on port `443`:\n\n```sh\nkubectl create -f deployment/deployment.yaml\n\nkubectl create -f deployment/service.yaml\n```\n\n### configure mutating admission webhook\n\nNow that our webhook server is running, it can accept requests from the `apiserver`. However, we should create some configuration resources in Kubernetes first. Let’s start with our validating webhook, then we’ll configure the mutating webhook later. If you take a look at the [webhook configuration](https://github.com/doitintl/kube-secrets-init/blob/master/deployment/mutatingwebhook.yaml), you’ll notice that it contains a placeholder for `CA_BUNDLE`:\n\n```yaml\n[...]\n      service:\n        name: secrets-init-webhook-svc\n        namespace: default\n        path: \"/pods\"\n      caBundle: ${CA_BUNDLE}\n[...]\n```\n\nThere is a [small script](https://github.com/doitintl/kube-secrets-init/blob/master/deployment/webhook-patch-ca-bundle.sh) that substitutes the CA_BUNDLE placeholder in the configuration with this CA. Run this command before creating the validating webhook configuration:\n\n```sh\ncat ./deployment/mutatingwebhook.yaml | ./deployment/webhook-patch-ca-bundle.sh \u003e ./deployment/mutatingwebhook-bundle.yaml\n```\n\nCreate mutating webhook configuration:\n\n```sh\nkubectl create -f deployment/mutatingwebhook-bundle.yaml\n```\n\n### configure RBAC for secrets-init-webhook\n\nCreate Kubernetes Service Account to be used with `secrets-init-webhook`:\n\n```sh\nkubectl create -f deployment/service-account.yaml\n```\n\nDefine RBAC permission for webhook service account:\n\n```sh\n# create a cluster role\nkubectl create -f deployment/clusterrole.yaml\n# define a cluster role binding\nkubectl create -f deployment/clusterrolebinding.yaml\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoitintl%2Fkube-secrets-init","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoitintl%2Fkube-secrets-init","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoitintl%2Fkube-secrets-init/lists"}