{"id":39664373,"url":"https://github.com/devantler-tech/pinniped-poc","last_synced_at":"2026-01-18T09:27:09.924Z","repository":{"id":289057920,"uuid":"969985239","full_name":"devantler-tech/pinniped-poc","owner":"devantler-tech","description":"A proof of concept for using Pinniped for authenticating to your cluster.","archived":false,"fork":false,"pushed_at":"2025-04-21T09:18:53.000Z","size":455,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-04-21T10:24:22.926Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"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/devantler-tech.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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-21T09:08:39.000Z","updated_at":"2025-04-21T09:18:56.000Z","dependencies_parsed_at":"2025-04-21T10:35:18.546Z","dependency_job_id":null,"html_url":"https://github.com/devantler-tech/pinniped-poc","commit_stats":null,"previous_names":["devantler-tech/pinniped-poc"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/devantler-tech/pinniped-poc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devantler-tech%2Fpinniped-poc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devantler-tech%2Fpinniped-poc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devantler-tech%2Fpinniped-poc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devantler-tech%2Fpinniped-poc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devantler-tech","download_url":"https://codeload.github.com/devantler-tech/pinniped-poc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devantler-tech%2Fpinniped-poc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28534159,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"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":[],"created_at":"2026-01-18T09:27:09.847Z","updated_at":"2026-01-18T09:27:09.916Z","avatar_url":"https://github.com/devantler-tech.png","language":null,"readme":"# Pinniped PoC\n\n\u003e [!NOTE]\n\u003e The PoC is built on [the tutorial from the Pinniped project](https://pinniped.dev/docs/tutorials/local-concierge-and-supervisor-demo/).\n\nThis is a PoC to test the Pinniped project, and how it fits in a multi-cluster setup.\n\n## Alternatives\n\n- [Kubelogin](https://github.com/int128/kubelogin)\n\n## Getting Started\n\n\u003e [!NOTE]\n\u003e For the PoC both the Supervisor (server) and the Concierge (agent) will be installed in the same cluster.\n\u003e\n\u003e Communication between the two will be done through ingress, to simulate a multi-cluster setup.\n\n![pinniped-architecture](pinniped-architecture.png)\n\n### Prerequisites\n\n- [Docker](https://www.docker.com/)\n- [KSail](https://github.com/devantler/ksail)\n- [Pinniped CLI](https://pinniped.dev/docs/howto/install-cli/)\n\nSet the following hostnames in your `/etc/hosts` file:\n\n```txt\n127.0.0.1 pinniped-supervisor.pinniped.svc.cluster.local\n```\n\n## Usage\n\nTo start the cluster with the Pinniped PoC, run the following command:\n\n```sh\nksail up\n```\n\nNow you should export the CA public key used by Pinniped and test that it works.\n\n```sh\n# To create the CA public key\nkubectl get secret pinniped-supervisor-tls \\\n  --namespace pinniped \\\n  -o jsonpath=\"{.data['ca\\.crt']}\" | base64 -d \u003e supervisor-ca.crt\n\n# To test that the supervisor is responding well to requests\ncurl --cacert supervisor-ca.crt \\\n  \"https://pinniped-supervisor.pinniped.svc.cluster.local/demo-issuer/.well-known/openid-configuration\"\n```\n\nAnd add a `JWTAuthenticator` to ensure authentication can happen between a Concierge Agent and the Central Supervisor:\n\n```sh\n# To configure Concierge to trust the Supervisor's FederationDomain.\ncat \u003c\u003cEOF | kubectl create -f -\napiVersion: authentication.concierge.pinniped.dev/v1alpha1\nkind: JWTAuthenticator\nmetadata:\n  name: supervisor-jwt-authenticator\nspec:\n  # This should be the issuer URL that was declared in the FederationDomain.\n  issuer: \"https://pinniped-supervisor.pinniped.svc.cluster.local/demo-issuer\"\n  # The audience value below is an arbitrary value which must uniquely\n  # identify this cluster. No other workload cluster should use the same value.\n  # It can have a human-readable component, but part of it should be random\n  # enough to ensure its uniqueness. Since this tutorial only uses a single\n  # cluster, you can copy/paste this example value.\n  audience: workload1-dd9de13c370982f61e9f\n  tls:\n    certificateAuthorityData: \"$(cat supervisor-ca.crt | base64)\"\nEOF\n```\n\nTo test the setup, the JWTAuthenticator should not fail. Check whether its phase is `Ready`:\n\n```sh\nkubectl get jwtauthenticator supervisor-jwt-authenticator -o yaml\n```\n\nAnd then we need to create a pinniped-compatible kubeconfig for the developers:\n\n```sh\n# This uses your current kubeconfig, which is the admin kubeconfig,\n# to generate a new kubeconfig for the cluster.\npinniped get kubeconfig \u003e kubeconfig.yaml\n```\n\nThis allows you to use the `kubeconfig.yaml` file to access the cluster as a developer, where you authenticate against the Concierge agent that does a roundtrip to the Supervisor service. Hence providing a federated authentication model for multi-cluster setups.\n\n```sh\n# Try to check who you are as a developer\npinniped whoami --kubeconfig kubeconfig.yaml\n\n# Try to list all namespaces as a developer\nkubectl get ns --kubeconfig kubeconfig.yaml\n\n# Try to list serviceaccounts in the dev namespace as a developer\nkubectl get sa --namespace dev --kubeconfig kubeconfig.yaml\n```\n\nYou will notice that you are correctly authenticated as a developer, and you can only access the `dev` namespace.\n\nWhen you are done run the following command to tear down the cluster:\n\n```sh\nksail down --registries\n```\n\n## Why Pinniped?\n\nPinniped is not only a project that provides federated authentication to a single cluster, but it also provides a way to authenticate users across multiple clusters. This is especially useful in multi-cluster setups where users need to access multiple clusters.\n\n- Federated authentication for multi-cluster setups (one authentication model for all clusters)\n  - A Supervisor service that provides authentication to any number of clusters. Installed on a central cluster, where app developers or devops users have no access to.\n  - A Concierge service that trusts the Supervisor, and acts as an in-cluster agent to provide unified authentication services to the cluster. Installed on every workload cluster.\n- Agnostic to the identity provider (it could be Dex as a middleman on the backend)\n- Provides non-sensitive Kubeconfig files to users (it is easy to share kubeconfig files with tenants)\n- Deep integration with `kubectl` (should make it easy to do Kubernetes API auth and RBAC)\n  - Long-lived logins (login once per day)\n  - Short-lived credentials (quick reaction to RBAC changes)\n- Credentials are scoped per cluster (it is not possible to use high privileged credentials to access other clusters)\n- Does not interfere with the original authentication system (The original admin-level kubeconfig from a cluster can be privately kept by the cluster’s creator)\n\n## What will be tested?\n\nThe PoC will try to setup Pinniped as the primary authentication system for a single cluster, while still using both the Supervisor and Concierge services.\n\n- The Supervisor will be installed in the `pinniped` namespace, where only the cluster admin has access to.\n- The Concierge will be installed in the `pinniped` namespace, where only the cluster admin has access to.\n- Kubernetes API auth will be configured to use the Concierge service, and one new user will be created.\n  - A `developer` user that has access to the `dev` namespace.\n- The Kubernetes API auth will be tested with various local tools (kubectl, k9s, etc.) against the `developer` user.\n- Traefik and cert-manager will be deployed in their own namespaces, and help with ingress and certificates.\n\n## What will not be tested?\n\n- Pinniped's OIDC Client support. (\u003chttps://pinniped.dev/docs/howto/configure-auth-for-webapps/\u003e)\n  - It was analyzed thoroughly, and I deemed that it was out of scope for this PoC.\n  - It does not work well with GitOps.\n  - It is API-based, requiring calling an API to get a client secret.\n- Pinniped and OIDC with Traefik ForwardAuth.\n  - It is related to the OIDC Client support, and thus it was deemed out of scope.\n  - It is possible.\n  - It requires an OIDC client for the backing service that Traefik is forwarding auth to.\n    - Maybe an OIDC client for Pinniped itself?\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevantler-tech%2Fpinniped-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevantler-tech%2Fpinniped-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevantler-tech%2Fpinniped-poc/lists"}