{"id":22930718,"url":"https://github.com/kubewarden/policy-sdk-go","last_synced_at":"2025-08-12T15:31:50.463Z","repository":{"id":37905420,"uuid":"349421874","full_name":"kubewarden/policy-sdk-go","owner":"kubewarden","description":"Kubewarden Policy SDK for the Go programming language","archived":false,"fork":false,"pushed_at":"2025-07-03T15:37:40.000Z","size":1240,"stargazers_count":9,"open_issues_count":10,"forks_count":8,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-03T16:46:20.206Z","etag":null,"topics":["go","hacktoberfest","kubernetes","kubernetes-security","kubewarden-policy-sdk","policy-as-code","tinygo","webassembly"],"latest_commit_sha":null,"homepage":"https://kubewarden.io","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/kubewarden.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":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-03-19T12:51:58.000Z","updated_at":"2025-07-03T15:37:44.000Z","dependencies_parsed_at":"2024-01-15T17:47:42.802Z","dependency_job_id":"6ef1db4c-d201-4b90-99a8-0946d999d3a0","html_url":"https://github.com/kubewarden/policy-sdk-go","commit_stats":{"total_commits":137,"total_committers":13,"mean_commits":"10.538461538461538","dds":0.7007299270072993,"last_synced_commit":"31871c9fa0bd63a7d6b0dcf163bdb1835d690280"},"previous_names":["chimera-kube/policy-sdk-go"],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/kubewarden/policy-sdk-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubewarden%2Fpolicy-sdk-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubewarden%2Fpolicy-sdk-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubewarden%2Fpolicy-sdk-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubewarden%2Fpolicy-sdk-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kubewarden","download_url":"https://codeload.github.com/kubewarden/policy-sdk-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubewarden%2Fpolicy-sdk-go/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270086718,"owners_count":24524626,"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","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["go","hacktoberfest","kubernetes","kubernetes-security","kubewarden-policy-sdk","policy-as-code","tinygo","webassembly"],"created_at":"2024-12-14T10:29:29.518Z","updated_at":"2025-08-12T15:31:50.454Z","avatar_url":"https://github.com/kubewarden.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Stable](https://img.shields.io/badge/status-stable-brightgreen?style=for-the-badge)](https://github.com/kubewarden/community/blob/main/REPOSITORIES.md#stable)\n[![GoDoc](https://godoc.org/github.com/kubewarden/policy-sdk-go?status.svg)](https://godoc.org/github.com/kubewarden/policy-sdk-go)\n\n\u003e Don't forget to take a look at [Kubewarden's official documentation](https://docs.kubewarden.io).\n\u003e The docs cover step-by-step instructions about how to write policies.\n\n# Kubewarden Go Policy SDK\n\nThis module provides a SDK that can be used to write [Kubewarden\nPolicies](https://github.com/kubewarden/) using the Go programming\nlanguage.\n\nDue to current Go compiler limitations, Go policies must be built\nusing [TinyGo](https://github.com/tinygo-org/tinygo).\n\n## Known limitations of TinyGo\n\nTinyGo doesn't have full support of the Go Standard Library. However, this\nshouldn't pose a limit to policy authors.\n\n# Validation\n\nThis SDK provides helper methods to accept and reject validation requests.\n\nA validation policy consists of these steps:\n\n1. Extract the object to inspect from the incoming payload\n2. (Optional) Extract the settings object from the incoming payload.\n3. Validation code\n4. Communicate the outcome of the validation: accept/reject\n\nThe 4th step is done using helper functions provided by this SDK.\n\nAs for the 1st step, there are two approaches that can be used.\n\n## Perform \"jq-like\" searches\n\nThe policy receives as input a `payload` parameter of type `[]byte`. This\ncontains the JSON document described [here](https://docs.kubewarden.io/writing-policies/spec/validating-policies#the-validationrequest-object).\n\nPolicy authors can leverage the [`github.com/tidwall/gjson`](https://github.com/tidwall/gjson)\npackage to search for data inside of this JSON document.\n\nFor example, assume you want to validate the `labels` that are inside of\na Kubernetes object. This can be done with this snippet:\n\n```go\ndata := gjson.GetBytes(\n  payload,\n  \"request.object.metadata.labels\")\n\nlabels := mapset.NewThreadUnsafeSet()\ndenied_labels_violations := []string{}\nconstrained_labels_violations := []string{}\n\ndata.ForEach(func(key, value gjson.Result) bool {\n  label := key.String()\n  labelValue := value.String()\n  // do something with label and labelValue\n\n  return true\n})\n```\n\nThis _\"jq-like\"_ approach can be pretty handy when the policy has to look\ndeep inside of a Kubernetes object. This is especially helpful when dealing with\ninner objects that are optional.\n\n## Use native Go types\n\nThe majority of policies target a specific type of Kubernetes resource, like\nPod, Ingress, Service and similar. Because of that, another possible approach\nis to unmarshal the incoming object into a native Go type.\n\nTinyGo doesn't yet support the full Go Standard Library, plus it has limited\nsupport of Go reflection.\nBecause of that, it is not possible to import the official Kubernetes Go library\nfrom upstream (e.g.: `k8s.io/api/core/v1`).\nImporting these official Kubernetes types will result in a compilation failure.\n\nMoreover, Kubewarden provides TinyGo friendly Go types for all the Kubernetes\ntypes inside of the [`github.com/kubewarden/k8s-objects`](https://github.com/kubewarden/k8s-objects)\npackage.\n\nUsing this SDK requires **TinyGo 0.28.1 or later.**\n\n\u003e **Warning**\n\u003e Using an older version of TinyGo will result in runtime errors due to the limited support for Go reflection.\n\n### Example\n\nThis snippet shows how to implement a `validation` function that uses the\n\"native Go types\" approach:\n\n```go\n// Create a ValidationRequest instance from the incoming payload\nvalidationRequest := kubewarden_protocol.ValidationRequest{}\nerr := json.Unmarshal(payload, \u0026validationRequest)\nif err != nil {\n\treturn kubewarden.RejectRequest(\n\t\tkubewarden.Message(err.Error()),\n\t\tkubewarden.Code(400))\n}\n\n// Access the **raw** JSON that describes the object\ningressJSON := validationRequest.Request.Object\n\n// Try to create an Ingress instance using the RAW JSON we got from the\n// ValidationRequest.\n// This policy works only against Ingress objects, if the creation fails\n// we reject the request and provide a meaningful error.\ningress := \u0026networkingv1.Ingress{}\nif err := json.Unmarshal([]byte(ingressJSON), ingress); err != nil {\n\treturn kubewarden.RejectRequest(\n\t\tkubewarden.Message(\n\t\tfmt.Sprintf(\"Cannot decode Ingress object: %s\", err.Error())),\n\t\tkubewarden.Code(400))\n}\n\n// the validation logic\n```\n\n**Note:** the `github.com/kubewarden/k8s-objects` package is organized\nin the same way as the official `k8s.io` one.\n\n# Mutating policy\n\nMutation policies works exactly like the validation ones. The only difference\nis that, when a request has to be accepted AND mutated, the policy must return\nthe input object with all the required changes applied.\n\nMutation policies can be done by leveraging the Kubernetes Go types\ndefined inside of the `github.com/kubewarden/k8s-objects` package and\nthe helper methods provided by this SDK.\n\nThe following example defines a mutating policy that always changes the name of\nIngress objects:\n\n```go\nimport (\n    \"encoding/json\"\n\t\"fmt\"\n\n\tnetworkingv1 \"github.com/kubewarden/k8s-objects/api/networking/v1\"\n\tkubewarden \"github.com/kubewarden/policy-sdk-go\"\n\n)\n\nfunc validate(payload []byte) ([]byte, error) {\n  // Create a ValidationRequest instance from the incoming payload\n  validationRequest := kubewarden_protocol.ValidationRequest{}\n  err := json.Unmarshal(payload, \u0026validationRequest)\n  if err != nil {\n    return kubewarden.RejectRequest(\n      kubewarden.Message(err.Error()),\n      kubewarden.Code(400))\n  }\n\n  // Access the **raw** JSON that describes the object\n  ingressJSON := validationRequest.Request.Object\n\n  // Try to create a Ingress instance using the RAW JSON we got from the\n  // ValidationRequest.\n  // This policy works only against Ingress objects, if the creation fails\n  // we reject the request and provide a meaningful error.\n  ingress := \u0026networkingv1.Ingress{}\n  if err := json.Unmarshal([]byte(ingressJSON), ingress); err != nil {\n    return kubewarden.RejectRequest(\n      kubewarden.Message(\n      fmt.Sprintf(\"Cannot decode Ingress object: %s\", err.Error())),\n      kubewarden.Code(400))\n  }\n\n  ingress.Metadata.Name = fmt.Sprintf(\"%s-changed\", ingress.Metadata.Name)\n\n  return kubewarden.MutateRequest(ingress)\n}\n```\n\n# Logging\n\nPolicies can generate log messages that are then propagated to the host\nenvironment (eg: [kwctl](https://github.com/kubewarden/kwctl),\n[policy-server](https://github.com/kubewarden/policy-server)).\n\nThis Go module provides logging capabilities that integrate with the\n[onelog](https://github.com/francoispqt/onelog) project.\n\nThis logging solution has been chosen because:\n\n- It works also with WebAssembly binaries. Other popular logging solutions\n  cannot even be built to WebAssembly.\n- It provides [good performance](https://github.com/francoispqt/onelog#benchmarks)\n- It supports structured logging.\n\n## Usage\n\nThe instructions provided by the official\n[onelog](https://github.com/francoispqt/onelog) project apply also to Kubewarden\npolicies.\n\nThe `onelog.Logger` instance must be configured to use a `KubewardenLogWriter`\nobject.\n\n```go\n\tkl := kubewarden.KubewardenLogWriter{}\n\tlogger := onelog.New(\n\t\t\u0026kl,\n\t\tonelog.ALL, // shortcut for onelog.DEBUG|onelog.INFO|onelog.WARN|onelog.ERROR|onelog.FATAL,\n\t)\n\tlogger.Info(\"info message from tinygo\")\n\tlogger.DebugWithFields(\"i'm not sure what's going on\", func(e onelog.Entry) {\n\t\te.String(\"string\", \"foobar\")\n\t\te.Int(\"int\", 12345)\n\t\te.Int64(\"int64\", 12345)\n\t\te.Float(\"float64\", 0.15)\n\t\te.Bool(\"bool\", true)\n\t\te.Err(\"err\", errors.New(\"someError\"))\n\t\te.ObjectFunc(\"user\", func(e onelog.Entry) {\n\t\t\te.String(\"name\", \"somename\")\n\t\t})\n\t})\n```\n\n# Host capabilities\n\nThe policy executor exposes additional capabilities that can be leveraged by the\nguest.\n\nThese capabilities are exposed to the Go policies via this SDK, through the `Host`\ntype defined inside of `github.com/kubewarden/policy-sdk-go/capabilities`.\n\n## Get OCI manifest digest\n\nThe policy can request the digest of an OCI manifest. This can be used to\nget the immutable reference of a container Image or anything that is stored\ninside of a container registry (e.g. Kubewarden Policies, Helm charts,...).\n\n```go\nhost := capabilities.NewHost()\ndigest, err := host.GetOCIManifestDigest(\"busybox:latest\")\n```\n\n## Hostname DNS lookup\n\nThe policy can lookup the addresses for a given hostname by using the\nDNS resolvers of the host that is evaluating the policy.\n\n```go\nhost := capabilities.NewHost()\nips, err := host.LookupHost(\"kubewarden.io\")\n```\n\n## Sigstore verification\n\nThe policy can ask the host to perform verification operations against\nobjects stored inside of container registries (e.g. container image, kubewarden\npolicy, helm chart,...) leveraging the [Sigstore](https://sigstore.dev) primitives.\n\nCurrently this SDK exposes helper function that can perform verification using\npublic keys and using the Sigstore keyless mechanism.\n\n# Testing\n\n[![GoDoc](https://godoc.org/github.com/kubewarden/policy-sdk-go/testing?status.svg)](https://godoc.org/github.com/kubewarden/policy-sdk-go/testing)\n\nThe `kubewarden/policy-sdk-go/testing` module provides some test helpers\nthat simplify the process of writing unit tests.\n\n## Host capabilities\n\nThe Go unit tests of a policy are **not** run inside of a WebAssembly environment,\nthey are instead built into a native executable using the official Go compiler.\n\nBecause of that, at test time the host capabilities have to be mocked. This is also\nuseful to write ad-hoc tests that can handle different kind of responses coming\nfrom the host.\n\nThe `Host` type described above relies on an internal `waPC` client that\ninteracts with the host. At test time, the client is an instance of\n`MockWapcClient`.\n\nDevelopers can create `MockWapcClient` instances using the `NewMockWapcClient`\nhelper method from the `capabilities` package. It is used as follows:\n\n```go\nmockWapcClient := \u0026mocks.MockWapcClient{}\nmockWapcClient.On(\"HostCall\", \"kubewarden\", \"kubernetes\", \"get_resource\", request).Return(wapcResponse, nil)\n```\n\n# Project template\n\nWe provide a GitHub repository template that can be used to quickly\nscaffold a new Kubewarden policy writing Go.\n\nThis can be found [here](https://github.com/kubewarden/go-policy-template).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkubewarden%2Fpolicy-sdk-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkubewarden%2Fpolicy-sdk-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkubewarden%2Fpolicy-sdk-go/lists"}