{"id":38094491,"url":"https://github.com/KongZ/piggy","last_synced_at":"2026-01-24T10:00:52.933Z","repository":{"id":40315651,"uuid":"385814317","full_name":"KongZ/piggy","owner":"KongZ","description":"Piggy is a tool built for supporting AWS Secret Manager with Kubernetes. It has abilities to mutating Pods, unseal secrets and inject into application environment.","archived":false,"fork":false,"pushed_at":"2026-01-22T17:58:40.000Z","size":11575,"stargazers_count":36,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-23T09:50:43.425Z","etag":null,"topics":["aws","eks","kubernetes","secret-manager","ssm-parameter-store"],"latest_commit_sha":null,"homepage":"https://piggysec.com","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/KongZ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["KongZ"]}},"created_at":"2021-07-14T04:35:31.000Z","updated_at":"2026-01-22T17:58:46.000Z","dependencies_parsed_at":"2024-01-24T17:47:30.722Z","dependency_job_id":"907501f5-ce72-4c93-8ee1-e5be052d81dc","html_url":"https://github.com/KongZ/piggy","commit_stats":null,"previous_names":[],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/KongZ/piggy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KongZ%2Fpiggy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KongZ%2Fpiggy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KongZ%2Fpiggy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KongZ%2Fpiggy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KongZ","download_url":"https://codeload.github.com/KongZ/piggy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KongZ%2Fpiggy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28724374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T08:27:05.734Z","status":"ssl_error","status_checked_at":"2026-01-24T08:27:01.197Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["aws","eks","kubernetes","secret-manager","ssm-parameter-store"],"created_at":"2026-01-16T21:00:23.270Z","updated_at":"2026-01-24T10:00:52.921Z","avatar_url":"https://github.com/KongZ.png","language":"Go","funding_links":["https://github.com/sponsors/KongZ"],"categories":["Go","Secret Management"],"sub_categories":[],"readme":"[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Action](https://github.com/KongZ/piggy/workflows/Build%20to%20GHCR/badge.svg?branch=main)](https://github.com/KongZ/piggy/actions)\n[![CodeQL](https://github.com/KongZ/piggy/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/KongZ/piggy/actions/workflows/codeql-analysis.yml)\n[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/piggy)](https://artifacthub.io/packages/search?repo=piggy)\n\n\u003cimg src=\"https://raw.githubusercontent.com/KongZ/piggy/refs/heads/main/docs/images/gopher-piggy.png\" alt=\"Piggy logo\" width=\"200\"/\u003e\n\n# Piggy\n\nPiggy is a tool built for supporting AWS Secret Manager with Kubernetes. It has abilities to mutating Pods, unseal secrets and inject\ninto application environment.\n\n## Installation\n\nCurrent release requires AWS IRSA to provide the IAM permission to piggy for unsealing secrets. Before installing Piggy webhooks, you must\nsetup the IRSA on AWS. Sees [https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html] for complete detail of IRSA setting up.\nAlternatively, you can use Terraform the setup IRSA. Sees [https://github.com/terraform-aws-modules/terraform-aws-eks/tree/master/examples/irsa]\n\nThe simplest IRSA Policy for Piggy webhooks\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"PiggySecretReadOnly\",\n      \"Action\": [\n        \"secretsmanager:DescribeSecret\",\n        \"secretsmanager:GetResourcePolicy\",\n        \"secretsmanager:GetSecretValue\",\n        \"secretsmanager:ListSecretVersionIds\",\n        \"secretsmanager:ListSecrets\"\n      ],\n      \"Effect\": \"Allow\",\n      \"Resource\": \"*\"\n    },\n    {\n      \"Sid\": \"PiggyECRReadOnly\",\n      \"Action\": [\n        \"ecr:BatchCheckLayerAvailability\",\n        \"ecr:BatchGetImage\",\n        \"ecr:DescribeImages\",\n        \"ecr:GetAuthorizationToken\",\n        \"ecr:GetDownloadUrlForLayer\"\n      ],\n      \"Effect\": \"Allow\",\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n\n1) Run helm chart install\n\n```bash\nhelm repo add piggysec https://piggysec.com\nhelm -n piggy-webhooks install piggy-webhooks piggysec/piggy-webhooks --set aws.roleArn=${piggy-role-arn}\n```\n\n2) Add these minimum annotations to your Deployment\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  annotations:\n    piggysec.com/piggy-address: https://piggy-webhooks.piggy-webhooks.svc.cluster.local\n    piggysec.com/aws-secret-name: ${your-aws-secret-name} ## e.g. myapp/sample/production\n    piggysec.com/aws-region: ${your-aws-secret-region} ## e.g. ap-southeast-1\n```\n\nYou can define a default AWS region by setting `AWS_REGION` environment value in Piggy Webhooks\n\n3) Add Env value with format `piggy:${name}`\n\n```yaml\n  containers:\n      env:\n        - name: TEST_ENV\n          value: piggy:TEST_ENV\n```\n\n4) That all!!. See the demo at [https://github.com/KongZ/piggy/tree/main/demo]\n\n### Default settings\n\nSome setting such as AWS region can set a default value by setting `env` in piggy webhooks helm chart value.\nSimply remove prefix `piggysec.com` from annotation, put it all in upper case, and change `-` to `_`.\n\nFor example:\n\n```yaml\nenv:\n  AWS_REGION: \"ap-southeast-1\"\n  PIGGY_ENFORCE_SERVICE_ACCOUNT: \"true\"\n```\n\n## Proxy mode\n\nThis is a default mode. The Piggy Webhooks requires a permission to read secret from AWS Secret Manager.\nThe application containers will send request to Piggy Webhooks and Piggy Webhooks will inject the secret into containers environments\nwhich prefix with `piggy:`\n\n```bash\n                (1)  ┌───────────┐ (10)\n                ───▶ │           │ ───▶\n              ───────│ Container │───────\n                     │           │\n                     └───────────┘\n                           │\n                         «tls»\n                           │\n                          ││▲\n                       (2)│││(9)\n                          ▼││\n┌───────────┐  (3)   ┌───────────┐  (5)   ┌───────────┐\n│Kubernetes │  ◀───  │   Piggy   │  ───▶  │           │\n│    API    │────────│ Webhooks  │────────│  AWS STS  │\n│           │  ───▶  │           │  ◀───  │           │\n└───────────┘   (4)  └───────────┘   (6)  └───────────┘\n                           │▲\n                          │││(8)\n                       (7)│││\n                          ▼│\n                     ┌───────────┐\n                     │AWS Secret │\n                     │  Manager  │\n                     │           │\n                     └───────────┘\n```\n\nThe example manifest file for Pod. To receive the Piggy Webhooks injection, you will need only 3 annotations\n\n  - `piggysec.com/piggy-address` - set a value to Piggy Webhooks service\n  - `piggysec.com/aws-secret-name` - set a value to your AWS secret name\n  - `piggysec.com/aws-region` - set a value to your AWS secret manager region\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: myapp\n  annotations:\n    piggysec.com/piggy-address: https://piggy-webhooks.piggy-webhooks.svc.cluster.local\n    piggysec.com/aws-secret-name: myapp/sample\n    piggysec.com/aws-region: ap-southeast-1\nspec:\n  containers:\n    - image: myapp:v1\n      name: myapp\n      env:\n        - name: TEST_ENV\n          value: piggy:TEST_ENV\n```\n\nThen you can read the `TEST_ENV` value from environment variable.\n\n```go\nfunc main() {\n  val := os.Getenv(\"TEST_ENV\")\n  fmt.Printf(\"%s\", val)\n}\n```\n\n### Restrict process to run\n\nSet [piggy-enforce-integrity](https://github.com/KongZ/piggy/blob/main/docs/annotations.md#piggy-enforce-integrity) annotation to `true` (default is true) will restrict piggy-env to resolve the variable only process defined on container arguments.\n\n### Limit secrets injection only allowed service accounts\n\nYou may improve security by restrict only Pod service account to read the secrets.\nYou can limit access by adding variable name `PIGGY_ALLOWED_SA` to AWS secret where value is `namespace:service_account` name.\n\nThe Piggy Webhooks will not inject secrets into containers if the Pod service account name is not matched with value of `PIGGY_ALLOWED_SA`.\n\nYou can add multiple service account name by separate each name with comma.\n\nFor example:\n\n```bash\nmyapp-namespace:myapp,myanotherapp-namespace:default\n```\n\n### Preventing unauthorized pods to read secrets\n\nThe Piggy provides 3 concepts to protect secrets.\n\n  - By enabling [piggy-enforce-integrity](https://github.com/KongZ/piggy/blob/main/docs/annotations.md#piggy-enforce-integrity). The Piggy will generate a check sum using SHA256 algorithm from a container command.\n  Then piggy-env will generate another check sum on running command every time when communicate with piggy-webhooks. If the check sum is not matched with original value, it will reject the request.\n  For example, if your container starts with command `rails server`, you won't be able to `exec` into pod and run `rails console` to get secrets. This option is enabled by default.\n  - Piggy will generate a UID for each containers during mutation process. If the requests from container is not matched the UID which was generated, it will reject.\n  - Uses [PIGGY_ALLOWED_SA](https://github.com/KongZ/piggy#limit-secrets-injection-only-allowed-service-accounts) to limit access to secrets by service account name\n\n### Default secret name\n\nYou can set the secret name from annotation `piggysec.com/aws-secret-name` but in proxy mode, you can remove this annotation.\nThe Piggy Webhooks will read secrets from default secret name which format is `${prefix}${namespace}/${service_account}${suffix}`\n\nFor example, if you do not set prefix and suffix, the default secret name of Pods which service account name `default` and namespace `demo` is `demo/default`\n\nYou can optionally set prefix of default secret name by set ENV `PIGGY_DEFAULT_SECRET_NAME_PREFIX` on Piggy Webhooks and suffix by set ENV `PIGGY_DEFAULT_SECRET_NAME_SUFFIX`\n\nFor example, if `PIGGY_DEFAULT_SECRET_NAME_SUFFIX=/production`, the default secret name of sample above will be `/demo/default/production`\n\nYou can see examples at [https://github.com/KongZ/piggy/tree/main/demo]\n\n### Default AWS Region\n\nYou can set default AWS Region by set ENV `AWS_REGION` on Piggy Webhooks. If `AWS_REGION` is set on Piggy Webhooks, you do not need to set an annotation `piggysec.com/aws-region` on Pod. In other word, the settings on Piggy Webhooks ENV can be overridden by pods annotations.\n\nYou can see examples at [https://github.com/KongZ/piggy/tree/main/demo]\n\n## Standalone mode\n\nThe standalone mode will not use Piggy Webhooks to inject secrets into containers. It will requires Pod service account with IRSA to\nread the secrets from AWS Secret Manager. You can enable standalone mode by adding annotation `piggysec.com/standalone: \"true\"` to Pod\n\n```bash\n     (1)  ┌───────────┐ (6)\n     ───▶ │           │ ───▶\n   ───────│ Container │───────\n          │           │\n          └───────────┘\n             │     │\n             │     │\n      ┌──────┘     └─────┐▲\n     ││▲                │││(3)\n  (4)│││(5)          (2)│││\n     ▼││                ▼│\n┌───────────┐      ┌───────────┐\n│AWS Secret │      │           │\n│  Manager  │      │  AWS STS  │\n│           │      │           │\n└───────────┘      └───────────┘\n```\n\nSince the standalone mode does not use Piggy Webhooks thus the Pod must have a permission to read secrets from AWS Secret Manager.\nYou need to setup AWS IRSA with at least this permission\n\n```yaml\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"PiggySecretReadOnly\",\n      \"Action\": [\n        \"secretsmanager:DescribeSecret\",\n        \"secretsmanager:GetResourcePolicy\",\n        \"secretsmanager:GetSecretValue\",\n        \"secretsmanager:ListSecretVersionIds\",\n        \"secretsmanager:ListSecrets\"\n      ],\n      \"Effect\": \"Allow\",\n      \"Resource\": \"${your-secret-name-arn}\"\n    }\n  ]\n}\n```\n\nThen add then follow annotations to Pod. You may notice, you don't have to provide the Piggy Webhooks address in this mode.\n\n  - `piggysec.com/aws-secret-name` - set a value to your AWS secret name\n  - `piggysec.com/aws-region` - set a value to your AWS secret manager region\n  - `piggysec.com/standalone` - set a value to true\n\n```yaml\napiVersion: v1\nkind: Pod\nmetadata:\n  name: myapp\n  annotations:\n    piggysec.com/aws-secret-name: omise-staging/sample/test\n    piggysec.com/aws-region: ap-southeast-1\n    piggysec.com/standalone: \"true\"\nspec:\n  serviceAccount: myapp\n  containers:\n    - image: myapp:v1\n      name: myapp\n      volumeMounts:\n        - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount\n          name: aws-iam-token\n          readOnly: true\n      env:\n        - name: TEST_ENV\n          value: piggy:TEST_ENV\n        - name: AWS_ROLE_ARN\n          value: ${your-role-arn}\n        - name: AWS_WEB_IDENTITY_TOKEN_FILE\n          value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token\n  volumes:\n    - name: aws-iam-token\n      projected:\n        defaultMode: 420\n        sources:\n        - serviceAccountToken:\n            audience: sts.amazonaws.com\n            expirationSeconds: 86400\n            path: token\n```\n\nAnd the service account\n\n```yaml\napiVersion: v1\nkind: ServiceAccount\nmetadata:\n  name: myapp\n  annotations:\n    eks.amazonaws.com/role-arn: ${your-role-arn}\n\n```\n\nNote: in standalone mode, piggy-env talks directly to AWS secret manager without talking to Kubernetes API or piggy-webhooks.\nThe secrets is fully protected by AWS role permissions.\n\n## How does it work\n\nWhen application is deployed on Kubernetes, the Kubernetes API will send admission request to Piggy webhooks. The Piggy webhooks will mutate the\npods and injecting secrets into containers\n\n```bash\n (1)   ┌───────────┐  (2)   ┌───────────┐ (5)   ┌───────────┐ (6)   ┌───────────┐\n ───▶  │           │  ───▶  │ Mutating  │ ───▶  │  Object   │ ───▶  │           │\n───────│Create Pod │────────│ Admission │───────│Validation │───────│ Persisted │\n       │           │        │           │       │           │       │           │\n       └───────────┘        └───────────┘       └───────────┘       └───────────┘\n                                  │\n                                «tls»\n                                  │▲\n                                 │││(4)\n                              (3)│││\n                                 ▼│\n                            ┌───────────┐\n                            │   Piggy   │\n                            │ Webhooks  │\n                            │           │\n                            └───────────┘\n```\n\nSee [how it works](https://github.com/KongZ/piggy/tree/main/docs/how-it-works.md)\n\n## Choose the Secret Version\n\nYou can specify the unique identifier of the version of the secret to retrieve. If you don't specify the piggy returns the AWSCURRENT version. To specify the secret version, annotate the pods with `piggysec.com/aws-secret-version` where the value is the unique identifier of the version.\n\n## Annotations\n\nSee [annotations](https://github.com/KongZ/piggy/tree/main/docs/annotations.md)\n\n## SSM Parameter Store\n\nThe piggy also support SSM Parameter Store. To retrieve secrets from parameter store, you will just add an annotation `piggysec.com/aws-ssm-parameter-path`. The piggy automatically detect this annotation and pull the secrets from parameter store instead of secret manager.\n\n*Note:* it support only [GetParameterByPath](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetParametersByPath.html) so referencing AWS Secrets Manager secrets from Parameter Store parameters is not supported yet.\n\nAnnotations\n\n### Parameter path\n\nThe parameter store is reference in a [hierarchy](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-su-create.html). The `piggysec.com/aws-ssm-parameter-path` annotation will refer to parameter path and name will be a last value of path. For example:\n\n![ssm_parameter_store](https://raw.githubusercontent.com/KongZ/piggy/main/docs/images/ssm_parameter_store.png \"ssm_parameter_store\")\n\nThe annotation is\n\n```yaml\npiggysec.com/aws-ssm-parameter-path: /demo/sample/test\n```\n\nAnd the environment variable are\n\n```yaml\n- name: TEST_ENV\n  value: piggy:TEST_ENV\n- name: TEST_LIST\n  value: piggy:TEST_LIST\n- name: TEST_PLAIN\n  value: piggy:TEST_PLAIN\n```\n\n### Policy for SSM Parameter Store\n\nRequired `ssm:GetParametersByPath` permission for reading parameter store.\n\nExample minimum policy for reading value from SSM Parameter Store\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"PiggySSM\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"ssm:GetParametersByPath\"\n      ],\n      \"Resource\": \"*\"\n    },\n    {\n      \"Sid\": \"PiggyECRReadOnly\",\n      \"Action\": [\n        \"ecr:BatchCheckLayerAvailability\",\n        \"ecr:BatchGetImage\",\n        \"ecr:DescribeImages\",\n        \"ecr:GetAuthorizationToken\",\n        \"ecr:GetDownloadUrlForLayer\"\n      ],\n      \"Effect\": \"Allow\",\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n\n## License\n\nLicensed 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\n\n\u003chttp://www.apache.org/licenses/LICENSE-2.0/\u003e\n\nUnless 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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKongZ%2Fpiggy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKongZ%2Fpiggy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKongZ%2Fpiggy/lists"}