{"id":18834034,"url":"https://github.com/jetstack/jwt-registry-auth","last_synced_at":"2026-01-26T03:30:19.533Z","repository":{"id":231300110,"uuid":"721541185","full_name":"jetstack/jwt-registry-auth","owner":"jetstack","description":null,"archived":false,"fork":false,"pushed_at":"2023-11-21T15:52:40.000Z","size":44,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-02-15T07:57:06.473Z","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/jetstack.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}},"created_at":"2023-11-21T09:23:13.000Z","updated_at":"2024-10-24T22:01:13.000Z","dependencies_parsed_at":"2024-04-03T11:48:39.340Z","dependency_job_id":null,"html_url":"https://github.com/jetstack/jwt-registry-auth","commit_stats":null,"previous_names":["jetstack/jwt-registry-auth"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jetstack%2Fjwt-registry-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jetstack%2Fjwt-registry-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jetstack%2Fjwt-registry-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jetstack%2Fjwt-registry-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jetstack","download_url":"https://codeload.github.com/jetstack/jwt-registry-auth/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239768930,"owners_count":19693764,"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":[],"created_at":"2024-11-08T02:06:40.793Z","updated_at":"2026-01-26T03:30:19.468Z","avatar_url":"https://github.com/jetstack.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jwt-registry-auth\n\nA solution that leverages JWT tokens to enable transparent and passwordless\ncontainer registry authentication and authorization for machine workloads like\nKubernetes pods and Github Actions.\n\nThis is a proof of concept and is not suitable for production use cases.\n\n## Goals\n\nThere are two main aims here.\n\n1. Allow Kubernetes pods and other types of 'machine' workload to pull/push\n   images from a registry without having to define static secrets.\n2. Enable authorization based on the properties of the workload's identity. For\n   example, allow Kubernetes service accounts within a given namespace to pull\n   from a particular set of repositories.\n\n## Solution\n\nThe goals are accomplished by enabling clients to authenticate to container\nregistries with a JWT token issued by a trusted identity provider.\n\nThis PoC provides implementations that enable the solution. These\nimplementations can be split into two categories (server and client) which are\nexpanded on in the following sections.\n\n## Server\n\nThe container registry server must be capable of accepting a JWT token as a\nclient's credentials, validating the token with a trusted identity provider and\nperforming authorization based on the claims in the token.\n\nAs far as I know, the only container registry that currently supports anything\nlike this is \n[Chainguard's registry](https://edu.chainguard.dev/chainguard/chainguard-registry/authenticating/#authenticating-with-github-actions).\n\nIn lieu of native registry support, this PoC implements two methods of strapping\nJWT authentication and authorization onto an existing registry.\n\n### Token Server\n\nThe [Distribution registry](https://github.com/distribution/distribution)\nsupports configurable authentication and authorization via a pluggable 'token'\nserver.\n\nThe [`cmd/token-server`](cmd/token-server) application implements a token server\nwhich:\n\n1. Accepts a JWT token as a user's password\n2. Validates and authenticates the token with a trusted identity provider\n3. Applies authorization based on the token's claims via CEL policies\n\n```mermaid\nsequenceDiagram\n    Client-\u003e\u003eRegistry: Push/Pull\n    Registry--\u003e\u003eClient: 401 'WWW-Authenticate: \u003ctoken-server\u003e'\n    Client-\u003e\u003eToken Server: 'Authorization: Basic \u003cprovider\u003e:\u003cjwt\u003e'\n    Token Server-\u003e\u003eIdentity Provider: /.well-known/openid-configuration\n    Identity Provider--\u003e\u003eToken Server: Public Key\n    Token Server--\u003e\u003eClient: {auth_token: \"\u003ctoken\u003e\"}\n    Client-\u003e\u003eRegistry: 'Authorization: Bearer \u003ctoken\u003e'\n    Registry--\u003e\u003eClient: Response\n```\n\n### Registry Auth Proxy\n\nMost registries don't support pluggable authentication and authorization in the\nsame way that the Distribution registry does.\n\nFor these registries, the PoC provides a reverse proxy,\n[`cmd/registry-auth-proxy`](cmd/registry-auth-proxy) that sits in front of a\nregistry and performs token-based authentication before proxying requests to\nthe upstream registry.\n\n```mermaid\nsequenceDiagram\n    Client-\u003e\u003eRegistry Auth Proxy: Push/Pull\n    Registry Auth Proxy--\u003e\u003eClient: 401 'WWW-Authenticate: \u003ctoken-server\u003e'\n    Client-\u003e\u003eToken Server: 'Authorization: Basic \u003cprovider\u003e:\u003cjwt\u003e'\n    Token Server-\u003e\u003eIdentity Provider: /.well-known/openid-configuration\n    Identity Provider--\u003e\u003eToken Server: Public Key\n    Token Server--\u003e\u003eClient: {auth_token: \"\u003ctoken\u003e\"}\n    Client-\u003e\u003eRegistry Auth Proxy: 'Authorization: Bearer \u003ctoken\u003e'\n    Registry Auth Proxy-\u003e\u003eUpstream Registry: Proxy Request\n    Upstream Registry--\u003e\u003eRegistry Auth Proxy: Response\n    Registry Auth Proxy--\u003e\u003eClient: Response\n```\n\n## Client\n\nClients that push or pull images from the registry must be configured so that\nthey can fetch a token from their identity provider and then provide that as\ntheir password when authenticating with the registry.\n\nThere are numerous ways to do this depending on the type of client and where it\nis running.\n\nThis PoC provides two methods, which are outlined below.\n\n### Kubernetes Controller\n\nThe [`cmd/kube-controller`](cmd/kube-controller) application runs in the cluster\nand enables Kubernetes pods to push and pull images based on their service \naccount identity.\n\nRefer to the [README.md](cmd/kube-controller/README.md) for more information.\n\n### Github Actions\n\nThe [`actions/docker-login`](actions/docker-login) GitHub Action logs into a\ncontainer registry with a GitHub Actions issued JWT token as the password.\n\nRefer to the [README.md](actions/docker-login/README.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjetstack%2Fjwt-registry-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjetstack%2Fjwt-registry-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjetstack%2Fjwt-registry-auth/lists"}