{"id":37191458,"url":"https://github.com/chainguard-dev/admission-sidecar","last_synced_at":"2026-01-14T22:10:53.328Z","repository":{"id":52378672,"uuid":"515711003","full_name":"chainguard-dev/admission-sidecar","owner":"chainguard-dev","description":"Generic webhook controller / proxy for ease of integration with Styra in particular.","archived":true,"fork":false,"pushed_at":"2024-01-18T04:04:03.000Z","size":239,"stargazers_count":8,"open_issues_count":5,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-22T00:05:29.343Z","etag":null,"topics":[],"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/chainguard-dev.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}},"created_at":"2022-07-19T19:09:16.000Z","updated_at":"2024-01-18T22:51:49.000Z","dependencies_parsed_at":"2023-02-16T15:00:31.238Z","dependency_job_id":"0eedca0b-061b-4da1-9496-d6e8278ffbe1","html_url":"https://github.com/chainguard-dev/admission-sidecar","commit_stats":{"total_commits":29,"total_committers":5,"mean_commits":5.8,"dds":0.3793103448275862,"last_synced_commit":"6a459276578a8e7ce8dc5756646e9fc3604c10b0"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/chainguard-dev/admission-sidecar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fadmission-sidecar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fadmission-sidecar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fadmission-sidecar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fadmission-sidecar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainguard-dev","download_url":"https://codeload.github.com/chainguard-dev/admission-sidecar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Fadmission-sidecar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28436268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T21:32:52.117Z","status":"ssl_error","status_checked_at":"2026-01-14T21:32:33.442Z","response_time":107,"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":[],"created_at":"2026-01-14T22:10:52.416Z","updated_at":"2026-01-14T22:10:53.321Z","avatar_url":"https://github.com/chainguard-dev.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# admission-sidecar\n\nSide car meant to run along side of Styra (or other things like that) which\nallow for proxying through it to 'real' k8s webhooks. Reconciles configurations\nand makes them available for easier calling from other places.\n\nExposes webhooks via:\n```\nhttp://\u003caddress of this webhook\u003e/[admit|mutate]/\u003cname-of-the-k8s-webhook\u003e\n```\n\nWhen injected as a sidecar container, by default the URL is:\n```\nhttp://localhost:8088/[admit|mutate]/name-of-the-k8s-webhook\n```\n\n# Controlling level of enforcement\n\nBy default the proxy requires the namespace of the resource to be labeled with\nthe following label. If label is not there, proxy will return Allowed\nadmission response.\n```\nproxy.chainguard.dev/include=true\n```\n\nThis behaviour can be changed with environment variable `REQUIRE_LABEL` when\nstarting proxy. Setting it to \"false\" will mean that proxy will not require the\nlabel, and resources in all namespaces are handled by the proxy.\n\n# Styra Integration\n\nTo patch this into a running OPA system, we add our container into the mix like\nso. The patch below shows how to patch in\n[release-v0.0.1-rc.2](https://github.com/chainguard-dev/admission-sidecar/releases/tag/v0.0.1-rc.2)\n\n```\nkubectl patch statefulset opa -n styra-system --type \"json\" -p '[{\"op\":\"add\",\"path\":\"/spec/template/spec/containers/2\",\"value\": {\"env\":[{\"name\":\"SYSTEM_NAMESPACE\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"metadata.namespace\"}}},{\"name\":\"POD_IP\",\"valueFrom\":{\"fieldRef\":{\"apiVersion\":\"v1\",\"fieldPath\":\"status.podIP\"}}},{\"name\":\"CONFIG_LOGGING_NAME\",\"value\":\"config-logging\"},{\"name\":\"CONFIG_OBSERVABILITY_NAME\",\"value\":\"config-observability\"},{\"name\":\"METRICS_DOMAIN\",\"value\":\"chainguard.dev/admission-sidecar\"}],\"image\":\"ghcr.io/chainguard-dev/admission-sidecar/admission-sidecar:v0.0.1-rc.2\",\"imagePullPolicy\":\"IfNotPresent\",\"livenessProbe\":{\"failureThreshold\":50,\"httpGet\":{\"httpHeaders\":[{\"name\":\"k-kubelet-probe\",\"value\":\"admission-sidecar\"}],\"path\":\"/\",\"port\":8088,\"scheme\":\"HTTP\"},\"periodSeconds\":1,\"successThreshold\":1,\"timeoutSeconds\":1},\"name\":\"controller\",\"ports\":[{\"containerPort\":8088,\"name\":\"http-webhook\",\"protocol\":\"TCP\"}],\"readinessProbe\":{\"failureThreshold\":3,\"httpGet\":{\"httpHeaders\":[{\"name\":\"k-kubelet-probe\",\"value\":\"admission-sidecar\"}],\"path\":\"/\",\"port\":8088,\"scheme\":\"HTTP\"},\"periodSeconds\":1,\"successThreshold\":1,\"timeoutSeconds\":1},\"resources\":{\"limits\":{\"cpu\":\"1\",\"memory\":\"1000Mi\"},\"requests\":{\"cpu\":\"50m\",\"memory\":\"50Mi\"}},\"securityContext\":{\"allowPrivilegeEscalation\":false,\"capabilities\":{\"drop\":[\"all\"]},\"readOnlyRootFilesystem\":true,\"runAsNonRoot\":true},\"terminationMessagePath\":\"/dev/termination-log\",\"terminationMessagePolicy\":\"File\"}}]'\n```\n\nFor readability, the patch request is shown here pretty printed:\n```json\n{\n  \"op\": \"add\",\n  \"path\": \"/spec/template/spec/containers/2\",\n  \"value\": {\n    \"env\": [\n      {\n        \"name\": \"SYSTEM_NAMESPACE\",\n        \"valueFrom\": {\n          \"fieldRef\": {\n            \"apiVersion\": \"v1\",\n            \"fieldPath\": \"metadata.namespace\"\n          }\n        }\n      },\n      {\n        \"name\": \"POD_IP\",\n        \"valueFrom\": {\n          \"fieldRef\": {\n            \"apiVersion\": \"v1\",\n            \"fieldPath\": \"status.podIP\"\n          }\n        }\n      },\n      {\n        \"name\": \"CONFIG_LOGGING_NAME\",\n        \"value\": \"config-logging\"\n      },\n      {\n        \"name\": \"CONFIG_OBSERVABILITY_NAME\",\n        \"value\": \"config-observability\"\n      },\n      {\n        \"name\": \"METRICS_DOMAIN\",\n        \"value\": \"chainguard.dev/admission-sidecar\"\n      }\n    ],\n    \"image\": \"ghcr.io/chainguard-dev/admission-sidecar/admission-sidecar:v0.0.1-rc.2\",\n    \"imagePullPolicy\": \"IfNotPresent\",\n    \"livenessProbe\": {\n      \"failureThreshold\": 50,\n      \"httpGet\": {\n        \"httpHeaders\": [\n          {\n            \"name\": \"k-kubelet-probe\",\n            \"value\": \"admission-sidecar\"\n          }\n        ],\n        \"path\": \"/\",\n        \"port\": 8088,\n        \"scheme\": \"HTTP\"\n      },\n      \"periodSeconds\": 1,\n      \"successThreshold\": 1,\n      \"timeoutSeconds\": 1\n    },\n    \"name\": \"controller\",\n    \"ports\": [\n      {\n        \"containerPort\": 8088,\n        \"name\": \"http-webhook\",\n        \"protocol\": \"TCP\"\n      }\n    ],\n    \"readinessProbe\": {\n      \"failureThreshold\": 3,\n      \"httpGet\": {\n        \"httpHeaders\": [\n          {\n            \"name\": \"k-kubelet-probe\",\n            \"value\": \"admission-sidecar\"\n          }\n        ],\n        \"path\": \"/\",\n        \"port\": 8088,\n        \"scheme\": \"HTTP\"\n      },\n      \"periodSeconds\": 1,\n      \"successThreshold\": 1,\n      \"timeoutSeconds\": 1\n    },\n    \"resources\": {\n      \"limits\": {\n        \"cpu\": \"1\",\n        \"memory\": \"1000Mi\"\n      },\n      \"requests\": {\n        \"cpu\": \"50m\",\n        \"memory\": \"50Mi\"\n      }\n    },\n    \"securityContext\": {\n      \"allowPrivilegeEscalation\": false,\n      \"capabilities\": {\n        \"drop\": [\n          \"all\"\n        ]\n      },\n      \"readOnlyRootFilesystem\": true,\n      \"runAsNonRoot\": true\n    },\n    \"terminationMessagePath\": \"/dev/termination-log\",\n    \"terminationMessagePolicy\": \"File\"\n  }\n}\n```\n\n\n# Then for Styra you can add a Validating Rule that looks like this:\n\n```\npackage policy[\"com.styra.kubernetes.validating\"].rules.rules\nenforce[decision] {\n  #title: chainguard-proxy\n  input.request.kind.kind == \"Pod\"\n  admissionresponse := http.send({\"raise_error\": true, \"url\": \"http://localhost:8088/admit/\u003cwebhook you want to hit\u003e\", \"body\": input, \"method\": \"POST\", \"force_json_decode\": true})\n  response := json.unmarshal(admissionresponse.raw_body)\n  msg := sprintf(\"Enforce Response: (%v)\", [response.response])\n  decision := {\n    \"allowed\": response.response.allowed == true,\n    \"message\": msg\n  }\n}\n```\n\n# Open questions\n\nBecause validatingwebhookconfiguration has a name, and each webhook has a name,\nwe might need a two level naming scheme in the above, something like:\n\n```\nhttp://localhost:8088/admit/\u003cvalidatingwebhookconfiguration name\u003e/\u003cwebhookname\u003e\n```\n\nHowever, empirical evidence suggests that you can't (at least on GKE that I'm\nrunning) have multiple webhooks even though it accepts multiple, it only keeps\none.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainguard-dev%2Fadmission-sidecar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchainguard-dev%2Fadmission-sidecar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainguard-dev%2Fadmission-sidecar/lists"}