{"id":21926600,"url":"https://github.com/freepik-company/admitik","last_synced_at":"2026-03-12T16:12:27.509Z","repository":{"id":260518570,"uuid":"880032514","full_name":"freepik-company/admitik","owner":"freepik-company","description":"🛡️ Cloud native policy engine for Kubernetes: validates, mutates, generates, clean (and more) based on conditions defined on powerful templates","archived":false,"fork":false,"pushed_at":"2026-03-04T02:22:27.000Z","size":1522,"stargazers_count":24,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-03-04T02:35:43.555Z","etag":null,"topics":["admission","cel","clean","cloud-native","generation","golang","gotmpl","kubernetes","mutation","operator","production","starlark","validation"],"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/freepik-company.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","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}},"created_at":"2024-10-29T01:42:17.000Z","updated_at":"2026-03-03T16:40:24.000Z","dependencies_parsed_at":"2024-10-31T19:30:54.600Z","dependency_job_id":"a15f3078-58db-43e6-a3f1-e79753b9bfb5","html_url":"https://github.com/freepik-company/admitik","commit_stats":null,"previous_names":["achetronic/admitik"],"tags_count":78,"template":false,"template_full_name":null,"purl":"pkg:github/freepik-company/admitik","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freepik-company%2Fadmitik","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freepik-company%2Fadmitik/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freepik-company%2Fadmitik/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freepik-company%2Fadmitik/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/freepik-company","download_url":"https://codeload.github.com/freepik-company/admitik/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freepik-company%2Fadmitik/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30431971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T14:34:45.044Z","status":"ssl_error","status_checked_at":"2026-03-12T14:09:33.793Z","response_time":114,"last_error":"SSL_read: 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":["admission","cel","clean","cloud-native","generation","golang","gotmpl","kubernetes","mutation","operator","production","starlark","validation"],"created_at":"2024-11-28T22:09:17.929Z","updated_at":"2026-03-12T16:12:27.483Z","avatar_url":"https://github.com/freepik-company.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Admitik\n\n\u003cimg src=\"https://raw.githubusercontent.com/achetronic/admitik/master/docs/img/logo.png\" alt=\"Admitik Logo (Main) logo.\" width=\"150\"\u003e\n\n![GitHub go.mod Go version (subdirectory of monorepo)](https://img.shields.io/github/go-mod/go-version/freepik-company/admitik)\n![GitHub](https://img.shields.io/github/license/freepik-company/admitik)\n\n![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCeSb3yfsPNNVr13YsYNvCAw?label=achetronic\u0026link=http%3A%2F%2Fyoutube.com%2Fachetronic)\n![GitHub followers](https://img.shields.io/github/followers/achetronic?label=achetronic\u0026link=http%3A%2F%2Fgithub.com%2Fachetronic)\n![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/achetronic?style=flat\u0026logo=twitter\u0026link=https%3A%2F%2Ftwitter.com%2Fachetronic)\n\n\nA dynamic Kubernetes admission controller that validates or modifies resources based on conditions you define using Helm templates.\n\nIt can retrieve data from other resources and inject it into templates, allowing for customizable conditions and messages.\n\n\n\n## Motivation\n\nKubernetes has not an implementation of an admission controller to validate/mutate resources.\nInstead, it leverages its creation to the clusters administrators.\n\nThis project was initiated to fill that gap by providing a potent and flexible admission controller.\nIt allows for dynamic validation and mutation of resources, using data from other resources and\nenabling conditions and messages defined through Helm templates.\n\nOur goal is to equip administrators with a tool that offers greater control and adaptability\nin managing Kubernetes resources due to:\n\n1. There are Kubernetes clusters where resources are introduced from a multitude of sources,\n   where maintaining harmony and preventing conflicts in production environments is a significant challenge.\n\n   It's essential to have a comprehensive set of policies that can enforce rules and prevent\n   resource collisions effectively.\n\n2. Existing solutions often fall short—they may not offer the level of power and dynamism\n   necessary to address complex deployment scenarios.\n\n\n\n## Deployment\n\nWe have designed the deployment of this project to allow remote deployment using Kustomize or Helm. This way it is possible\nto use it with a GitOps approach, using tools such as ArgoCD or FluxCD.\n\nIf you prefer Kustomize, just make a Kustomization manifest referencing\nthe tag of the version you want to deploy as follows:\n\n```yaml\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nresources:\n- https://github.com/freepik-company/admitik/releases/download/v0.1.0/install.yaml\n```\n\n\u003e 🧚🏼 **Hey, listen! If you prefer to deploy using Helm, go to the [Helm registry](https://freepik-company.github.io/admitik/)**\n\n\n## Flags\n\nSome configuration parameters can be defined by flags that can be passed to the controller.\nThey are described in the following table:\n\n| Name                                   | Description                                                                    |        Default         |\n|:---------------------------------------|:-------------------------------------------------------------------------------|:----------------------:|\n| `--metrics-bind-address`               | The address the metric endpoint binds to. \u003c/br\u003e 0 disables the server          |          `0`           |\n| `--health-probe-bind-address`          | he address the probe endpoint binds to                                         |        `:8081`         |\n| `--leader-elect`                       | Enable leader election for controller manager                                  |        `false`         |\n| `--metrics-secure`                     | If set the metrics endpoint is served securely                                 |        `false`         |\n| `--enable-http2`                       | If set, HTTP/2 will be enabled for the metrirs                                 |        `false`         |\n| `--sources-time-to-resync-informers`   | Interval to resynchronize all resources in the informers                       |         `60s`          |\n| `--sources-time-to-reconcile-watchers` | Time between each reconciliation loop of the watchers                          |         `10s`          |\n| `--sources-time-to-ack-watcher`        | Wait time before marking a watcher as acknowledged (ACK) after it starts       |          `2s`          |\n| `--webhook-client-hostname`            | The hostname used by Kubernetes when calling the webhooks server               | `webhooks.admitik.svc` |\n| `--webhook-client-port`                | The port used by Kubernetes when calling the webhooks server                   |        `10250`         |\n| `--webhook-client-timeout`             | The seconds until timout waited by Kubernetes when calling the webhooks server |          `10`          |\n| `--webhook-server-port`                | The port where the webhooks server listens                                     |        `10250`         |\n| `--webhook-server-path`                | The path where the webhooks server listens                                     |      `/validate`       |\n| `--webhook-server-ca`                  | The CA bundle to use for the webhooks server                                   |          `-`           |\n| `--webhook-server-certificate`         | The Certificate used by webhooks server                                        |          `-`           |\n| `--webhook-server-private-key`         | The Private Key used by webhooks server                                        |          `-`           |\n\n\n## Examples\n\nAfter deploying this operator, you will have new resources available. Let's talk about them.\n\n### How to create kubernetes dynamic admission policies\n\nTo create a dynamic admission policy in your cluster, you will need to create a `ClusterAdmissionPolicy` resource.\nYou may prefer to learn directly from an example, so let's explain it creating a ClusterAdmissionPolicy:\n\n\u003e [!TIP]\n\u003e You can find the spec samples for all the versions of the resource in the [examples directory](./config/samples)\n\n\u003e [!IMPORTANT]\n\u003e When you have multiple ClusterAdmissionPolicy resources with the same watchedResources parameters,\n\u003e a resource can be rejected due to conditions specified in any of these policies.\n\u003e\n\u003e However, because conditions are evaluated one after the other, the rejection message displayed\n\u003e will be the one defined in the specific ClusterAdmissionPolicy where the rejecting condition is located.\n\n```yaml\napiVersion: admitik.freepik.com/v1alpha1\nkind: ClusterAdmissionPolicy\nmetadata:\n  labels:\n    app.kubernetes.io/name: admitik\n    app.kubernetes.io/managed-by: kustomize\n  name: avoid-colisioning-routes\nspec:\n\n  # (Optional) Action to perform with the conditions are not met\n  # Posible values: Enforce, Permissive\n  # Enforce: (default) Reject the object.\n  # Permissive: Accept the object\n  # Both results create an event in Kubernetes\n  failureAction: Enforce\n\n  # Resources to be validated against the webhooks server.\n  # Those matching any combination of following params will be sent.\n  # As a hint: don't set operations you don't need for a resource type\n  watchedResources:\n    group: gateway.networking.k8s.io\n    version: v1\n    resource: httproutes\n    operations:\n      - CREATE\n      - UPDATE\n\n  # Other resources to be retrieved for later templates.\n  # They will be included under .sources scope for conditions and message\n  sources:\n    - group: gateway.networking.k8s.io\n      version: v1\n      resource: httproutes\n\n      # (Optional) It's possible to retrieve specific resources\n      # name: secondary-route\n      # namespace: default\n\n\n  # ALL the conditions must be valid to allow the resource entrance.\n  conditions:\n    - name: confirm-non-existing-routes\n\n      # The 'key' field admits vitamin Golang templating (well known from Helm)\n      # The result of this field will be compared with 'value' for equality\n      key: |\n        {{- $operation := .operation -}}\n        {{- $object := .object -}}\n        {{- $oldObject := .oldObject -}}\n        {{- $sources := .sources -}}\n\n\n        {{- $routeFound := false -}}\n\n        {{- $routes := (index .sources 0) -}}\n        {{- range $routeObjIndex, $routeObj := $routes -}}\n\n          {{/* Here some logic to confirm you found the route already existing */}}\n          {{- $routeFound := true -}}\n\n        {{- end -}}\n\n        {{- if $routeFound -}}\n          {{- printf \"route-already-created\" -}}\n        {{- else -}}\n          {{- printf \"route-not-found\" -}}\n        {{- end -}}\n\n      value: \"route-not-found\"\n\n  message:\n    template: |\n      {{- $object := .object -}}\n      {{- printf \"Resource '%s' was rejected as some of declared routes already exists\" $object.metadata.name -}}\n\n```\n\nAs you probably noticed in the previous example, conditions are made using vitamin Golang template\n(better known as Helm template), so **all the functions available in Helm are available here too.**\nThis way you start creating wonderful policies from first minute.\n\n**Sometimes you need to store information** during conditions' evaluation that will be useful in later messages shown to the team.\nThis will help your mates having meaningful messages that save time during debug.\n\nBecause of that, there is a special function available in templates called `setVar`. It can be used as follows:\n\n```yaml\napiVersion: admitik.freepik.com/v1alpha1\nkind: ClusterAdmissionPolicy\nspec:\n\n  ...\n\n  conditions:\n    - name: store-vars-for-later-usage\n      key: |\n        {{- $someDataForLater := dict \"name\" \"example-name\" \"namespace\" \"example-namespace\" -}}\n\n\n        {{/* Store your data under your desired key. You can use as many keys as needed */}}\n        {{- setVar \"some_key\" $someDataForLater -}}\n\n\n        {{- printf \"force-condition-not-being-met\" -}}\n      value: \"condition-key-result\"\n\n  message:\n    template: |\n      {{- $myVars := .vars -}}\n\n      {{- $someKeyInside := $myVars.some_key-}}\n\n      {{- printf \"let's show some stored data: %s/%s\" $someKeyInside.name $someKeyInside.namespace -}}\n```\n\n\u003e [!TIP]\n\u003e Another useful function that can be used in templates is `logPrintf`. It accepts the same params as printf\n\u003e but throw the result in controller's logs instead of returning it\n\n\n## How to develop\n\n### Prerequisites\n- Kubebuilder v4.0.0+\n- go version v1.22.0+\n- docker version 17.03+.\n- kubectl version v1.11.3+.\n- Access to a Kubernetes v1.11.3+ cluster.\n\n### The process\n\n\u003e We recommend you to use a development tool like [Kind](https://kind.sigs.k8s.io/) or [Minikube](https://minikube.sigs.k8s.io/docs/start/)\n\u003e to launch a lightweight Kubernetes on your local machine for development purposes\n\nFor learning purposes, we will suppose you are going to use Kind. So the first step is to create a Kubernetes cluster\non your local machine executing the following command:\n\n```console\nkind create cluster\n```\n\nOnce you have launched a safe play place, execute the following command. It will install the custom resource definitions\n(CRDs) in the cluster configured in your ~/.kube/config file and run Kuberbac locally against the cluster:\n\n```console\nmake install run\n```\n\n\u003e [!IMPORTANT]\n\u003e When executing this, a temporary public reverse tunnel will be created.\n\u003e It goes from Kube Apiserver to your local webhooks server. It's done this way to be able to test the webhooks server\n\u003e using local development tools such as **Kind**\n\nIf you would like to test the operator against some resources, our examples can be applied to see the result in\nyour Kind cluster\n\n```sh\nkubectl apply -k config/samples/\n```\n\n\u003e Remember that your `kubectl` is pointing to your Kind cluster. However, you should always review the context your\n\u003e kubectl CLI is pointing to\n\n\n\n## How releases are created\n\nEach release of this operator is done following several steps carefully in order not to break the things for anyone.\nReliability is important to us, so we automated all the process of launching a release. For a better understanding of\nthe process, the steps are described in the following recipe:\n\n1. Test the changes on the code:\n\n    ```console\n    make test\n    ```\n\n   \u003e A release is not done if this stage fails\n\n\n2. Define the package information\n\n    ```console\n    export VERSION=\"0.0.1\"\n    export IMG=\"ghcr.io/freepik-company/admitik:v$VERSION\"\n    ```\n\n3. Generate and push the Docker image (published on Docker Hub).\n\n    ```console\n    make docker-build docker-push\n    ```\n\n4. Generate the manifests for deployments using Kustomize\n\n   ```console\n    make build-installer\n    ```\n\n\n\n## How to collaborate\n\nThis project is done on top of [Kubebuilder](https://github.com/kubernetes-sigs/kubebuilder), so read about that project\nbefore collaborating. Of course, we are open to external collaborations for this project. For doing it you must fork the\nrepository, make your changes to the code and open a PR. The code will be reviewed and tested (always)\n\n\u003e We are developers and hate bad code. For that reason we ask you the highest quality on each line of code to improve\n\u003e this project on each iteration.\n\n\n\n## License\n\nCopyright 2022.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreepik-company%2Fadmitik","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreepik-company%2Fadmitik","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreepik-company%2Fadmitik/lists"}