Merge branch 'main' into impersonation-proxy
This commit is contained in:
commit
f8111db5ff
@ -8,7 +8,7 @@ Please see the [Code of Conduct](./CODE_OF_CONDUCT.md).
|
|||||||
|
|
||||||
## Project Scope
|
## Project Scope
|
||||||
|
|
||||||
Learn about the [scope](https://pinniped.dev/docs/scope/) of the project.
|
See [SCOPE.md](./SCOPE.md) for some guidelines about what we consider in and out of scope for Pinniped.
|
||||||
|
|
||||||
## Community Meetings
|
## Community Meetings
|
||||||
|
|
||||||
|
14
README.md
14
README.md
@ -10,7 +10,7 @@ install procedure across all types and origins of Kubernetes clusters,
|
|||||||
declarative configuration via Kubernetes APIs, enterprise-grade integrations
|
declarative configuration via Kubernetes APIs, enterprise-grade integrations
|
||||||
with IDPs, and distribution-specific integration strategies.
|
with IDPs, and distribution-specific integration strategies.
|
||||||
|
|
||||||
### Example Use Cases
|
### Example use cases
|
||||||
|
|
||||||
* Your team uses a large enterprise IDP, and has many clusters that they
|
* Your team uses a large enterprise IDP, and has many clusters that they
|
||||||
manage. Pinniped provides:
|
manage. Pinniped provides:
|
||||||
@ -39,17 +39,15 @@ The Pinniped Concierge can be configured to hook into the Pinniped Supervisor's
|
|||||||
federated credentials, or it can authenticate users directly via external IDP
|
federated credentials, or it can authenticate users directly via external IDP
|
||||||
credentials.
|
credentials.
|
||||||
|
|
||||||
To learn more, see [architecture](https://pinniped.dev/docs/architecture/).
|
To learn more, see [architecture](https://pinniped.dev/docs/background/architecture/).
|
||||||
|
|
||||||
<img src="site/content/docs/img/pinniped_architecture_concierge_supervisor.svg" alt="Pinniped Architecture Sketch"/>
|
## Getting started with Pinniped
|
||||||
|
|
||||||
## Trying Pinniped
|
|
||||||
|
|
||||||
Care to kick the tires? It's easy to [install and try Pinniped](https://pinniped.dev/docs/demo/).
|
Care to kick the tires? It's easy to [install and try Pinniped](https://pinniped.dev/docs/demo/).
|
||||||
|
|
||||||
## Community Meetings
|
## Community meetings
|
||||||
|
|
||||||
Pinniped is better because of our contributors and maintainers. It is because of you that we can bring great software to the community. Please join us during our online community meetings, occuring every first and third Thursday of the month at 9AM PT / 12PM PT. Use [this Zoom Link](https://vmware.zoom.us/j/93798188973?pwd=T3pIMWxReEQvcWljNm1admRoZTFSZz09) to attend and add any agenda items you wish to discuss to [the notes document](https://hackmd.io/rd_kVJhjQfOvfAWzK8A3tQ?view). Join our [Google Group](https://groups.google.com/u/1/g/project-pinniped) to receive invites to this meeting.
|
Pinniped is better because of our contributors and maintainers. It is because of you that we can bring great software to the community. Please join us during our online community meetings, occurring every first and third Thursday of the month at 9 AM PT / 12 PM PT. Use [this Zoom Link](https://vmware.zoom.us/j/93798188973?pwd=T3pIMWxReEQvcWljNm1admRoZTFSZz09) to attend and add any agenda items you wish to discuss to [the notes document](https://hackmd.io/rd_kVJhjQfOvfAWzK8A3tQ?view). Join our [Google Group](https://groups.google.com/u/1/g/project-pinniped) to receive invites to this meeting.
|
||||||
|
|
||||||
If the meeting day falls on a US holiday, please consider that occurrence of the meeting to be canceled.
|
If the meeting day falls on a US holiday, please consider that occurrence of the meeting to be canceled.
|
||||||
|
|
||||||
@ -61,7 +59,7 @@ Got a question, comment, or idea? Please don't hesitate to reach out via the Git
|
|||||||
|
|
||||||
Contributions are welcome. Before contributing, please see the [contributing guide](CONTRIBUTING.md).
|
Contributions are welcome. Before contributing, please see the [contributing guide](CONTRIBUTING.md).
|
||||||
|
|
||||||
## Reporting Security Vulnerabilities
|
## Reporting security vulnerabilities
|
||||||
|
|
||||||
Please follow the procedure described in [SECURITY.md](SECURITY.md).
|
Please follow the procedure described in [SECURITY.md](SECURITY.md).
|
||||||
|
|
||||||
|
32
SCOPE.md
Normal file
32
SCOPE.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Project Scope
|
||||||
|
|
||||||
|
The Pinniped project is guided by the following principles.
|
||||||
|
|
||||||
|
- Pinniped lets you plug any external identity providers into Kubernetes.
|
||||||
|
These integrations follow enterprise-grade security principles.
|
||||||
|
- Pinniped is easy to install and use on any Kubernetes cluster via distribution-specific integration mechanisms.
|
||||||
|
- Pinniped uses a declarative configuration via Kubernetes APIs.
|
||||||
|
- Pinniped provides optimal user experience when authenticating to many clusters at one time.
|
||||||
|
- Pinniped provides enterprise-grade security posture via secure defaults and revocable or very short-lived credentials.
|
||||||
|
- Where possible, Pinniped will contribute ideas and code to upstream Kubernetes.
|
||||||
|
|
||||||
|
When contributing to Pinniped, please consider whether your contribution follows
|
||||||
|
these guiding principles.
|
||||||
|
|
||||||
|
## Out Of Scope
|
||||||
|
|
||||||
|
The following items are out of scope for the Pinniped project.
|
||||||
|
|
||||||
|
- Authorization.
|
||||||
|
- Standalone identity provider for general use.
|
||||||
|
- Machine-to-machine (service) identity.
|
||||||
|
- Running outside of Kubernetes.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
See our [open milestones][milestones] and the [`priority/backlog` label][backlog] for an idea about what's next on our roadmap.
|
||||||
|
|
||||||
|
For more details on proposing features and bugs, check out our [contributing](./CONTRIBUTING.md) doc.
|
||||||
|
|
||||||
|
[milestones]: https://github.com/vmware-tanzu/pinniped/milestones
|
||||||
|
[backlog]: https://github.com/vmware-tanzu/pinniped/labels/priority%2Fbacklog
|
@ -1,39 +1,3 @@
|
|||||||
# Deploying
|
# Pinniped Concierge Deployment
|
||||||
|
|
||||||
## Connecting Pinniped to an Identity Provider
|
See [the how-to guide for details](https://pinniped.dev/docs/howto/install-concierge/).
|
||||||
|
|
||||||
If you would like to try Pinniped, but you don't have a compatible identity provider,
|
|
||||||
you can use Pinniped's test identity provider.
|
|
||||||
See [deploy/local-user-authenticator/README.md](../../deploy/local-user-authenticator/README.md)
|
|
||||||
for details.
|
|
||||||
|
|
||||||
## Installing the Latest Version with Default Options
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f https://get.pinniped.dev/latest/install-pinniped-concierge.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing a Specific Version with Default Options
|
|
||||||
|
|
||||||
Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number
|
|
||||||
and use it to replace the version number in the URL below.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Replace v0.4.1 with your preferred version in the URL below
|
|
||||||
kubectl apply -f https://get.pinniped.dev/v0.4.1/install-pinniped-concierge.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing with Custom Options
|
|
||||||
|
|
||||||
Creating your own deployment YAML file requires `ytt` from [Carvel](https://carvel.dev/) to template the YAML files
|
|
||||||
in the `deploy/concierge` directory.
|
|
||||||
Either [install `ytt`](https://get-ytt.io/) or use the [container image from Dockerhub](https://hub.docker.com/r/k14s/image/tags).
|
|
||||||
|
|
||||||
1. `git clone` this repo and `git checkout` the release version tag of the release that you would like to deploy.
|
|
||||||
1. The configuration options are in [deploy/concierge/values.yml](values.yaml).
|
|
||||||
Fill in the values in that file, or override those values using additional `ytt` command-line options in
|
|
||||||
the command below. Use the release version tag as the `image_tag` value.
|
|
||||||
2. In a terminal, cd to this `deploy/concierge` directory
|
|
||||||
3. To generate the final YAML files, run `ytt --file .`
|
|
||||||
4. Deploy the generated YAML using your preferred deployment tool, such as `kubectl` or [`kapp`](https://get-kapp.io/).
|
|
||||||
For example: `ytt --file . | kapp deploy --yes --app pinniped --diff-changes --file -`
|
|
||||||
|
@ -1,184 +1,3 @@
|
|||||||
# Deploying the Pinniped Supervisor
|
# Pinniped Supervisor Deployment
|
||||||
|
|
||||||
## What is the Pinniped Supervisor?
|
See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/).
|
||||||
|
|
||||||
The Pinniped Supervisor app is a component of the Pinniped OIDC and Cluster Federation solutions.
|
|
||||||
It can be deployed when those features are needed.
|
|
||||||
|
|
||||||
## Installing the Latest Version with Default Options
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl apply -f https://get.pinniped.dev/latest/install-pinniped-supervisor.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing a Specific Version with Default Options
|
|
||||||
|
|
||||||
Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number
|
|
||||||
and use it to replace the version number in the URL below.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Replace v0.4.1 with your preferred version in the URL below
|
|
||||||
kubectl apply -f https://get.pinniped.dev/v0.4.1/install-pinniped-supervisor.yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing with Custom Options
|
|
||||||
|
|
||||||
Creating your own deployment YAML file requires `ytt` from [Carvel](https://carvel.dev/) to template the YAML files
|
|
||||||
in the `deploy/supervisor` directory.
|
|
||||||
Either [install `ytt`](https://get-ytt.io/) or use the [container image from Dockerhub](https://hub.docker.com/r/k14s/image/tags).
|
|
||||||
|
|
||||||
1. `git clone` this repo and `git checkout` the release version tag of the release that you would like to deploy.
|
|
||||||
1. The configuration options are in [deploy/supervisor/values.yml](values.yaml).
|
|
||||||
Fill in the values in that file, or override those values using additional `ytt` command-line options in
|
|
||||||
the command below. Use the release version tag as the `image_tag` value.
|
|
||||||
2. In a terminal, cd to this `deploy/supervisor` directory
|
|
||||||
3. To generate the final YAML files, run `ytt --file .`
|
|
||||||
4. Deploy the generated YAML using your preferred deployment tool, such as `kubectl` or [`kapp`](https://get-kapp.io/).
|
|
||||||
For example: `ytt --file . | kapp deploy --yes --app pinniped-supervisor --diff-changes --file -`
|
|
||||||
|
|
||||||
## Configuring After Installing
|
|
||||||
|
|
||||||
### Exposing the Supervisor App as a Service
|
|
||||||
|
|
||||||
The Supervisor app's endpoints should be exposed as HTTPS endpoints with proper TLS certificates signed by a
|
|
||||||
Certificate Authority which will be trusted by your user's web browsers. Because there are
|
|
||||||
many ways to expose TLS services from a Kubernetes cluster, the Supervisor app leaves this up to the user.
|
|
||||||
The most common ways are:
|
|
||||||
|
|
||||||
1. Define an [`Ingress` resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) with TLS certificates.
|
|
||||||
In this case, the ingress will terminate TLS. Typically, the ingress will then talk plain HTTP to its backend,
|
|
||||||
which would be a NodePort or LoadBalancer Service in front of the HTTP port 8080 of the Supervisor pods.
|
|
||||||
|
|
||||||
The required configuration of the Ingress is specific to your cluster's Ingress Controller, so please refer to the
|
|
||||||
documentation from your Kubernetes provider. If you are using a cluster from a cloud provider, then you'll probably
|
|
||||||
want to start with that provider's documentation. For example, if your cluster is a Google GKE cluster, refer to
|
|
||||||
the [GKE documentation for Ingress](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress).
|
|
||||||
Otherwise, the Kubernetes documentation provides a list of popular
|
|
||||||
[Ingress Controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/), including
|
|
||||||
[Contour](https://projectcontour.io/) and many others.
|
|
||||||
|
|
||||||
1. Or, define a [TCP LoadBalancer Service](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer)
|
|
||||||
which is a layer 4 load balancer and does not terminate TLS. In this case, the Supervisor app will need to be
|
|
||||||
configured with TLS certificates and will terminate the TLS connection itself (see the section about FederationDomain
|
|
||||||
below). The LoadBalancer Service should be configured to use the HTTPS port 443 of the Supervisor pods as its `targetPort`.
|
|
||||||
|
|
||||||
*Warning:* Do not expose the Supervisor's port 8080 to the public. It would not be secure for the OIDC protocol
|
|
||||||
to use HTTP, because the user's secret OIDC tokens would be transmitted across the network without encryption.
|
|
||||||
|
|
||||||
1. Or, expose the Supervisor app using a Kubernetes service mesh technology, e.g. [Istio](https://istio.io/).
|
|
||||||
Please see the documentation for your service mesh. Generally, the setup would be similar to the description
|
|
||||||
above for defining an ingress, expect the service mesh would probably provide both the ingress with TLS termination
|
|
||||||
and the service.
|
|
||||||
|
|
||||||
For either of the first two options mentioned above, if you installed using `ytt` then you can use
|
|
||||||
the related `service_*` options from [deploy/supervisor/values.yml](values.yaml) to create a Service.
|
|
||||||
If you installed using `install-supervisor.yaml` then you can create
|
|
||||||
the Service separately after installing the Supervisor app. There is no `Ingress` included in the `ytt` templates,
|
|
||||||
so if you choose to use an Ingress then you'll need to create that separately after installing the Supervisor app.
|
|
||||||
|
|
||||||
#### Example: Using a LoadBalancer Service
|
|
||||||
|
|
||||||
This is an example of creating a LoadBalancer Service to expose port 8443 of the Supervisor app outside the cluster.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: pinniped-supervisor-loadbalancer
|
|
||||||
# Assuming that this is the namespace where the supervisor was installed. This is the default in install-supervisor.yaml.
|
|
||||||
namespace: pinniped-supervisor
|
|
||||||
spec:
|
|
||||||
type: LoadBalancer
|
|
||||||
selector:
|
|
||||||
# Assuming that this is how the supervisor pods are labeled. This is the default in install-supervisor.yaml.
|
|
||||||
app: pinniped-supervisor
|
|
||||||
ports:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 443
|
|
||||||
targetPort: 8443
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example: Using a NodePort Service
|
|
||||||
|
|
||||||
A NodePort Service exposes the app as a port on the nodes of the cluster.
|
|
||||||
|
|
||||||
This is convenient for use with kind clusters, because kind can
|
|
||||||
[expose node ports as localhost ports on the host machine](https://kind.sigs.k8s.io/docs/user/configuration/#extra-port-mappings)
|
|
||||||
without requiring an Ingress, although
|
|
||||||
[kind also supports several Ingress Controllers](https://kind.sigs.k8s.io/docs/user/ingress).
|
|
||||||
|
|
||||||
A NodePort Service could also be used behind an Ingress which is terminating TLS.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: pinniped-supervisor-nodeport
|
|
||||||
# Assuming that this is the namespace where the supervisor was installed. This is the default in install-supervisor.yaml.
|
|
||||||
namespace: pinniped-supervisor
|
|
||||||
spec:
|
|
||||||
type: NodePort
|
|
||||||
selector:
|
|
||||||
# Assuming that this is how the supervisor pods are labeled. This is the default in install-supervisor.yaml.
|
|
||||||
app: pinniped-supervisor
|
|
||||||
ports:
|
|
||||||
- protocol: TCP
|
|
||||||
port: 80
|
|
||||||
targetPort: 8080
|
|
||||||
nodePort: 31234 # This is the port that you would forward to the kind host. Or omit this key for a random port.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuring the Supervisor to Act as an OIDC Provider
|
|
||||||
|
|
||||||
The Supervisor can be configured as an OIDC provider by creating `FederationDomain` resources
|
|
||||||
in the same namespace where the Supervisor app was installed. For example:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: config.supervisor.pinniped.dev/v1alpha1
|
|
||||||
kind: FederationDomain
|
|
||||||
metadata:
|
|
||||||
name: my-provider
|
|
||||||
# Assuming that this is the namespace where the supervisor was installed. This is the default in install-supervisor.yaml.
|
|
||||||
namespace: pinniped-supervisor
|
|
||||||
spec:
|
|
||||||
# The hostname would typically match the DNS name of the public ingress or load balancer for the cluster.
|
|
||||||
# Any path can be specified, which allows a single hostname to have multiple different issuers. The path is optional.
|
|
||||||
issuer: https://my-issuer.example.com/any/path
|
|
||||||
|
|
||||||
# Optionally configure the name of a Secret in the same namespace, of type `kubernetes.io/tls`,
|
|
||||||
# which contains the TLS serving certificate for the HTTPS endpoints served by this OIDC Provider.
|
|
||||||
tls:
|
|
||||||
secretName: my-tls-cert-secret
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Configuring TLS for the Supervisor OIDC Endpoints
|
|
||||||
|
|
||||||
If you have terminated TLS outside the app, for example using an Ingress with TLS certificates, then you do not need to
|
|
||||||
configure TLS certificates on the FederationDomain.
|
|
||||||
|
|
||||||
If you are using a LoadBalancer Service to expose the Supervisor app outside your cluster, then you will
|
|
||||||
also need to configure the Supervisor app to terminate TLS. There are two places to configure TLS certificates:
|
|
||||||
|
|
||||||
1. Each `FederationDomain` can be configured with TLS certificates, using the `spec.tls.secretName` field.
|
|
||||||
|
|
||||||
1. The default TLS certificate for all OIDC providers can be configured by creating a Secret called
|
|
||||||
`pinniped-supervisor-default-tls-certificate` in the same namespace in which the Supervisor was installed.
|
|
||||||
|
|
||||||
The default TLS certificate will be used for all OIDC providers which did not declare a `spec.tls.secretName`.
|
|
||||||
Also, the `spec.tls.secretName` will be ignored for incoming requests to the OIDC endpoints
|
|
||||||
that use an IP address as the host, so those requests will always present the default TLS certificates
|
|
||||||
to the client. When the request includes the hostname, and that hostname matches the hostname of an `Issuer`,
|
|
||||||
then the TLS certificate defined by the `spec.tls.secretName` will be used. If that issuer did not
|
|
||||||
define `spec.tls.secretName` then the default TLS certificate will be used. If neither exists,
|
|
||||||
then the client will get a TLS error because the server will not present any TLS certificate.
|
|
||||||
|
|
||||||
It is recommended that you have a DNS entry for your load balancer or Ingress, and that you configure the
|
|
||||||
OIDC provider's `Issuer` using that DNS hostname, and that the TLS certificate for that provider also
|
|
||||||
covers that same hostname.
|
|
||||||
|
|
||||||
You can create the certificate Secrets however you like, for example you could use [cert-manager](https://cert-manager.io/)
|
|
||||||
or `kubectl create secret tls`.
|
|
||||||
Keep in mind that your users will load some of these endpoints in their web browsers, so the TLS certificates
|
|
||||||
should be signed by a Certificate Authority that will be trusted by their browsers.
|
|
||||||
|
11
go.mod
11
go.mod
@ -7,8 +7,8 @@ require (
|
|||||||
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||||
github.com/coreos/go-oidc/v3 v3.0.0
|
github.com/coreos/go-oidc/v3 v3.0.0
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/go-logr/logr v0.3.0
|
github.com/go-logr/logr v0.4.0
|
||||||
github.com/go-logr/stdr v0.2.0
|
github.com/go-logr/stdr v0.4.0
|
||||||
github.com/go-openapi/spec v0.19.9
|
github.com/go-openapi/spec v0.19.9
|
||||||
github.com/gofrs/flock v0.8.0
|
github.com/gofrs/flock v0.8.0
|
||||||
github.com/golang/mock v1.4.4
|
github.com/golang/mock v1.4.4
|
||||||
@ -24,16 +24,15 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/sclevine/agouti v3.0.0+incompatible
|
github.com/sclevine/agouti v3.0.0+incompatible
|
||||||
github.com/sclevine/spec v1.4.0
|
github.com/sclevine/spec v1.4.0
|
||||||
github.com/spf13/cobra v1.1.1
|
github.com/spf13/cobra v1.1.3
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620
|
golang.org/x/crypto v0.0.0-20201217014255-9d1352758620
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d // indirect
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||||
gopkg.in/square/go-jose.v2 v2.5.1
|
gopkg.in/square/go-jose.v2 v2.5.1
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
||||||
k8s.io/api v0.20.4
|
k8s.io/api v0.20.4
|
||||||
k8s.io/apimachinery v0.20.4
|
k8s.io/apimachinery v0.20.4
|
||||||
@ -41,7 +40,7 @@ require (
|
|||||||
k8s.io/client-go v0.20.4
|
k8s.io/client-go v0.20.4
|
||||||
k8s.io/component-base v0.20.4
|
k8s.io/component-base v0.20.4
|
||||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded
|
k8s.io/gengo v0.0.0-20201113003025-83324d819ded
|
||||||
k8s.io/klog/v2 v2.4.0
|
k8s.io/klog/v2 v2.5.0
|
||||||
k8s.io/kube-aggregator v0.20.4
|
k8s.io/kube-aggregator v0.20.4
|
||||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd
|
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920
|
||||||
|
17
go.sum
17
go.sum
@ -209,10 +209,10 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v0.3.0 h1:q4c+kbcR0d5rSurhBR8dIgieOaYpXtsdTYfx22Cu6rs=
|
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||||
github.com/go-logr/logr v0.3.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/stdr v0.2.0 h1:EuTFw3BCZ6H/+1VNFlOLVK/sPKwmGMLx8/FTOFWuXpU=
|
github.com/go-logr/stdr v0.4.0 h1:ijk9G/xzDRZdMU1QRhLYdHuWvNZWqte+NZMOGsiKWbc=
|
||||||
github.com/go-logr/stdr v0.2.0/go.mod h1:NO1vneyJDqKVgJYnxhwXWWmQPOvNM391IG3H8ql3jiA=
|
github.com/go-logr/stdr v0.4.0/go.mod h1:NO1vneyJDqKVgJYnxhwXWWmQPOvNM391IG3H8ql3jiA=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
@ -961,8 +961,9 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
|
|||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
|
|
||||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||||
|
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
|
||||||
|
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
@ -987,8 +988,9 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/subosito/gotenv v1.1.1/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.1.1/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
@ -1515,8 +1517,9 @@ k8s.io/gengo v0.0.0-20201113003025-83324d819ded h1:JApXBKYyB7l9xx+DK7/+mFjC7A9Bt
|
|||||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
|
|
||||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
|
k8s.io/klog/v2 v2.5.0 h1:8mOnjf1RmUPW6KRqQCfYSZq/K20Unmp3IhuZUhxl8KI=
|
||||||
|
k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||||
k8s.io/kube-aggregator v0.20.4 h1:j/SUwPy1eO+ud3XOUGmH18gISPyerqhXOoNRZDbv3fs=
|
k8s.io/kube-aggregator v0.20.4 h1:j/SUwPy1eO+ud3XOUGmH18gISPyerqhXOoNRZDbv3fs=
|
||||||
k8s.io/kube-aggregator v0.20.4/go.mod h1:0ixQ9De7KXyHteXizS6nVtrnKqGa4kiuxl9rEBsNccw=
|
k8s.io/kube-aggregator v0.20.4/go.mod h1:0ixQ9De7KXyHteXizS6nVtrnKqGa4kiuxl9rEBsNccw=
|
||||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c=
|
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c=
|
||||||
|
@ -152,7 +152,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="secret \"test-client-secret\" not found" "reason"="SecretNotFound" "status"="False" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="secret \"test-client-secret\" not found" "reason"="SecretNotFound" "status"="False" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="secret \"test-client-secret\" not found" "name"="test-name" "namespace"="test-namespace" "reason"="SecretNotFound" "type"="ClientCredentialsValid"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="secret \"test-client-secret\" not found" "name"="test-name" "namespace"="test-namespace" "reason"="SecretNotFound" "type"="ClientCredentialsValid"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -198,7 +198,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "reason"="SecretWrongType" "status"="False" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "reason"="SecretWrongType" "status"="False" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "name"="test-name" "namespace"="test-namespace" "reason"="SecretWrongType" "type"="ClientCredentialsValid"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" has wrong type \"some-other-type\" (should be \"secrets.pinniped.dev/oidc-client\")" "name"="test-name" "namespace"="test-namespace" "reason"="SecretWrongType" "type"="ClientCredentialsValid"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -243,7 +243,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "reason"="SecretMissingKeys" "status"="False" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "reason"="SecretMissingKeys" "status"="False" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="discovered issuer configuration" "reason"="Success" "status"="True" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "name"="test-name" "namespace"="test-namespace" "reason"="SecretMissingKeys" "type"="ClientCredentialsValid"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="referenced Secret \"test-client-secret\" is missing required keys [\"clientID\" \"clientSecret\"]" "name"="test-name" "namespace"="test-namespace" "reason"="SecretMissingKeys" "type"="ClientCredentialsValid"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -291,7 +291,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: illegal base64 data at input byte 7" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -339,7 +339,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: no certificates found" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="spec.certificateAuthorityData is invalid: no certificates found" "reason"="InvalidTLSConfig" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="spec.certificateAuthorityData is invalid: no certificates found" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="spec.certificateAuthorityData is invalid: no certificates found" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidTLSConfig" "type"="OIDCDiscoverySucceeded"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -384,7 +384,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"invalid-url\"" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to perform OIDC discovery against \"invalid-url\"" "reason"="Unreachable" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="failed to perform OIDC discovery against \"invalid-url\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to perform OIDC discovery against \"invalid-url\"" "name"="test-name" "namespace"="test-namespace" "reason"="Unreachable" "type"="OIDCDiscoverySucceeded"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -430,7 +430,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="failed to parse authorization endpoint URL: parse \"%\": invalid URL escape \"%\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
@ -476,7 +476,7 @@ func TestController(t *testing.T) {
|
|||||||
wantLogs: []string{
|
wantLogs: []string{
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="loaded client credentials" "reason"="Success" "status"="True" "type"="ClientCredentialsValid"`,
|
||||||
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "level"=0 "msg"="updated condition" "name"="test-name" "namespace"="test-namespace" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "reason"="InvalidResponse" "status"="False" "type"="OIDCDiscoverySucceeded"`,
|
||||||
`upstream-observer "error"="OIDCIdentityProvider has a failing condition" "msg"="found failing condition" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
`upstream-observer "msg"="found failing condition" "error"="OIDCIdentityProvider has a failing condition" "message"="authorization endpoint URL scheme must be \"https\", not \"http\"" "name"="test-name" "namespace"="test-namespace" "reason"="InvalidResponse" "type"="OIDCDiscoverySucceeded"`,
|
||||||
},
|
},
|
||||||
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
wantResultingCache: []provider.UpstreamOIDCIdentityProviderI{},
|
||||||
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
wantResultingUpstreams: []v1alpha1.OIDCIdentityProvider{{
|
||||||
|
@ -22,17 +22,13 @@ markup:
|
|||||||
noClasses: false
|
noClasses: false
|
||||||
style: monokailight
|
style: monokailight
|
||||||
tabWidth: 4
|
tabWidth: 4
|
||||||
menu:
|
|
||||||
docs:
|
related:
|
||||||
- name: Overview
|
includeNewer: true
|
||||||
url: /docs/
|
indices:
|
||||||
weight: 100
|
- name: tags
|
||||||
- name: Install
|
weight: 50
|
||||||
url: /docs/install/
|
- name: date
|
||||||
weight: 110
|
weight: 50
|
||||||
- name: Architecture
|
threshold: 0
|
||||||
url: /docs/architecture/
|
toLower: true
|
||||||
- name: Demo
|
|
||||||
url: /docs/demo/
|
|
||||||
- name: Scope
|
|
||||||
url: /docs/scope/
|
|
@ -16,8 +16,8 @@ layout: section
|
|||||||
<a href="{{< param "github_url" >}}"><img src="/img/github-image.svg" /></a>
|
<a href="{{< param "github_url" >}}"><img src="/img/github-image.svg" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3><a href="{{< param "github_url" >}}">Check out Github</a></h3>
|
<h3><a href="{{< param "github_url" >}}">Check out GitHub</a></h3>
|
||||||
<p>Head over to our git repo and check out the discussions and issues sections.</p>
|
<p>Head over to our GitHub repo and check out the <a href="https://github.com/vmware-tanzu/pinniped/discussions">discussions</a> and <a href="https://github.com/vmware-tanzu/pinniped/issues">issues</a>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@ -35,7 +35,7 @@ layout: section
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3><a href="{{< param "community_url" >}}">Community Meetings</a></h3>
|
<h3><a href="{{< param "community_url" >}}">Community Meetings</a></h3>
|
||||||
<p>Pinniped Community Meetings are held every 1st and 3rd Thursday of the month at 9AM PT / 12PM ET</p>
|
<p>Pinniped Community Meetings are held every first and third Thursday of the month at 9 AM PT / 12 PM ET</p>
|
||||||
<p>Join our <a href="https://groups.google.com/u/1/g/project-pinniped">Google Group</a> to receive invites to the meeting</p>
|
<p>Join our <a href="https://groups.google.com/u/1/g/project-pinniped">Google Group</a> to receive invites to the meeting</p>
|
||||||
<p>Watch previous community meetings on our <a href="https://www.youtube.com/playlist?list=PL7bmigfV0EqQ8qYn8ornuJnuGvCt0belt">YouTube playlist</a></p>
|
<p>Watch previous community meetings on our <a href="https://www.youtube.com/playlist?list=PL7bmigfV0EqQ8qYn8ornuJnuGvCt0belt">YouTube playlist</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,61 +1,31 @@
|
|||||||
---
|
---
|
||||||
title: "Pinniped Documentation"
|
|
||||||
cascade:
|
cascade:
|
||||||
layout: docs
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Overview
|
||||||
|
weight: 1
|
||||||
---
|
---
|
||||||
|
|
||||||
![Pinniped Logo](/docs/img/pinniped_logo.svg)
|
# Getting started with Pinniped
|
||||||
|
|
||||||
## Overview
|
Pinniped is an authentication service for Kubernetes clusters.
|
||||||
|
As a Kubernetes cluster administrator or user, you can learn how Pinniped works, see how to use it on your clusters, and dive into internals of Pinniped's APIs and architecture.
|
||||||
|
|
||||||
Pinniped provides identity services to Kubernetes.
|
Have a question, comment, or idea? Please reach out via [GitHub Discussions](https://github.com/vmware-tanzu/pinniped/discussions) or [join the Pinniped community meetings]({{< ref "/community" >}}).
|
||||||
|
|
||||||
Pinniped allows cluster administrators to easily plug in external identity
|
## Tutorials
|
||||||
providers (IDPs) into Kubernetes clusters. This is achieved via a uniform
|
|
||||||
install procedure across all types and origins of Kubernetes clusters,
|
|
||||||
declarative configuration via Kubernetes APIs, enterprise-grade integrations
|
|
||||||
with IDPs, and distribution-specific integration strategies.
|
|
||||||
|
|
||||||
### Example Use Cases
|
{{< docsmenu "tutorials" >}}
|
||||||
|
|
||||||
* Your team uses a large enterprise IDP, and has many clusters that they
|
## How-to guides
|
||||||
manage. Pinniped provides:
|
|
||||||
* Seamless and robust integration with the IDP
|
|
||||||
* Easy installation across clusters of any type and origin
|
|
||||||
* A simplified login flow across all clusters
|
|
||||||
* Your team shares a single cluster. Pinniped provides:
|
|
||||||
* Simple configuration to integrate an IDP
|
|
||||||
* Individual, revocable identities
|
|
||||||
|
|
||||||
### Architecture
|
{{< docsmenu "howtos" >}}
|
||||||
|
|
||||||
Pinniped offers credential exchange to enable a user to exchange an external IDP
|
## Reference
|
||||||
credential for a short-lived, cluster-specific credential. Pinniped supports various
|
|
||||||
IDP types and implements different integration strategies for various Kubernetes
|
|
||||||
distributions to make authentication possible.
|
|
||||||
|
|
||||||
To learn more, see [docs/architecture](/docs/architecture).
|
{{< docsmenu "reference" >}}
|
||||||
|
|
||||||
<img src="docs/img/pinniped_architecture_concierge_supervisor.svg" alt="Pinniped Architecture Sketch" width="300px"/>
|
## Background
|
||||||
|
|
||||||
## Trying Pinniped
|
{{< docsmenu "background" >}}
|
||||||
|
|
||||||
Care to kick the tires? It's easy to [install and try Pinniped](/docs/demo).
|
|
||||||
|
|
||||||
## Discussion
|
|
||||||
|
|
||||||
Got a question, comment, or idea? Please don't hesitate to reach out via the GitHub [Discussions](https://github.com/vmware-tanzu/pinniped/discussions) tab at the top of this page.
|
|
||||||
|
|
||||||
## Contributions
|
|
||||||
|
|
||||||
Contributions are welcome. Before contributing, please see the [contributing guide](https://github.com/vmware-tanzu/pinniped/blob/main/CONTRIBUTING.md).
|
|
||||||
|
|
||||||
## Reporting Security Vulnerabilities
|
|
||||||
|
|
||||||
Please follow the procedure described in [SECURITY.md](https://github.com/vmware-tanzu/pinniped/blob/main/SECURITY.md).
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Pinniped is open source and licensed under Apache License Version 2.0. See [LICENSE](https://github.com/vmware-tanzu/pinniped/blob/main/LICENSE).
|
|
||||||
|
|
||||||
Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
|
||||||
|
13
site/content/docs/background/_index.md
Normal file
13
site/content/docs/background/_index.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Background
|
||||||
|
identifier: background
|
||||||
|
weight: 110
|
||||||
|
---
|
||||||
|
|
||||||
|
# Pinniped background
|
||||||
|
|
||||||
|
{{< docsmenu "background" >}}
|
@ -1,16 +1,20 @@
|
|||||||
---
|
---
|
||||||
title: "Pinniped Architecture"
|
title: Architecture
|
||||||
|
description: Dive into the overall design and implementation details of Pinniped.
|
||||||
cascade:
|
cascade:
|
||||||
layout: docs
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Architecture
|
||||||
|
weight: 100
|
||||||
|
parent: background
|
||||||
---
|
---
|
||||||
|
|
||||||
# Architecture
|
|
||||||
|
|
||||||
The principal purpose of Pinniped is to allow users to access Kubernetes
|
The principal purpose of Pinniped is to allow users to access Kubernetes
|
||||||
clusters. Pinniped hopes to enable this access across a wide range of Kubernetes
|
clusters. Pinniped hopes to enable this access across a wide range of Kubernetes
|
||||||
environments with zero configuration.
|
environments with zero configuration.
|
||||||
|
|
||||||
Pinniped is composed of two parts.
|
Pinniped is composed of two parts.
|
||||||
|
|
||||||
1. The Pinniped Supervisor is an OIDC server which allows users to authenticate
|
1. The Pinniped Supervisor is an OIDC server which allows users to authenticate
|
||||||
with an external identity provider (IDP), and then issues its own federation ID tokens
|
with an external identity provider (IDP), and then issues its own federation ID tokens
|
||||||
to be passed on to clusters based on the user information from the IDP.
|
to be passed on to clusters based on the user information from the IDP.
|
||||||
@ -24,14 +28,6 @@ understood by the host Kubernetes cluster.
|
|||||||
Pinniped supports various authenticator types and OIDC identity providers and implements different integration strategies
|
Pinniped supports various authenticator types and OIDC identity providers and implements different integration strategies
|
||||||
for various Kubernetes distributions to make authentication possible.
|
for various Kubernetes distributions to make authentication possible.
|
||||||
|
|
||||||
## Supported Kubernetes Cluster Types
|
|
||||||
|
|
||||||
Pinniped supports the following types of Kubernetes clusters:
|
|
||||||
|
|
||||||
- Clusters where the Kube Controller Manager pod is accessible from Pinniped's pods.
|
|
||||||
|
|
||||||
Support for other types of Kubernetes distributions is coming soon.
|
|
||||||
|
|
||||||
## External Identity Provider Integrations
|
## External Identity Provider Integrations
|
||||||
|
|
||||||
The Pinniped Supervisor will federate identity from one or more IDPs.
|
The Pinniped Supervisor will federate identity from one or more IDPs.
|
@ -1,9 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Pinniped Demo"
|
|
||||||
cascade:
|
|
||||||
layout: docs
|
|
||||||
---
|
|
||||||
|
|
||||||
# Trying Pinniped
|
|
||||||
1. [Concierge with webhook demo](/docs/concierge-only-demo)
|
|
||||||
1. [Concierge with Supervisor and JWT authenticator demo](/docs/concierge-and-supervisor-demo)
|
|
14
site/content/docs/howto/_index.md
Normal file
14
site/content/docs/howto/_index.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
title: Pinniped How-To Guides
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: How-to Guides
|
||||||
|
identifier: howtos
|
||||||
|
weight: 50
|
||||||
|
---
|
||||||
|
|
||||||
|
These how-to guides show you how to install and configure the Pinniped command-line tool, Concierge, and Supervisor:
|
||||||
|
|
||||||
|
{{< docsmenu "howtos" >}}
|
142
site/content/docs/howto/configure-concierge-jwt.md
Normal file
142
site/content/docs/howto/configure-concierge-jwt.md
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
---
|
||||||
|
title: Configure the Pinniped Concierge to validate JWT tokens
|
||||||
|
description: Set up JSON Web Token (JWT) based token authentication on an individual Kubernetes cluster.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Configure Concierge JWT Authentication
|
||||||
|
weight: 25
|
||||||
|
parent: howtos
|
||||||
|
---
|
||||||
|
The Concierge can validate [JSON Web Tokens (JWTs)](https://tools.ietf.org/html/rfc7519), which are commonly issued by [OpenID Connect (OIDC)](https://openid.net/connect/) identity providers.
|
||||||
|
|
||||||
|
This guide shows you how to use this capability _without_ the Pinniped Supervisor.
|
||||||
|
This is most useful if you have only a single cluster and want to authenticate to it via an existing OIDC provider.
|
||||||
|
|
||||||
|
If you have multiple clusters, you may want to [install]({{< ref "install-supervisor" >}}) and [configure]({{< ref "configure-supervisor" >}}) the Pinniped Supervisor.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before starting, you should have the [command-line tool installed]({{< ref "install-cli" >}}) locally and [Concierge running in your cluster]({{< ref "install-concierge" >}}).
|
||||||
|
|
||||||
|
You should also have some existing OIDC issuer configuration:
|
||||||
|
|
||||||
|
- An OIDC provider that supports [discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) and the `email` scope.
|
||||||
|
- A public client with callback URI `http://127.0.0.1:12345/callback` and `email` scope.
|
||||||
|
|
||||||
|
## Create a JWTAuthenticator
|
||||||
|
|
||||||
|
Create a JWTAuthenticator describing how to validate tokens from your OIDC issuer:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
|
||||||
|
kind: JWTAuthenticator
|
||||||
|
metadata:
|
||||||
|
name: my-jwt-authenticator
|
||||||
|
spec:
|
||||||
|
issuer: https://my-issuer.example.com/any/path
|
||||||
|
audience: my-client-id
|
||||||
|
claims:
|
||||||
|
username: email
|
||||||
|
```
|
||||||
|
|
||||||
|
If you've saved this into a file `my-jwt-authenticator.yaml`, then install it into your cluster using:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f my-jwt-authenticator.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generate a kubeconfig file
|
||||||
|
|
||||||
|
Generate a kubeconfig file to target the JWTAuthenticator:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pinniped get kubeconfig \
|
||||||
|
--oidc-client-id my-client-id \
|
||||||
|
--oidc-scopes openid,email \
|
||||||
|
--oidc-listen-port 12345 \
|
||||||
|
> my-cluster.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a kubeconfig YAML file `my-cluster.yaml` that targets your JWTAuthenticator using `pinniped login oidc` as an [ExecCredential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins).
|
||||||
|
|
||||||
|
It should look something like below:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Config
|
||||||
|
current-context: pinniped
|
||||||
|
clusters:
|
||||||
|
- cluster:
|
||||||
|
certificate-authority-data: LS0tLS[...]
|
||||||
|
server: https://my-kubernetes-api-endpoint.example.com:59986
|
||||||
|
name: pinniped
|
||||||
|
contexts:
|
||||||
|
- context:
|
||||||
|
cluster: pinniped
|
||||||
|
user: pinniped
|
||||||
|
name: pinniped
|
||||||
|
users:
|
||||||
|
- name: pinniped
|
||||||
|
user:
|
||||||
|
exec:
|
||||||
|
apiVersion: client.authentication.k8s.io/v1beta1
|
||||||
|
command: /usr/local/bin/pinniped
|
||||||
|
args:
|
||||||
|
- login
|
||||||
|
- oidc
|
||||||
|
- --enable-concierge
|
||||||
|
- --concierge-api-group-suffix=pinniped.dev
|
||||||
|
- --concierge-authenticator-name=my-jwt-authenticator
|
||||||
|
- --concierge-authenticator-type=jwt
|
||||||
|
- --concierge-endpoint=https://my-kubernetes-api-endpoint.example.com:59986
|
||||||
|
- --concierge-ca-bundle-data=LS0tLS[...]
|
||||||
|
- --issuer=https://my-oidc-issuer.example.com/any/path
|
||||||
|
- --client-id=my-client-id
|
||||||
|
- --scopes=offline_access,openid,email
|
||||||
|
- --listen-port=12345
|
||||||
|
- --request-audience=my-client-id
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the kubeconfig file
|
||||||
|
|
||||||
|
Use the kubeconfig with `kubectl` to access your cluster:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl --kubeconfig my-cluster.yaml get namespaces
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see:
|
||||||
|
|
||||||
|
- The `pinniped login oidc` command is executed automatically by `kubectl`.
|
||||||
|
|
||||||
|
- Pinniped opens your browser window and directs you to login with your identity provider.
|
||||||
|
|
||||||
|
- After you've logged in, you see a page telling you `you have been logged in and may now close this tab`.
|
||||||
|
|
||||||
|
- In your shell, you see your clusters namespaces.
|
||||||
|
|
||||||
|
If instead you get an access denied error, you may need to create a ClusterRoleBinding for the `email` of your OIDC account, for example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl create clusterrolebinding my-user-admin \
|
||||||
|
--clusterrole admin \
|
||||||
|
--user my-username@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Other notes
|
||||||
|
|
||||||
|
- Pinniped kubeconfig files do not contain secrets and are safe to share between users.
|
||||||
|
|
||||||
|
- Temporary OIDC session credentials such as ID, access, and refresh tokens are stored in:
|
||||||
|
- `~/.config/pinniped/sessions.yaml` (macOS/Linux)
|
||||||
|
- `%USERPROFILE%/.config/pinniped/sessions.yaml` (Windows).
|
||||||
|
|
||||||
|
- If your OIDC provider supports [wildcard port number matching](https://tools.ietf.org/html/draft-ietf-oauth-security-topics-16#section-2.1) for localhost URIs, you can omit the `--oidc-listen-port` flag to use a randomly chosen ephemeral TCP port.
|
||||||
|
|
||||||
|
- The Pinniped command-line tool can only act as a public client with no client secret.
|
||||||
|
If your provider only supports non-public clients, consider using the Pinniped Supervisor.
|
||||||
|
|
||||||
|
- In general, it is not safe to use the same OIDC client across multiple clusters.
|
||||||
|
If you need to access multiple clusters, please [install the Pinniped Supervisor]({{< ref "install-supervisor" >}}).
|
116
site/content/docs/howto/configure-concierge-webhook.md
Normal file
116
site/content/docs/howto/configure-concierge-webhook.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
---
|
||||||
|
title: Configure the Pinniped Concierge to validate webhook tokens
|
||||||
|
description: Set up webhook-based token authentication on an individual Kubernetes cluster.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Configure Concierge Webhook Authentication
|
||||||
|
weight: 26
|
||||||
|
parent: howtos
|
||||||
|
---
|
||||||
|
|
||||||
|
The Concierge can validate arbitrary tokens via an external webhook endpoint using the [same validation process as Kubernetes itself](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication).
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
Before starting, you should have the [command-line tool installed]({{< ref "install-cli" >}}) locally and [Concierge running in your cluster]({{< ref "install-concierge" >}}).
|
||||||
|
|
||||||
|
You should also have a custom TokenReview webhook endpoint:
|
||||||
|
|
||||||
|
- Your webhook endpoint must handle the `authentication.k8s.io/v1` [TokenReview API](https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/token-review-v1/#TokenReview).
|
||||||
|
|
||||||
|
- Your webhook must be accessible from the Concierge pod over HTTPS.
|
||||||
|
|
||||||
|
## Create a WebhookAuthenticator
|
||||||
|
|
||||||
|
Create a WebhookAuthenticator describing how to validate tokens using your webhook:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
|
||||||
|
kind: WebhookAuthenticator
|
||||||
|
metadata:
|
||||||
|
name: my-webhook-authenticator
|
||||||
|
spec:
|
||||||
|
# HTTPS endpoint to be called as a webhook
|
||||||
|
endpoint: https://my-webhook.example.com/any/path
|
||||||
|
tls:
|
||||||
|
# base64-encoded PEM CA bundle (optional)
|
||||||
|
certificateAuthorityData: "LS0tLS1CRUdJTi[...]"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you've saved this into a file `my-webhook-authenticator.yaml`, then install it into your cluster using:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl apply -f my-webhook-authenticator.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Generate a kubeconfig file
|
||||||
|
|
||||||
|
Generate a kubeconfig file to target the WebhookAuthenticator:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pinniped get kubeconfig \
|
||||||
|
--static-token-env MY_CLUSTER_ACCESS_TOKEN \
|
||||||
|
> my-cluster.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a kubeconfig YAML file `my-cluster.yaml` that targets your WebhookAuthenticator using `pinniped login static` as an [ExecCredential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins).
|
||||||
|
|
||||||
|
It should look something like below:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Config
|
||||||
|
current-context: pinniped
|
||||||
|
clusters:
|
||||||
|
- cluster:
|
||||||
|
certificate-authority-data: LS0tLS[...]
|
||||||
|
server: https://my-kubernetes-api-endpoint.example.com:59986
|
||||||
|
name: pinniped
|
||||||
|
contexts:
|
||||||
|
- context:
|
||||||
|
cluster: pinniped
|
||||||
|
user: pinniped
|
||||||
|
name: pinniped
|
||||||
|
users:
|
||||||
|
- name: pinniped
|
||||||
|
user:
|
||||||
|
exec:
|
||||||
|
apiVersion: client.authentication.k8s.io/v1beta1
|
||||||
|
command: /usr/local/bin/pinniped
|
||||||
|
args:
|
||||||
|
- login
|
||||||
|
- oidc
|
||||||
|
- login
|
||||||
|
- static
|
||||||
|
- --enable-concierge
|
||||||
|
- --concierge-api-group-suffix=pinniped.dev
|
||||||
|
- --concierge-authenticator-name=my-webhook-authenticator
|
||||||
|
- --concierge-authenticator-type=webhook
|
||||||
|
- --concierge-endpoint=https://127.0.0.1:59986
|
||||||
|
- --concierge-ca-bundle-data=LS0tLS[...]
|
||||||
|
- --token-env=MY_CLUSTER_ACCESS_TOKEN
|
||||||
|
```
|
||||||
|
|
||||||
|
## Use the kubeconfig file
|
||||||
|
|
||||||
|
Set the `$MY_CLUSTER_ACCESS_TOKEN` environment variable and use the kubeconfig with `kubectl` to access your cluster:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
MY_CLUSTER_ACCESS_TOKEN=secret-token kubectl --kubeconfig my-cluster.yaml get namespaces
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see:
|
||||||
|
|
||||||
|
- The `pinniped login static` command is silently executed automatically by `kubectl`.
|
||||||
|
|
||||||
|
- The command-line tool sends your token to the Concierge which validates it by making a request to your webhook endpoint.
|
||||||
|
|
||||||
|
- In your shell, you see your clusters namespaces.
|
||||||
|
|
||||||
|
If instead you get an access denied error, you may need to create a ClusterRoleBinding for the username/groups returned by your webhook, for example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kubectl create clusterrolebinding my-user-admin --clusterrole admin --user my-username
|
||||||
|
```
|
161
site/content/docs/howto/configure-supervisor.md
Normal file
161
site/content/docs/howto/configure-supervisor.md
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
---
|
||||||
|
title: Configure the Pinniped Supervisor as an OIDC issuer
|
||||||
|
description: Set up the Pinniped Supervisor to provide seamless login flows across multiple clusters.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Configure Supervisor
|
||||||
|
weight: 35
|
||||||
|
parent: howtos
|
||||||
|
---
|
||||||
|
The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single "upstream" OIDC identity provider to many "downstream" cluster clients.
|
||||||
|
|
||||||
|
This guide show you how to use this capability to issue [JSON Web Tokens (JWTs)](https://tools.ietf.org/html/rfc7519) that can be validated by the [Pinniped Concierge]({{< ref "configure-concierge-jwt" >}}).
|
||||||
|
|
||||||
|
Before starting, you should have the [command-line tool installed]({{< ref "install-cli" >}}) locally and the Concierge [installed]({{< ref "install-concierge" >}}) in your cluster.
|
||||||
|
|
||||||
|
## Expose the Supervisor app as a service
|
||||||
|
|
||||||
|
The Supervisor app's endpoints should be exposed as HTTPS endpoints with proper TLS certificates signed by a certificate authority (CA) which is trusted by your user's web browsers.
|
||||||
|
|
||||||
|
Because there are many ways to expose TLS services from a Kubernetes cluster, the Supervisor app leaves this up to the user.
|
||||||
|
The most common ways are:
|
||||||
|
|
||||||
|
1. Define an [`Ingress` resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) with TLS certificates.
|
||||||
|
In this case, the ingress terminates TLS. Typically, the ingress then talks plain HTTP to its backend,
|
||||||
|
which would be a NodePort or LoadBalancer Service in front of the HTTP port 8080 of the Supervisor pods.
|
||||||
|
|
||||||
|
The required configuration of the Ingress is specific to your cluster's Ingress Controller, so please refer to the
|
||||||
|
documentation from your Kubernetes provider. If you are using a cluster from a cloud provider, then you'll probably
|
||||||
|
want to start with that provider's documentation. For example, if your cluster is a Google GKE cluster, refer to
|
||||||
|
the [GKE documentation for Ingress](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress).
|
||||||
|
Otherwise, the Kubernetes documentation provides a list of popular
|
||||||
|
[Ingress Controllers](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/), including
|
||||||
|
[Contour](https://projectcontour.io/) and many others.
|
||||||
|
|
||||||
|
1. Or, define a [TCP LoadBalancer Service](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer)
|
||||||
|
which is a layer 4 load balancer and does not terminate TLS. In this case, the Supervisor app needs to be
|
||||||
|
configured with TLS certificates and terminates the TLS connection itself (see the section about FederationDomain
|
||||||
|
below). The LoadBalancer Service should be configured to use the HTTPS port 443 of the Supervisor pods as its `targetPort`.
|
||||||
|
|
||||||
|
*Warning:* do not expose the Supervisor's port 8080 to the public. It would not be secure for the OIDC protocol
|
||||||
|
to use HTTP, because the user's secret OIDC tokens would be transmitted across the network without encryption.
|
||||||
|
|
||||||
|
1. Or, expose the Supervisor app using a Kubernetes service mesh technology, for example [Istio](https://istio.io/).
|
||||||
|
Please see the documentation for your service mesh. Generally, the setup would be similar to the previous description
|
||||||
|
for defining an ingress, except the service mesh would probably provide both the ingress with TLS termination
|
||||||
|
and the service.
|
||||||
|
|
||||||
|
For either of the first two options, if you installed using `ytt` then you can use
|
||||||
|
the related `service_*` options from [deploy/supervisor/values.yml](values.yaml) to create a Service.
|
||||||
|
If you installed using `install-supervisor.yaml` then you can create
|
||||||
|
the Service separately after installing the Supervisor app. There is no `Ingress` included in the `ytt` templates,
|
||||||
|
so if you choose to use an Ingress then you'll need to create that separately after installing the Supervisor app.
|
||||||
|
|
||||||
|
#### Example: Using a LoadBalancer Service
|
||||||
|
|
||||||
|
This is an example of creating a LoadBalancer Service to expose port 8443 of the Supervisor app outside the cluster.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: pinniped-supervisor-loadbalancer
|
||||||
|
# Assuming that this is the namespace where the supervisor was installed. This is the default in install-supervisor.yaml.
|
||||||
|
namespace: pinniped-supervisor
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector:
|
||||||
|
# Assuming that this is how the supervisor pods are labeled. This is the default in install-supervisor.yaml.
|
||||||
|
app: pinniped-supervisor
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 443
|
||||||
|
targetPort: 8443
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example: Using a NodePort Service
|
||||||
|
|
||||||
|
A NodePort Service exposes the app as a port on the nodes of the cluster.
|
||||||
|
|
||||||
|
This is convenient for use with kind clusters, because kind can
|
||||||
|
[expose node ports as localhost ports on the host machine](https://kind.sigs.k8s.io/docs/user/configuration/#extra-port-mappings)
|
||||||
|
without requiring an Ingress, although
|
||||||
|
[kind also supports several Ingress Controllers](https://kind.sigs.k8s.io/docs/user/ingress).
|
||||||
|
|
||||||
|
A NodePort Service could also be used behind an Ingress which is terminating TLS.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: pinniped-supervisor-nodeport
|
||||||
|
# Assuming that this is the namespace where the supervisor was installed. This is the default in install-supervisor.yaml.
|
||||||
|
namespace: pinniped-supervisor
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
# Assuming that this is how the supervisor pods are labeled. This is the default in install-supervisor.yaml.
|
||||||
|
app: pinniped-supervisor
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
nodePort: 31234 # This is the port that you would forward to the kind host. Or omit this key for a random port.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuring the Supervisor to act as an OIDC provider
|
||||||
|
|
||||||
|
The Supervisor can be configured as an OIDC provider by creating `FederationDomain` resources
|
||||||
|
in the same namespace where the Supervisor app was installed. For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: config.supervisor.pinniped.dev/v1alpha1
|
||||||
|
kind: FederationDomain
|
||||||
|
metadata:
|
||||||
|
name: my-provider
|
||||||
|
# Assuming that this is the namespace where the supervisor was installed. This is the default in install-supervisor.yaml.
|
||||||
|
namespace: pinniped-supervisor
|
||||||
|
spec:
|
||||||
|
# The hostname would typically match the DNS name of the public ingress or load balancer for the cluster.
|
||||||
|
# Any path can be specified, which allows a single hostname to have multiple different issuers. The path is optional.
|
||||||
|
issuer: https://my-issuer.example.com/any/path
|
||||||
|
|
||||||
|
# Optionally configure the name of a Secret in the same namespace, of type `kubernetes.io/tls`,
|
||||||
|
# which contains the TLS serving certificate for the HTTPS endpoints served by this OIDC Provider.
|
||||||
|
tls:
|
||||||
|
secretName: my-tls-cert-secret
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Configuring TLS for the Supervisor OIDC endpoints
|
||||||
|
|
||||||
|
If you have terminated TLS outside the app, for example using an Ingress with TLS certificates, then you do not need to
|
||||||
|
configure TLS certificates on the FederationDomain.
|
||||||
|
|
||||||
|
If you are using a LoadBalancer Service to expose the Supervisor app outside your cluster, then you
|
||||||
|
also need to configure the Supervisor app to terminate TLS. There are two places to configure TLS certificates:
|
||||||
|
|
||||||
|
1. Each `FederationDomain` can be configured with TLS certificates, using the `spec.tls.secretName` field.
|
||||||
|
|
||||||
|
1. The default TLS certificate for all OIDC providers can be configured by creating a Secret called
|
||||||
|
`pinniped-supervisor-default-tls-certificate` in the same namespace in which the Supervisor was installed.
|
||||||
|
|
||||||
|
The default TLS certificate are used for all OIDC providers which did not declare a `spec.tls.secretName`.
|
||||||
|
Also, the `spec.tls.secretName` is ignored for incoming requests to the OIDC endpoints
|
||||||
|
that use an IP address as the host, so those requests always present the default TLS certificates
|
||||||
|
to the client. When the request includes the hostname, and that hostname matches the hostname of an `Issuer`,
|
||||||
|
then the TLS certificate defined by the `spec.tls.secretName` is used. If that issuer did not
|
||||||
|
define `spec.tls.secretName` then the default TLS certificate is used. If neither exists,
|
||||||
|
then the client gets a TLS error because the server does not present any TLS certificate.
|
||||||
|
|
||||||
|
It is recommended that you have a DNS entry for your load balancer or Ingress, and that you configure the
|
||||||
|
OIDC provider's `Issuer` using that DNS hostname, and that the TLS certificate for that provider also
|
||||||
|
covers that same hostname.
|
||||||
|
|
||||||
|
You can create the certificate Secrets however you like, for example you could use [cert-manager](https://cert-manager.io/)
|
||||||
|
or `kubectl create secret tls`.
|
||||||
|
Keep in mind that your users must load some of these endpoints in their web browsers, so the TLS certificates
|
||||||
|
should be signed by a certificate authority that is trusted by their browsers.
|
55
site/content/docs/howto/install-cli.md
Normal file
55
site/content/docs/howto/install-cli.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
title: Install the Pinniped command-line tool
|
||||||
|
description: Download and set up the `pinniped` command-line tool on macOS, Linux, or Windows clients.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Install CLI
|
||||||
|
weight: 10
|
||||||
|
parent: howtos
|
||||||
|
---
|
||||||
|
The `pinniped` command-line tool is used to generate Pinniped-compatible kubeconfig files, and is also an important part of the Pinniped-based login flow.
|
||||||
|
|
||||||
|
It must be installed by administrators setting up a Pinniped cluster as well as by users accessing a Pinniped-enabled cluster.
|
||||||
|
|
||||||
|
## Install using Homebrew on macOS or Linux
|
||||||
|
|
||||||
|
Use [Homebrew](https://brew.sh/) to install from the Pinniped [tap](https://github.com/vmware-tanzu/homebrew-pinniped):
|
||||||
|
|
||||||
|
- `brew install vmware-tanzu/pinniped/pinniped-cli`
|
||||||
|
|
||||||
|
## Download binaries
|
||||||
|
|
||||||
|
Find the appropriate binary for your platform from the [latest release](https://github.com/vmware-tanzu/pinniped/releases/latest):
|
||||||
|
|
||||||
|
{{< buttonlink href="https://get.pinniped.dev/latest/pinniped-cli-darwin-amd64" >}}Download for macOS/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
||||||
|
|
||||||
|
{{< buttonlink href="https://get.pinniped.dev/latest/pinniped-cli-linux-amd64" >}}Download for Linux/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
||||||
|
|
||||||
|
{{< buttonlink href="https://get.pinniped.dev/latest/pinniped-cli-windows-amd64.exe" >}}Download for Windows/amd64{{< buttonicon "download.png" >}}{{< /buttonlink >}}
|
||||||
|
|
||||||
|
You should put the command-line tool somewhere on your `$PATH`, such as `/usr/local/bin` on macOS/Linux.
|
||||||
|
You'll also need to mark the file as executable.
|
||||||
|
|
||||||
|
To find specific versions or view all available platforms and architectures, visit the [releases page](https://github.com/vmware-tanzu/pinniped/releases/).
|
||||||
|
|
||||||
|
### Gatekeeper
|
||||||
|
|
||||||
|
If you are using macOS, you may get an error dialog when you first run `pinniped` that says `“pinniped” cannot be opened because the developer cannotbe verified`.
|
||||||
|
Cancel this dialog, open System Preferences, click Security & Privacy, and click the Allow Anyway button next to the Pinniped message.
|
||||||
|
|
||||||
|
Run the command again and another dialog appears saying `macOS cannot verify the developer of “pinniped”. Are you sure you want to open it?`.
|
||||||
|
Click Open to allow the command to proceed.
|
||||||
|
|
||||||
|
## Install a specific version via script
|
||||||
|
|
||||||
|
For example, to install v0.4.1 on Linux/amd64:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -Lso pinniped https://get.pinniped.dev/v0.4.1/pinniped-cli-linux-amd64 \
|
||||||
|
&& chmod +x pinniped \
|
||||||
|
&& sudo mv pinniped /usr/local/bin/pinniped
|
||||||
|
```
|
||||||
|
|
||||||
|
*Next, [install the Concierge]({{< ref "install-concierge.md" >}})!*
|
60
site/content/docs/howto/install-concierge.md
Normal file
60
site/content/docs/howto/install-concierge.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
title: Install the Pinniped Concierge
|
||||||
|
description: Install the Pinniped Concierge service in a Kubernetes cluster.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Install Concierge
|
||||||
|
weight: 20
|
||||||
|
parent: howtos
|
||||||
|
---
|
||||||
|
This guide shows you how to install the Pinniped Concierge.
|
||||||
|
You should have a [supported Kubernetes cluster]({{< ref "../reference/supported-clusters" >}}).
|
||||||
|
|
||||||
|
## With default options
|
||||||
|
|
||||||
|
1. Install the latest version of the Concierge into the `pinniped-concierge` namespace with default options:
|
||||||
|
|
||||||
|
- `kubectl apply -f https://get.pinniped.dev/latest/install-pinniped-concierge.yaml`
|
||||||
|
|
||||||
|
## With specific version and default options
|
||||||
|
|
||||||
|
1. Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number and use it to replace the version number in the URL below.
|
||||||
|
|
||||||
|
1. Install the Concierge into the `pinniped-concierge` namespace with default options:
|
||||||
|
|
||||||
|
- `kubectl apply -f https://get.pinniped.dev/v0.4.1/install-pinniped-concierge.yaml`
|
||||||
|
|
||||||
|
*Replace v0.4.1 with your preferred version number.*
|
||||||
|
|
||||||
|
## With custom options
|
||||||
|
|
||||||
|
Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/) as a templating system.
|
||||||
|
|
||||||
|
1. Install the `ytt` command-line tool using the instructions from the [Carvel documentation](https://carvel.dev/#whole-suite).
|
||||||
|
|
||||||
|
1. Clone the Pinniped GitHub repository and visit the `deploy/concierge` directory:
|
||||||
|
|
||||||
|
- `git clone git@github.com:vmware-tanzu/pinniped.git`
|
||||||
|
- `cd pinniped/deploy/concierge`
|
||||||
|
|
||||||
|
1. Customize configuration parameters:
|
||||||
|
|
||||||
|
- Edit `values.yaml` with your custom values.
|
||||||
|
- See the [default values](http://github.com/vmware-tanzu/pinniped/tree/main/deploy/concierge/values.yaml) for documentation about individual configuration parameters.
|
||||||
|
|
||||||
|
1. Render templated YAML manifests:
|
||||||
|
|
||||||
|
- `ytt --file .`
|
||||||
|
|
||||||
|
1. Deploy the templated YAML manifests:
|
||||||
|
|
||||||
|
- *If you're using `kubectl`:*
|
||||||
|
|
||||||
|
`ytt --file . | kubectl apply -f -`
|
||||||
|
- *If you're using [`kapp` from Carvel](https://carvel.dev/kapp/):*
|
||||||
|
|
||||||
|
`ytt --file . | kapp deploy --yes --app pinniped-concierge --diff-changes --file -`
|
||||||
|
|
||||||
|
*Next, configure the Concierge for [JWT]({{< ref "configure-concierge-jwt.md" >}}) or [webhook]({{< ref "configure-concierge-webhook.md" >}}) authentication.*
|
59
site/content/docs/howto/install-supervisor.md
Normal file
59
site/content/docs/howto/install-supervisor.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
title: Install the Pinniped Supervisor
|
||||||
|
description: Install the Pinniped Supervisor service in a Kubernetes cluster.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Install Supervisor
|
||||||
|
weight: 30
|
||||||
|
parent: howtos
|
||||||
|
---
|
||||||
|
This guide shows you how to install the Pinniped Supervisor, which allows seamless login across one or many Kubernetes clusters.
|
||||||
|
You should have a supported Kubernetes cluster with working HTTPS ingress capabilities.
|
||||||
|
<!-- TODO: link to support matrix -->
|
||||||
|
|
||||||
|
## With default options
|
||||||
|
|
||||||
|
1. Install the latest version of the Supervisor into the `pinniped-supervisor` namespace with default options:
|
||||||
|
|
||||||
|
- `kubectl apply -f https://get.pinniped.dev/latest/install-pinniped-supervisor.yaml`
|
||||||
|
|
||||||
|
## With specific version and default options
|
||||||
|
|
||||||
|
1. Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number and use it to replace the version number in the URL below.
|
||||||
|
|
||||||
|
1. Install the Supervisor into the `pinniped-supervisor` namespace with default options:
|
||||||
|
|
||||||
|
- `kubectl apply -f https://get.pinniped.dev/v0.4.1/install-pinniped-supervisor.yaml`
|
||||||
|
|
||||||
|
*Replace v0.4.1 with your preferred version number.*
|
||||||
|
|
||||||
|
## With custom options
|
||||||
|
|
||||||
|
Pinniped uses [ytt](https://carvel.dev/ytt/) from [Carvel](https://carvel.dev/) as a templating system.
|
||||||
|
|
||||||
|
1. Install the `ytt` command-line tool using the instructions from the [Carvel documentation](https://carvel.dev/#whole-suite).
|
||||||
|
|
||||||
|
1. Clone the Pinniped GitHub repository and visit the `deploy/supervisor` directory:
|
||||||
|
|
||||||
|
- `git clone git@github.com:vmware-tanzu/pinniped.git`
|
||||||
|
- `cd pinniped/deploy/supervisor`
|
||||||
|
|
||||||
|
1. Customize configuration parameters:
|
||||||
|
|
||||||
|
- Edit `values.yaml` with your custom values.
|
||||||
|
- See the [default values](http://github.com/vmware-tanzu/pinniped/tree/main/deploy/supervisor/values.yaml) for documentation about individual configuration parameters.
|
||||||
|
|
||||||
|
1. Render templated YAML manifests:
|
||||||
|
|
||||||
|
- `ytt --file .`
|
||||||
|
|
||||||
|
1. Deploy the templated YAML manifests:
|
||||||
|
|
||||||
|
- *If you're using `kubectl`:*
|
||||||
|
|
||||||
|
`ytt --file . | kubectl apply -f -`
|
||||||
|
- *If you're using [`kapp` from Carvel](https://carvel.dev/kapp/):*
|
||||||
|
|
||||||
|
`ytt --file . | kapp deploy --yes --app pinniped-supervisor --diff-changes --file -`
|
@ -1,21 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Installing Pinniped"
|
|
||||||
cascade:
|
|
||||||
layout: docs
|
|
||||||
---
|
|
||||||
|
|
||||||
# Installing Pinniped
|
|
||||||
|
|
||||||
## Install the CLI
|
|
||||||
|
|
||||||
- Find the appropriate binary for your platform from the [latest release](https://github.com/vmware-tanzu/pinniped/releases/latest).
|
|
||||||
|
|
||||||
- Use Homebrew on macOS: `brew install vmware-tanzu/pinniped/pinniped-cli`.
|
|
||||||
|
|
||||||
## Install the Concierge
|
|
||||||
|
|
||||||
- See the [concierge deployment guide](https://github.com/vmware-tanzu/pinniped/tree/main/deploy/concierge).
|
|
||||||
|
|
||||||
## Install the Supervisor
|
|
||||||
|
|
||||||
- See the [supervisor deployment guide](https://github.com/vmware-tanzu/pinniped/tree/main/deploy/supervisor).
|
|
13
site/content/docs/reference/_index.md
Normal file
13
site/content/docs/reference/_index.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Reference
|
||||||
|
identifier: reference
|
||||||
|
weight: 100
|
||||||
|
---
|
||||||
|
|
||||||
|
# Pinniped reference
|
||||||
|
|
||||||
|
{{< docsmenu "reference" >}}
|
12
site/content/docs/reference/api.md
Normal file
12
site/content/docs/reference/api.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
title: API Types
|
||||||
|
description: Reference for the `*.pinniped.dev` Kubernetes API groups.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: API Types
|
||||||
|
weight: 35
|
||||||
|
parent: reference
|
||||||
|
---
|
||||||
|
Full API reference documentation for the Pinniped Kubernetes API is available [on GitHub](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc).
|
84
site/content/docs/reference/cli.md
Normal file
84
site/content/docs/reference/cli.md
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
title: Command-Line Options Reference
|
||||||
|
description: Reference for the `pinniped` command-line tool
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Command-Line Options
|
||||||
|
weight: 30
|
||||||
|
parent: reference
|
||||||
|
---
|
||||||
|
|
||||||
|
## `pinniped version`
|
||||||
|
|
||||||
|
Print the version of this Pinniped CLI.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pinniped version [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `-h`, `--help`:
|
||||||
|
|
||||||
|
help for kubeconfig
|
||||||
|
|
||||||
|
## `pinniped get kubeconfig`
|
||||||
|
|
||||||
|
Generate a Pinniped-based kubeconfig for a cluster.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pinniped get kubeconfig [flags]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `-h`, `--help`:
|
||||||
|
|
||||||
|
help for kubeconfig
|
||||||
|
|
||||||
|
- `--concierge-api-group-suffix string`:
|
||||||
|
|
||||||
|
Concierge API group suffix (default "pinniped.dev")
|
||||||
|
- `--concierge-authenticator-name string`:
|
||||||
|
|
||||||
|
Concierge authenticator name (default: autodiscover)
|
||||||
|
- `--concierge-authenticator-type string`:
|
||||||
|
|
||||||
|
Concierge authenticator type (e.g., 'webhook', 'jwt') (default: autodiscover)
|
||||||
|
- `--kubeconfig string`:
|
||||||
|
|
||||||
|
Path to kubeconfig file
|
||||||
|
- `--kubeconfig-context string`:
|
||||||
|
|
||||||
|
Kubeconfig context name (default: current active context)
|
||||||
|
- `--no-concierge`:
|
||||||
|
|
||||||
|
Generate a configuration which does not use the concierge, but sends the credential to the cluster directly
|
||||||
|
- `--oidc-ca-bundle strings`:
|
||||||
|
|
||||||
|
Path to TLS certificate authority bundle (PEM format, optional, can be repeated)
|
||||||
|
- `--oidc-client-id string`:
|
||||||
|
|
||||||
|
OpenID Connect client ID (default: autodiscover) (default "pinniped-cli")
|
||||||
|
- `--oidc-issuer string`:
|
||||||
|
|
||||||
|
OpenID Connect issuer URL (default: autodiscover)
|
||||||
|
- `--oidc-listen-port uint16`:
|
||||||
|
|
||||||
|
TCP port for localhost listener (authorization code flow only)
|
||||||
|
- `--oidc-request-audience string`:
|
||||||
|
|
||||||
|
Request a token with an alternate audience using RFC8693 token exchange
|
||||||
|
- `--oidc-scopes strings`:
|
||||||
|
|
||||||
|
OpenID Connect scopes to request during login (default [offline_access,openid,pinniped:request-audience])
|
||||||
|
- `--oidc-session-cache string`:
|
||||||
|
|
||||||
|
Path to OpenID Connect session cache file
|
||||||
|
- `--oidc-skip-browser`:
|
||||||
|
|
||||||
|
During OpenID Connect login, skip opening the browser (just print the URL)
|
||||||
|
- `--static-token string`:
|
||||||
|
|
||||||
|
Instead of doing an OIDC-based login, specify a static token
|
||||||
|
- `--static-token-env string`:
|
||||||
|
|
||||||
|
Instead of doing an OIDC-based login, read a static token from the environment
|
29
site/content/docs/reference/supported-clusters.md
Normal file
29
site/content/docs/reference/supported-clusters.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
title: Supported cluster types
|
||||||
|
description: See the supported cluster types for the Pinniped Concierge.
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Supported Cluster Types
|
||||||
|
weight: 10
|
||||||
|
parent: reference
|
||||||
|
---
|
||||||
|
|
||||||
|
| **Cluster Type** | **Concierge Works?** |
|
||||||
|
|-|-|
|
||||||
|
| [VMware Tanzu Kubernetes Grid (TKG) clusters](https://tanzu.vmware.com/kubernetes-grid) | Yes |
|
||||||
|
| [Kind clusters](https://kind.sigs.k8s.io/) | Yes |
|
||||||
|
| [Kubeadm-based clusters](https://kubernetes.io/docs/reference/setup-tools/kubeadm/) | Yes |
|
||||||
|
| [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/) | No |
|
||||||
|
| [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) | No |
|
||||||
|
| [Azure Kubernetes Service (AKS)](https://azure.microsoft.com/en-us/overview/kubernetes-on-azure) | No |
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
The Pinniped Concierge currently supports clusters where a custom pod can be executed on the same node running `kube-controller-manager`.
|
||||||
|
This type of cluster is typically called "self-hosted" because the cluster's control plane is running on nodes that are part of the cluster itself.
|
||||||
|
|
||||||
|
In practice, this means that many Kubernetes distributions are supported, but not most managed Kubernetes services
|
||||||
|
|
||||||
|
Support for more cluster types, including managed Kubernetes environments, is planned.
|
@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Pinniped Scope"
|
|
||||||
cascade:
|
|
||||||
layout: docs
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
# Project Scope
|
|
||||||
|
|
||||||
The Pinniped project is guided by the following principles.
|
|
||||||
* Pinniped lets you plug any external identity providers into
|
|
||||||
Kubernetes. These integrations follow enterprise-grade security principles.
|
|
||||||
* Pinniped is easy to install and use on any Kubernetes cluster via
|
|
||||||
distribution-specific integration mechanisms.
|
|
||||||
* Pinniped uses a declarative configuration via Kubernetes APIs.
|
|
||||||
* Pinniped provides optimal user experience when authenticating to many
|
|
||||||
clusters at one time.
|
|
||||||
* Pinniped provides enterprise-grade security posture via secure defaults and
|
|
||||||
revocable or very short-lived credentials.
|
|
||||||
* Where possible, Pinniped will contribute ideas and code to upstream
|
|
||||||
Kubernetes.
|
|
||||||
|
|
||||||
When contributing to Pinniped, please consider whether your contribution follows
|
|
||||||
these guiding principles.
|
|
||||||
|
|
||||||
## Out Of Scope
|
|
||||||
|
|
||||||
The following items are out of scope for the Pinniped project.
|
|
||||||
* Authorization.
|
|
||||||
* Standalone identity provider for general use.
|
|
||||||
* Machine-to-machine (service) identity.
|
|
||||||
* Running outside of Kubernetes.
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
More details coming soon!
|
|
||||||
|
|
||||||
For more details on proposing features and bugs, check out our
|
|
||||||
[contributing](https://github.com/vmware-tanzu/pinniped/blob/main/CONTRIBUTING.md) doc.
|
|
15
site/content/docs/tutorials/_index.md
Normal file
15
site/content/docs/tutorials/_index.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
cascade:
|
||||||
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Tutorials
|
||||||
|
identifier: tutorials
|
||||||
|
weight: 40
|
||||||
|
---
|
||||||
|
|
||||||
|
# Pinniped tutorials
|
||||||
|
|
||||||
|
These tutorials demonstrate how to use the Pinniped command-line tool, Concierge, and Supervisor:
|
||||||
|
|
||||||
|
{{< docsmenu "tutorials" >}}
|
@ -1,11 +1,14 @@
|
|||||||
---
|
---
|
||||||
title: "Pinniped Concierge and Supervisor Demo"
|
title: Learn to use the Pinniped Supervisor alongside the Concierge
|
||||||
|
description: See how the Pinniped Supervisor streamlines login to multiple Kubernetes clusters.
|
||||||
cascade:
|
cascade:
|
||||||
layout: docs
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Concierge with Supervisor
|
||||||
|
parent: tutorials
|
||||||
---
|
---
|
||||||
|
|
||||||
# Trying Pinniped Supervisor and Concierge
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
1. A Kubernetes cluster of a type supported by Pinniped Concierge as described in [architecture](/docs/architecture).
|
1. A Kubernetes cluster of a type supported by Pinniped Concierge as described in [architecture](/docs/architecture).
|
||||||
@ -13,18 +16,18 @@ cascade:
|
|||||||
Don't have a cluster handy? Consider using [kind](https://kind.sigs.k8s.io/) on your local machine.
|
Don't have a cluster handy? Consider using [kind](https://kind.sigs.k8s.io/) on your local machine.
|
||||||
See below for an example of using kind.
|
See below for an example of using kind.
|
||||||
|
|
||||||
1. A Kubernetes cluster of a type supported by Pinniped Supervisor (this can be the same cluster as the above, or different).
|
1. A Kubernetes cluster of a type supported by Pinniped Supervisor (this can be the same cluster as the first, or different).
|
||||||
|
|
||||||
1. A kubeconfig that has admin-like privileges on each cluster.
|
1. A kubeconfig that has administrator-like privileges on each cluster.
|
||||||
|
|
||||||
1. An external OIDC identity provider to use as the source of identity for Pinniped.
|
1. An external OIDC identity provider to use as the source of identity for Pinniped.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Installing and trying Pinniped on any cluster will consist of the following general steps. See the next section below
|
Installing and trying Pinniped on any cluster consists of the following general steps. See the next section below
|
||||||
for a more specific example, including the commands to use for that case.
|
for a more specific example, including the commands to use for that case.
|
||||||
|
|
||||||
1. Install the Pinniped Supervisor. See [deploy/supervisor/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/supervisor/README.md).
|
1. [Install the Supervisor]({{< ref "../howto/install-supervisor" >}}).
|
||||||
1. Create a
|
1. Create a
|
||||||
[`FederationDomain`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-supervisor-config-v1alpha1-federationdomain)
|
[`FederationDomain`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-supervisor-config-v1alpha1-federationdomain)
|
||||||
via the installed Pinniped Supervisor.
|
via the installed Pinniped Supervisor.
|
||||||
@ -35,31 +38,31 @@ for a more specific example, including the commands to use for that case.
|
|||||||
1. Create a
|
1. Create a
|
||||||
[`JWTAuthenticator`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticator)
|
[`JWTAuthenticator`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticator)
|
||||||
via the installed Pinniped Concierge.
|
via the installed Pinniped Concierge.
|
||||||
1. Download the Pinniped CLI from [Pinniped's github Releases page](https://github.com/vmware-tanzu/pinniped/releases/latest).
|
1. [Install the Pinniped command-line tool]({{< ref "../howto/install-cli" >}}).
|
||||||
1. Generate a kubeconfig using the Pinniped CLI. Run `pinniped get kubeconfig --help` for more information.
|
1. Generate a kubeconfig using the Pinniped command-line tool. Run `pinniped get kubeconfig --help` for more information.
|
||||||
1. Run `kubectl` commands using the generated kubeconfig. The Pinniped Supervisor and Concierge will automatically be used for authentication during those commands.
|
1. Run `kubectl` commands using the generated kubeconfig. The Pinniped Supervisor and Concierge are automatically used for authentication during those commands.
|
||||||
|
|
||||||
## Example of Deploying on Multiple kind Clusters
|
## Example of deploying on multiple kind clusters
|
||||||
|
|
||||||
[kind](https://kind.sigs.k8s.io) is a tool for creating and managing Kubernetes clusters on your local machine
|
[kind](https://kind.sigs.k8s.io) is a tool for creating and managing Kubernetes clusters on your local machine
|
||||||
which uses Docker containers as the cluster's "nodes". This is a convenient way to try out Pinniped on local
|
which uses Docker containers as the cluster's nodes. This is a convenient way to try out Pinniped on local
|
||||||
non-production clusters.
|
non-production clusters.
|
||||||
|
|
||||||
The following steps will deploy the latest release of Pinniped on kind. It will deploy the Pinniped
|
The following steps deploy the latest release of Pinniped on kind. They deploy the Pinniped
|
||||||
Supervisor on one cluster, and the Pinniped Concierge on another cluster. A multi-cluster deployment
|
Supervisor on one cluster, and the Pinniped Concierge on another cluster. A multi-cluster deployment
|
||||||
strategy is typical for Pinniped. The Pinniped Concierge will use a
|
strategy is typical for Pinniped. The Pinniped Concierge uses a
|
||||||
[`JWTAuthenticator`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticator)
|
[`JWTAuthenticator`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticator)
|
||||||
to authenticate federated identities from the Supervisor.
|
to authenticate federated identities from the Supervisor.
|
||||||
|
|
||||||
1. Install the tools required for the following steps.
|
1. Install the tools required for the following steps.
|
||||||
|
|
||||||
- [Install kind](https://kind.sigs.k8s.io/docs/user/quick-start/), if not already installed. e.g. `brew install kind` on MacOS.
|
- [Install kind](https://kind.sigs.k8s.io/docs/user/quick-start/), if not already installed. For example, `brew install kind` on macOS.
|
||||||
|
|
||||||
- kind depends on Docker. If not already installed, [install Docker](https://docs.docker.com/get-docker/), e.g. `brew cask install docker` on MacOS.
|
- kind depends on Docker. If not already installed, [install Docker](https://docs.docker.com/get-docker/), for example `brew cask install docker` on macOS.
|
||||||
|
|
||||||
- This demo requires `kubectl`, which comes with Docker, or can be [installed separately](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
- This demo requires `kubectl`, which comes with Docker, or can be [installed separately](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
||||||
|
|
||||||
- This demo requires `openssl`, which is installed on MacOS by default, or can be [installed separately](https://www.openssl.org/).
|
- This demo requires `openssl`, which is installed on macOS by default, or can be [installed separately](https://www.openssl.org/).
|
||||||
|
|
||||||
1. Create a new Kubernetes cluster for the Pinniped Supervisor using `kind create cluster --name pinniped-supervisor`.
|
1. Create a new Kubernetes cluster for the Pinniped Supervisor using `kind create cluster --name pinniped-supervisor`.
|
||||||
|
|
||||||
@ -68,10 +71,10 @@ to authenticate federated identities from the Supervisor.
|
|||||||
1. Deploy the Pinniped Supervisor with a valid serving certificate and network path. See
|
1. Deploy the Pinniped Supervisor with a valid serving certificate and network path. See
|
||||||
[deploy/supervisor/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/supervisor/README.md).
|
[deploy/supervisor/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/supervisor/README.md).
|
||||||
|
|
||||||
For purposes of this demo, the following issuer will be used. This issuer is specific to DNS and
|
For purposes of this demo, the following issuer is used. This issuer is specific to DNS and
|
||||||
TLS infrastructure set up for this demo.
|
TLS infrastructure set up for this demo:
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
issuer=https://my-supervisor.demo.pinniped.dev
|
issuer=https://my-supervisor.demo.pinniped.dev
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -88,7 +91,7 @@ to authenticate federated identities from the Supervisor.
|
|||||||
[`FederationDomain`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-supervisor-config-v1alpha1-federationdomain)
|
[`FederationDomain`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-supervisor-config-v1alpha1-federationdomain)
|
||||||
object to configure the Pinniped Supervisor to issue federated identities.
|
object to configure the Pinniped Supervisor to issue federated identities.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
cat <<EOF | kubectl create --context kind-pinniped-supervisor --namespace pinniped-supervisor -f -
|
cat <<EOF | kubectl create --context kind-pinniped-supervisor --namespace pinniped-supervisor -f -
|
||||||
apiVersion: config.supervisor.pinniped.dev/v1alpha1
|
apiVersion: config.supervisor.pinniped.dev/v1alpha1
|
||||||
kind: FederationDomain
|
kind: FederationDomain
|
||||||
@ -104,7 +107,7 @@ to authenticate federated identities from the Supervisor.
|
|||||||
1. Create a `Secret` with the external OIDC identity provider OAuth 2.0 client credentials named
|
1. Create a `Secret` with the external OIDC identity provider OAuth 2.0 client credentials named
|
||||||
`my-oidc-identity-provider-client` in the pinniped-supervisor namespace.
|
`my-oidc-identity-provider-client` in the pinniped-supervisor namespace.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl create secret generic my-oidc-identity-provider-client \
|
kubectl create secret generic my-oidc-identity-provider-client \
|
||||||
--context kind-pinniped-supervisor \
|
--context kind-pinniped-supervisor \
|
||||||
--namespace pinniped-supervisor \
|
--namespace pinniped-supervisor \
|
||||||
@ -121,7 +124,7 @@ to authenticate federated identities from the Supervisor.
|
|||||||
Replace the `issuer` with your external identity provider's issuer and
|
Replace the `issuer` with your external identity provider's issuer and
|
||||||
adjust any other configuration on the spec.
|
adjust any other configuration on the spec.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
cat <<EOF | kubectl create --context kind-pinniped-supervisor --namespace pinniped-supervisor -f -
|
cat <<EOF | kubectl create --context kind-pinniped-supervisor --namespace pinniped-supervisor -f -
|
||||||
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
|
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
|
||||||
kind: OIDCIdentityProvider
|
kind: OIDCIdentityProvider
|
||||||
@ -140,21 +143,19 @@ to authenticate federated identities from the Supervisor.
|
|||||||
|
|
||||||
1. Deploy the Pinniped Concierge.
|
1. Deploy the Pinniped Concierge.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl apply \
|
kubectl apply \
|
||||||
--context kind-pinniped-concierge \
|
--context kind-pinniped-concierge \
|
||||||
-f https://get.pinniped.dev/latest/install-pinniped-concierge.yaml
|
-f https://get.pinniped.dev/latest/install-pinniped-concierge.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The `install-pinniped-concierge.yaml` file includes the default deployment options.
|
The `install-pinniped-concierge.yaml` file includes the default deployment options.
|
||||||
If you would prefer to customize the available options, please see [deploy/concierge/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/concierge/README.md)
|
If you would prefer to customize the available options, please see the [Concierge installation guide]({{< ref "../howto/install-concierge" >}})
|
||||||
for instructions on how to deploy using `ytt`.
|
for instructions on how to deploy using `ytt`.
|
||||||
|
|
||||||
If you prefer to install a specific version, replace `latest` in the above URL with the version number such as `v0.4.1`.
|
|
||||||
|
|
||||||
1. Generate a random audience value for this cluster.
|
1. Generate a random audience value for this cluster.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
audience="$(openssl rand -hex 8)"
|
audience="$(openssl rand -hex 8)"
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -162,7 +163,7 @@ to authenticate federated identities from the Supervisor.
|
|||||||
[`JWTAuthenticator`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticator)
|
[`JWTAuthenticator`](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#k8s-api-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticator)
|
||||||
object to configure the Pinniped Concierge to authenticate using the Pinniped Supervisor.
|
object to configure the Pinniped Concierge to authenticate using the Pinniped Supervisor.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
cat <<EOF | kubectl create --context kind-pinniped-concierge -f -
|
cat <<EOF | kubectl create --context kind-pinniped-concierge -f -
|
||||||
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
|
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
|
||||||
kind: JWTAuthenticator
|
kind: JWTAuthenticator
|
||||||
@ -175,30 +176,28 @@ to authenticate federated identities from the Supervisor.
|
|||||||
certificateAuthorityData: $(cat /tmp/pinniped-supervisor-ca-bundle-base64-encoded.pem)
|
certificateAuthorityData: $(cat /tmp/pinniped-supervisor-ca-bundle-base64-encoded.pem)
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
1. Download the latest version of the Pinniped CLI binary for your platform
|
|
||||||
from Pinniped's [latest release](https://github.com/vmware-tanzu/pinniped/releases/latest).
|
|
||||||
|
|
||||||
1. Move the Pinniped CLI binary to your preferred filename and directory. Add the executable bit,
|
1. Download the latest version of the Pinniped command-line tool for your platform.
|
||||||
e.g. `chmod +x /usr/local/bin/pinniped`.
|
On macOS or Linux, you can do this using Homebrew:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
brew install vmware-tanzu/pinniped/pinniped-cli
|
||||||
|
```
|
||||||
|
|
||||||
|
On other platforms, see the [command-line installation guide]({{< ref "../howto/install-cli" >}}) for more details.
|
||||||
|
|
||||||
1. Generate a kubeconfig for the current cluster.
|
1. Generate a kubeconfig for the current cluster.
|
||||||
```bash
|
|
||||||
|
```sh
|
||||||
pinniped get kubeconfig \
|
pinniped get kubeconfig \
|
||||||
--kubeconfig-context kind-pinniped-concierge \
|
--kubeconfig-context kind-pinniped-concierge \
|
||||||
> /tmp/pinniped-kubeconfig
|
> /tmp/pinniped-kubeconfig
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are using MacOS, you may get an error dialog that says
|
1. Try using the generated kubeconfig to issue arbitrary `kubectl` commands. The `pinniped` command-line tool
|
||||||
`“pinniped” cannot be opened because the developer cannot be verified`. Cancel this dialog, open System Preferences,
|
opens a browser page that can be used to login to the external OIDC identity provider configured earlier.
|
||||||
click on Security & Privacy, and click the Allow Anyway button next to the Pinniped message.
|
|
||||||
Run the above command again and another dialog will appear saying
|
|
||||||
`macOS cannot verify the developer of “pinniped”. Are you sure you want to open it?`.
|
|
||||||
Click Open to allow the command to proceed.
|
|
||||||
|
|
||||||
1. Try using the generated kubeconfig to issue arbitrary `kubectl` commands. The `pinniped` CLI will
|
```sh
|
||||||
open a browser page that can be used to login to the external OIDC identity provider configured earlier.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped-concierge
|
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped-concierge
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -209,30 +208,28 @@ to authenticate federated identities from the Supervisor.
|
|||||||
to the upstream OIDC identity provider. However, this does prove that you are authenticated and
|
to the upstream OIDC identity provider. However, this does prove that you are authenticated and
|
||||||
acting as the `pinny` user.
|
acting as the `pinny` user.
|
||||||
|
|
||||||
1. As the admin user, create RBAC rules for the test user to give them permissions to perform actions on the cluster.
|
1. As the administrator user, create RBAC rules for the test user to give them permissions to perform actions on the cluster.
|
||||||
For example, grant the test user permission to view all cluster resources.
|
For example, grant the test user permission to view all cluster resources.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl --context kind-pinniped-concierge create clusterrolebinding pinny-can-read --clusterrole view --user pinny
|
kubectl --context kind-pinniped-concierge create clusterrolebinding pinny-can-read --clusterrole view --user pinny
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Use the generated kubeconfig to issue arbitrary `kubectl` commands as the `pinny` user.
|
1. Use the generated kubeconfig to issue arbitrary `kubectl` commands as the `pinny` user.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped-concierge
|
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped-concierge
|
||||||
```
|
```
|
||||||
|
|
||||||
The user has permission to list pods, so the command succeeds this time.
|
The user has permission to list pods, so the command succeeds this time.
|
||||||
Pinniped has provided authentication into the cluster for your `kubectl` command! 🎉
|
Pinniped has provided authentication into the cluster for your `kubectl` command. 🎉
|
||||||
|
|
||||||
1. Carry on issuing as many `kubectl` commands as you'd like as the `pinny` user.
|
1. Carry on issuing as many `kubectl` commands as you'd like as the `pinny` user.
|
||||||
Each invocation will use Pinniped for authentication.
|
Each invocation uses Pinniped for authentication.
|
||||||
You may find it convenient to set the `KUBECONFIG` environment variable rather than passing `--kubeconfig` to each invocation.
|
You may find it convenient to set the `KUBECONFIG` environment variable rather than passing `--kubeconfig` to each invocation.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
export KUBECONFIG=/tmp/pinniped-kubeconfig
|
export KUBECONFIG=/tmp/pinniped-kubeconfig
|
||||||
kubectl get namespaces
|
kubectl get namespaces
|
||||||
kubectl get pods -A
|
kubectl get pods -A
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Profit! 💰
|
|
@ -1,11 +1,15 @@
|
|||||||
---
|
---
|
||||||
title: "Pinniped Concierge Only Demo"
|
title: Learn to use the Pinniped Concierge
|
||||||
|
description: See how the Pinniped Concierge works to provide a uniform login flow across different Kubernetes clusters.
|
||||||
cascade:
|
cascade:
|
||||||
layout: docs
|
layout: docs
|
||||||
|
menu:
|
||||||
|
docs:
|
||||||
|
name: Concierge with Webhook
|
||||||
|
parent: tutorials
|
||||||
|
weight: 100
|
||||||
---
|
---
|
||||||
|
|
||||||
# Trying Pinniped Concierge
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
1. A Kubernetes cluster of a type supported by Pinniped as described in [architecture](/docs/architecture).
|
1. A Kubernetes cluster of a type supported by Pinniped as described in [architecture](/docs/architecture).
|
||||||
@ -20,48 +24,53 @@ cascade:
|
|||||||
by following the directions in [deploy/local-user-authenticator/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/local-user-authenticator/README.md).
|
by following the directions in [deploy/local-user-authenticator/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/local-user-authenticator/README.md).
|
||||||
See below for an example of deploying this on kind.
|
See below for an example of deploying this on kind.
|
||||||
|
|
||||||
1. A kubeconfig where the current context points to the cluster and has admin-like
|
1. A kubeconfig where the current context points to the cluster and has administrator-like
|
||||||
privileges on that cluster.
|
privileges on that cluster.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Installing and trying Pinniped on any cluster will consist of the following general steps. See the next section below
|
Installing and trying the Pinniped Concierge on any cluster consists of the following general steps. See the next section below
|
||||||
for a more specific example of installing onto a local kind cluster, including the exact commands to use for that case.
|
for a more specific example of installing onto a local kind cluster, including the exact commands to use for that case.
|
||||||
|
|
||||||
1. Install the Pinniped Concierge. See [deploy/concierge/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/concierge/README.md).
|
1. [Install the Concierge]({{< ref "../howto/install-concierge" >}}).
|
||||||
1. Download the Pinniped CLI from [Pinniped's github Releases page](https://github.com/vmware-tanzu/pinniped/releases/latest).
|
1. [Install the Pinniped command-line tool]({{< ref "../howto/install-cli" >}}).
|
||||||
1. Generate a kubeconfig using the Pinniped CLI. Run `pinniped get kubeconfig --help` for more information.
|
1. Configure the Concierge with a
|
||||||
1. Run `kubectl` commands using the generated kubeconfig. The Pinniped Concierge will automatically be used for authentication during those commands.
|
[JWT]({{< ref "../howto/configure-concierge-jwt" >}}) or
|
||||||
|
[webhook]({{< ref "../howto/configure-concierge-webhook" >}}) authenticator.
|
||||||
|
1. Generate a kubeconfig using the Pinniped command-line tool (run `pinniped get kubeconfig --help` for more information).
|
||||||
|
1. Run `kubectl` commands using the generated kubeconfig.
|
||||||
|
|
||||||
## Example of Deploying on kind
|
The Pinniped Concierge is automatically be used for authentication during those commands.
|
||||||
|
|
||||||
|
## Example of deploying on kind
|
||||||
|
|
||||||
[kind](https://kind.sigs.k8s.io) is a tool for creating and managing Kubernetes clusters on your local machine
|
[kind](https://kind.sigs.k8s.io) is a tool for creating and managing Kubernetes clusters on your local machine
|
||||||
which uses Docker containers as the cluster's "nodes". This is a convenient way to try out Pinniped on a local
|
which uses Docker containers as the cluster's nodes. This is a convenient way to try out Pinniped on a local
|
||||||
non-production cluster.
|
non-production cluster.
|
||||||
|
|
||||||
The following steps will deploy the latest release of Pinniped on kind using the local-user-authenticator component
|
The following steps deploy the latest release of Pinniped on kind using the local-user-authenticator component
|
||||||
as the authenticator.
|
as the authenticator.
|
||||||
|
|
||||||
1. Install the tools required for the following steps.
|
1. Install the tools required for the following steps.
|
||||||
|
|
||||||
- [Install kind](https://kind.sigs.k8s.io/docs/user/quick-start/), if not already installed. e.g. `brew install kind` on MacOS.
|
- [Install kind](https://kind.sigs.k8s.io/docs/user/quick-start/), if not already installed. For example, `brew install kind` on macOS.
|
||||||
|
|
||||||
- kind depends on Docker. If not already installed, [install Docker](https://docs.docker.com/get-docker/), e.g. `brew cask install docker` on MacOS.
|
- kind depends on Docker. If not already installed, [install Docker](https://docs.docker.com/get-docker/), for example `brew cask install docker` on macOS.
|
||||||
|
|
||||||
- This demo requires `kubectl`, which comes with Docker, or can be [installed separately](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
- This demo requires `kubectl`, which comes with Docker, or can be [installed separately](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
||||||
|
|
||||||
- This demo requires a tool capable of generating a `bcrypt` hash in order to interact with
|
- This demo requires a tool capable of generating a `bcrypt` hash to interact with
|
||||||
the webhook. The example below uses `htpasswd`, which is installed on most macOS systems, and can be
|
the webhook. The example below uses `htpasswd`, which is installed on most macOS systems, and can be
|
||||||
installed on some Linux systems via the `apache2-utils` package (e.g., `apt-get install
|
installed on some Linux systems via the `apache2-utils` package (for example, `apt-get install
|
||||||
apache2-utils`).
|
apache2-utils`).
|
||||||
|
|
||||||
1. Create a new Kubernetes cluster using `kind create cluster`. Optionally provide a cluster name using the `--name` flag.
|
1. Create a new Kubernetes cluster using `kind create cluster`. Optionally provide a cluster name using the `--name` flag.
|
||||||
kind will automatically update your kubeconfig to point to the new cluster as a user with admin-like permissions.
|
kind automatically updates your kubeconfig to point to the new cluster as a user with administrator-like permissions.
|
||||||
|
|
||||||
1. Deploy the local-user-authenticator app. This is a demo authenticator. In production, you would configure
|
1. Deploy the local-user-authenticator app. This is a demo authenticator. In production, you would configure
|
||||||
an authenticator that works with your real identity provider, and therefore would not need to deploy or configure local-user-authenticator.
|
an authenticator that works with your real identity provider, and therefore would not need to deploy or configure local-user-authenticator.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl apply -f https://get.pinniped.dev/latest/install-local-user-authenticator.yaml
|
kubectl apply -f https://get.pinniped.dev/latest/install-local-user-authenticator.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -70,11 +79,11 @@ as the authenticator.
|
|||||||
see [deploy/local-user-authenticator/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/local-user-authenticator/README.md)
|
see [deploy/local-user-authenticator/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/local-user-authenticator/README.md)
|
||||||
for instructions on how to deploy using `ytt`.
|
for instructions on how to deploy using `ytt`.
|
||||||
|
|
||||||
If you prefer to install a specific version, replace `latest` in the above URL with the version number such as `v0.4.1`.
|
If you prefer to install a specific version, replace `latest` in the URL with the version number such as `v0.4.1`.
|
||||||
|
|
||||||
1. Create a test user named `pinny-the-seal` in the local-user-authenticator namespace.
|
1. Create a test user named `pinny-the-seal` in the local-user-authenticator namespace.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl create secret generic pinny-the-seal \
|
kubectl create secret generic pinny-the-seal \
|
||||||
--namespace local-user-authenticator \
|
--namespace local-user-authenticator \
|
||||||
--from-literal=groups=group1,group2 \
|
--from-literal=groups=group1,group2 \
|
||||||
@ -83,7 +92,7 @@ as the authenticator.
|
|||||||
|
|
||||||
1. Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint.
|
1. Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \
|
kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \
|
||||||
-o jsonpath={.data.caCertificate} \
|
-o jsonpath={.data.caCertificate} \
|
||||||
| tee /tmp/local-user-authenticator-ca-base64-encoded
|
| tee /tmp/local-user-authenticator-ca-base64-encoded
|
||||||
@ -91,12 +100,12 @@ as the authenticator.
|
|||||||
|
|
||||||
1. Deploy the Pinniped Concierge.
|
1. Deploy the Pinniped Concierge.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl apply -f https://get.pinniped.dev/latest/install-pinniped-concierge.yaml
|
kubectl apply -f https://get.pinniped.dev/latest/install-pinniped-concierge.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
The `install-pinniped-concierge.yaml` file includes the default deployment options.
|
The `install-pinniped-concierge.yaml` file includes the default deployment options.
|
||||||
If you would prefer to customize the available options, please see [deploy/concierge/README.md](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/concierge/README.md)
|
If you would prefer to customize the available options, please see the [Concierge installation guide]({{< ref "../howto/install-concierge" >}})
|
||||||
for instructions on how to deploy using `ytt`.
|
for instructions on how to deploy using `ytt`.
|
||||||
|
|
||||||
1. Create a `WebhookAuthenticator` object to configure the Pinniped Concierge to authenticate using local-user-authenticator.
|
1. Create a `WebhookAuthenticator` object to configure the Pinniped Concierge to authenticate using local-user-authenticator.
|
||||||
@ -114,61 +123,63 @@ as the authenticator.
|
|||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Download the latest version of the Pinniped CLI binary for your platform
|
1. Download the latest version of the Pinniped command-line tool for your platform.
|
||||||
from Pinniped's [latest release](https://github.com/vmware-tanzu/pinniped/releases/latest).
|
On macOS or Linux, you can do this using Homebrew:
|
||||||
|
|
||||||
1. Move the Pinniped CLI binary to your preferred filename and directory. Add the executable bit,
|
```sh
|
||||||
e.g. `chmod +x /usr/local/bin/pinniped`.
|
brew install vmware-tanzu/pinniped/pinniped-cli
|
||||||
|
|
||||||
1. Generate a kubeconfig for the current cluster. Use `--static-token` to include a token which should
|
|
||||||
allow you to authenticate as the user that you created above.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pinniped get kubeconfig --static-token "pinny-the-seal:password123" --concierge-authenticator-type webhook --concierge-authenticator-name local-user-authenticator > /tmp/pinniped-kubeconfig
|
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are using MacOS, you may get an error dialog that says
|
On other platforms, see the [command-line installation guide]({{< ref "../howto/install-cli" >}}) for more details.
|
||||||
`“pinniped” cannot be opened because the developer cannot be verified`. Cancel this dialog, open System Preferences,
|
|
||||||
click on Security & Privacy, and click the Allow Anyway button next to the Pinniped message.
|
1. Generate a kubeconfig for the current cluster. Use `--static-token` to include a token which should
|
||||||
Run the above command again and another dialog will appear saying
|
allow you to authenticate as the user that you created previously.
|
||||||
`macOS cannot verify the developer of “pinniped”. Are you sure you want to open it?`.
|
|
||||||
Click Open to allow the command to proceed.
|
```sh
|
||||||
|
pinniped get kubeconfig \
|
||||||
|
--static-token "pinny-the-seal:password123" \
|
||||||
|
--concierge-authenticator-type webhook \
|
||||||
|
--concierge-authenticator-name local-user-authenticator \
|
||||||
|
> /tmp/pinniped-kubeconfig
|
||||||
|
```
|
||||||
|
|
||||||
1. Try using the generated kubeconfig to issue arbitrary `kubectl` commands as
|
1. Try using the generated kubeconfig to issue arbitrary `kubectl` commands as
|
||||||
the `pinny-the-seal` user.
|
the `pinny-the-seal` user.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped-concierge
|
kubectl --kubeconfig /tmp/pinniped-kubeconfig \
|
||||||
|
get pods -n pinniped-concierge
|
||||||
```
|
```
|
||||||
|
|
||||||
Because this user has no RBAC permissions on this cluster, the previous command
|
Because this user has no RBAC permissions on this cluster, the previous command
|
||||||
results in the error `Error from server (Forbidden): pods is forbidden: User "pinny-the-seal" cannot list resource "pods" in API group "" in the namespace "pinniped"`.
|
results in the error `Error from server (Forbidden): pods is forbidden: User "pinny-the-seal" cannot list resource "pods" in API group "" in the namespace "pinniped-concierge"`.
|
||||||
However, this does prove that you are authenticated and acting as the `pinny-the-seal` user.
|
However, this does prove that you are authenticated and acting as the `pinny-the-seal` user.
|
||||||
|
|
||||||
1. As the admin user, create RBAC rules for the test user to give them permissions to perform actions on the cluster.
|
1. As the administrator user, create RBAC rules for the test user to give them permissions to perform actions on the cluster.
|
||||||
For example, grant the test user permission to view all cluster resources.
|
For example, grant the test user permission to view all cluster resources.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl create clusterrolebinding pinny-can-read --clusterrole view --user pinny-the-seal
|
kubectl create clusterrolebinding pinny-can-read \
|
||||||
|
--clusterrole view \
|
||||||
|
--user pinny-the-seal
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Use the generated kubeconfig to issue arbitrary `kubectl` commands as the `pinny-the-seal` user.
|
1. Use the generated kubeconfig to issue arbitrary `kubectl` commands as the `pinny-the-seal` user.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped-concierge
|
kubectl --kubeconfig /tmp/pinniped-kubeconfig \
|
||||||
|
get pods -n pinniped-concierge
|
||||||
```
|
```
|
||||||
|
|
||||||
The user has permission to list pods, so the command succeeds this time.
|
The user has permission to list pods, so the command succeeds this time.
|
||||||
Pinniped has provided authentication into the cluster for your `kubectl` command! 🎉
|
Pinniped has provided authentication into the cluster for your `kubectl` command. 🎉
|
||||||
|
|
||||||
1. Carry on issuing as many `kubectl` commands as you'd like as the `pinny-the-seal` user.
|
1. Carry on issuing as many `kubectl` commands as you'd like as the `pinny-the-seal` user.
|
||||||
Each invocation will use Pinniped for authentication.
|
Each invocation uses Pinniped for authentication.
|
||||||
You may find it convenient to set the `KUBECONFIG` environment variable rather than passing `--kubeconfig` to each invocation.
|
You may find it convenient to set the `KUBECONFIG` environment variable rather than passing `--kubeconfig` to each invocation.
|
||||||
|
|
||||||
```bash
|
```sh
|
||||||
export KUBECONFIG=/tmp/pinniped-kubeconfig
|
export KUBECONFIG=/tmp/pinniped-kubeconfig
|
||||||
kubectl get namespaces
|
kubectl get namespaces
|
||||||
kubectl get pods -A
|
kubectl get pods -A
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Profit! 💰
|
|
@ -5,7 +5,7 @@ date: 2020-11-12
|
|||||||
author: Pablo Schuhmacher
|
author: Pablo Schuhmacher
|
||||||
image: /img/logo.svg
|
image: /img/logo.svg
|
||||||
excerpt: "Pinniped intends to bring that dream state — log in once and you’re done — to reality."
|
excerpt: "Pinniped intends to bring that dream state — log in once and you’re done — to reality."
|
||||||
tags: ['Pablo Schuhmacher']
|
tags: ['Pablo Schuhmacher', 'release']
|
||||||
---
|
---
|
||||||
|
|
||||||
Kubernetes, containers, microservices: They’ve all turned conventional application development wisdom inside out. But for all the wonders introduced and new technologies released, there are still a few things that remain difficult, cumbersome, or just really really frustrating when it comes to Kubernetes. We have set out to make one of those things easier and more understandable: authentication.
|
Kubernetes, containers, microservices: They’ve all turned conventional application development wisdom inside out. But for all the wonders introduced and new technologies released, there are still a few things that remain difficult, cumbersome, or just really really frustrating when it comes to Kubernetes. We have set out to make one of those things easier and more understandable: authentication.
|
||||||
|
@ -87,7 +87,7 @@ The default behavior of Pinniped remains unchanged, and we made sure to implemen
|
|||||||
|
|
||||||
### Advantages and Disadvantages
|
### Advantages and Disadvantages
|
||||||
|
|
||||||
With v0.5.0, each instance of Pinniped to be upgraded and operated 100% independently, with no coordination or shared state needed.
|
With v0.5.0, each instance of Pinniped can be upgraded and operated 100% independently, with no coordination or shared state needed.
|
||||||
One remaining constraint is that each instance should be deployed into its own namespace.
|
One remaining constraint is that each instance should be deployed into its own namespace.
|
||||||
This ensures that any other standard Kubernetes objects such as Secrets and ConfigMaps referenced by the configuration do not overlap.
|
This ensures that any other standard Kubernetes objects such as Secrets and ConfigMaps referenced by the configuration do not overlap.
|
||||||
|
|
||||||
|
@ -28,3 +28,16 @@ HUGO_VERSION = "0.78.0"
|
|||||||
|
|
||||||
[context.next.environment]
|
[context.next.environment]
|
||||||
HUGO_ENABLEGITINFO = "true"
|
HUGO_ENABLEGITINFO = "true"
|
||||||
|
|
||||||
|
[[headers]]
|
||||||
|
for = "/fonts/*"
|
||||||
|
[headers.values]
|
||||||
|
Access-Control-Allow-Origin = "*"
|
||||||
|
|
||||||
|
[[headers]]
|
||||||
|
for = "/*"
|
||||||
|
[headers.values]
|
||||||
|
Content-Security-Policy = "default-src 'self'; img-src *"
|
||||||
|
X-Content-Type-Options = "nosniff"
|
||||||
|
X-Frame-Options = "DENY"
|
||||||
|
X-XSS-Protection = "1; mode=block"
|
@ -1,3 +1,8 @@
|
|||||||
|
[[redirects]]
|
||||||
|
from = "/"
|
||||||
|
to = "https://pinniped.dev"
|
||||||
|
status = 302
|
||||||
|
force = true
|
||||||
|
|
||||||
[[redirects]]
|
[[redirects]]
|
||||||
from = "/latest/*"
|
from = "/latest/*"
|
||||||
|
File diff suppressed because one or more lines are too long
@ -97,6 +97,13 @@ button {
|
|||||||
&.tertiary {
|
&.tertiary {
|
||||||
border: 1px solid $blue;
|
border: 1px solid $blue;
|
||||||
}
|
}
|
||||||
|
img.button-icon {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-bottom: -8px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.buttons {
|
.buttons {
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
|
@ -273,9 +273,8 @@
|
|||||||
list-style-type: unset;
|
list-style-type: unset;
|
||||||
display: list-item;
|
display: list-item;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
color: $darkgrey;
|
color: $darkgrey;
|
||||||
line-height: 1.6em;
|
|
||||||
list-style-image: url(/img/arrow.svg);
|
list-style-image: url(/img/arrow.svg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -408,9 +407,19 @@
|
|||||||
.side-nav {
|
.side-nav {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
float: left;
|
float: left;
|
||||||
|
@include breakpoint(small-medium) {
|
||||||
|
width: 100%;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
padding-left: 0px;
|
padding-left: 0px;
|
||||||
margin-bottom: 35px;
|
margin-bottom: 35px;
|
||||||
|
ul {
|
||||||
|
padding-left: 15px;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
li {
|
li {
|
||||||
display: list-item;
|
display: list-item;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
@ -431,8 +440,12 @@
|
|||||||
.docs-content {
|
.docs-content {
|
||||||
width: 75%;
|
width: 75%;
|
||||||
float: right;
|
float: right;
|
||||||
|
@include breakpoint(small-medium) {
|
||||||
|
width: 100%;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
a {
|
a {
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
@ -486,10 +499,37 @@
|
|||||||
border: 15px solid #EFEFEF;
|
border: 15px solid #EFEFEF;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
strong {
|
||||||
|
font-family: $metropolis-medium;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.danger {
|
||||||
|
.danger-icon {
|
||||||
|
float: left;
|
||||||
|
padding: 40px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
padding: 10px;
|
||||||
|
font-family: $metropolis-light-italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
white-space: nowrap;
|
||||||
|
a {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
td {
|
||||||
|
padding: 10px 30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,7 +19,6 @@
|
|||||||
<body>
|
<body>
|
||||||
{{ partial "header" . }}
|
{{ partial "header" . }}
|
||||||
{{ block "main" . }}{{ end }}
|
{{ block "main" . }}{{ end }}
|
||||||
{{ partial "getting-started" . }}
|
|
||||||
{{ partial "footer" . }}
|
{{ partial "footer" . }}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -7,8 +7,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="wrapper docs clearfix">
|
<div class="wrapper docs clearfix">
|
||||||
{{ partial "docs-sidebar.html" . }}
|
{{ partial "docs-sidebar.html" . }}
|
||||||
|
|
||||||
<div class="docs-content">
|
<div class="docs-content">
|
||||||
|
{{- with .Title -}}
|
||||||
|
<h1>{{.}}</h1>
|
||||||
|
{{- end -}}
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<main>
|
<main>
|
||||||
<div class="hero subpage">
|
<div class="hero subpage">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<h2>Pinniped Blog</h2>
|
<h2>Pinniped blog</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper blog landing">
|
<div class="wrapper blog landing">
|
||||||
@ -14,4 +14,5 @@
|
|||||||
{{ partial "pagination.html" . }}
|
{{ partial "pagination.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
{{ partial "getting-started" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<main>
|
<main>
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
</main>
|
</main>
|
||||||
|
{{ partial "getting-started" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<article>
|
<article>
|
||||||
<div class="hero subpage">
|
<div class="hero subpage">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<h1>Pinniped Blog</h1>
|
<h1>Pinniped blog</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wrapper blog">
|
<div class="wrapper blog">
|
||||||
@ -15,18 +15,19 @@
|
|||||||
<p class="date">{{ dateFormat "Jan 2, 2006" .Date }}</p>
|
<p class="date">{{ dateFormat "Jan 2, 2006" .Date }}</p>
|
||||||
{{ .Content }}
|
{{ .Content }}
|
||||||
</div>
|
</div>
|
||||||
<h2>Related Content</h2>
|
{{ $related := (where (.Site.RegularPages.Related .) "Type" "posts") | first 3 }}
|
||||||
<div class="grid three">
|
{{ with $related }}
|
||||||
{{ $related := (where (.Site.RegularPages.Related .) "Type" "posts") | first 3 }}
|
<h2>Related content</h2>
|
||||||
{{ with $related }}
|
<div class="grid three">
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
{{ partial "blog-post-card.html" . }}
|
{{ partial "blog-post-card.html" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
</div>
|
||||||
</div>
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
|
{{ partial "getting-started" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,4 +13,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
{{ partial "getting-started" . }}
|
||||||
{{ end }}
|
{{ end }}
|
@ -6,7 +6,7 @@
|
|||||||
<div class="wrapper grid two">
|
<div class="wrapper grid two">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<p class="strong">Introduction to Pinniped</p>
|
<p class="strong">Introduction to Pinniped</p>
|
||||||
<p><a href="https://pinniped.dev/docs/demo/">Learn how Pinniped</a> provides identity services to Kubernetes</p>
|
<p><a href="https://pinniped.dev/docs/">Learn how Pinniped</a> provides identity services to Kubernetes</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<p class="strong">How do you use Pinniped?</p>
|
<p class="strong">How do you use Pinniped?</p>
|
||||||
@ -17,4 +17,5 @@
|
|||||||
{{ partial "use-cases.html" . }}
|
{{ partial "use-cases.html" . }}
|
||||||
{{ partial "team.html" . }}
|
{{ partial "team.html" . }}
|
||||||
</main>
|
</main>
|
||||||
|
{{ partial "getting-started" . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
|
<h3><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
|
||||||
|
<time>{{ .Date.Format "January 2, 2006" }}</time>
|
||||||
<p>{{ .Params.Excerpt }}</p>
|
<p>{{ .Params.Excerpt }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,8 +1,17 @@
|
|||||||
<div class="side-nav">
|
<div class="side-nav">
|
||||||
<ul>
|
<ul>
|
||||||
{{ $currentPage := . }}
|
{{- $currentPage := . }}
|
||||||
{{ range .Site.Menus.docs }}
|
{{- range .Site.Menus.docs }}
|
||||||
<li><a href="{{ .URL }}" {{ if (eq $currentPage.RelPermalink .URL) }}class="active"{{ end }}>{{ .Name }}</a></li>
|
<li>
|
||||||
{{ end }}
|
<a href="{{ .URL }}" class="{{ cond ($currentPage.IsMenuCurrent "docs" .) "active" "" }}">{{ .Name }}</a>
|
||||||
|
{{- if .HasChildren }}
|
||||||
|
<ul class="sub-menu">
|
||||||
|
{{- range .Children }}
|
||||||
|
<li><a href="{{ .URL }}"{{ if $currentPage.IsMenuCurrent "docs" . }} class="active"{{ end }} >{{ .Name }}</a></li>
|
||||||
|
{{- end }}
|
||||||
|
</ul>
|
||||||
|
{{- end }}
|
||||||
|
</li>
|
||||||
|
{{- end }}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
@ -2,10 +2,10 @@
|
|||||||
<div class="wrapper clearfix">
|
<div class="wrapper clearfix">
|
||||||
<div class="left-side">
|
<div class="left-side">
|
||||||
<h2>Getting started</h2>
|
<h2>Getting started</h2>
|
||||||
<p>To help you get started, see the documentation.</p>
|
<p>Learn how Pinniped works, see how to use it on your clusters, and dive into internals of Pinniped's APIs and architecture.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-side">
|
<div class="right-side">
|
||||||
<a href="/docs/" class="button">Get started</a>
|
<a href="/docs/" class="button">Read the docs</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -7,7 +7,7 @@
|
|||||||
<li><a href="/blog/" {{ if or (eq .Page.Section "posts") (eq .Page.Section "tags") }}class="active"{{ end }}>Blog</a></li>
|
<li><a href="/blog/" {{ if or (eq .Page.Section "posts") (eq .Page.Section "tags") }}class="active"{{ end }}>Blog</a></li>
|
||||||
<li><a href="/docs/" {{ if (eq .Page.Section "docs") }}class="active"{{ end }}>Docs</a></li>
|
<li><a href="/docs/" {{ if (eq .Page.Section "docs") }}class="active"{{ end }}>Docs</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<button type="button" class="mobile" onclick="mobileNavToggle()">
|
<button type="button" class="mobile" id="mobile-menu-button">
|
||||||
<img class="collapsed-icon" src="/img/hamburger.svg" alt="Mobile nav icon">
|
<img class="collapsed-icon" src="/img/hamburger.svg" alt="Mobile nav icon">
|
||||||
<img class="expanded-icon" src="/img/close.svg" alt="Mobile nav icon">
|
<img class="expanded-icon" src="/img/close.svg" alt="Mobile nav icon">
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<div class="hero homepage">
|
<div class="hero homepage">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="text-block">
|
<div class="text-block">
|
||||||
<h2>Pinniped - Simplify user authentication for any Kubernetes cluster: log in once and you’re done.</h2>
|
<h2>Batteries-included for Kubernetes authentication</h2>
|
||||||
<p>Pinniped delivers a consistent Kubernetes user authentication experience while prioritizing security, interoperability and low-effort management at scale.</p>
|
<p>Pinniped is the easy, secure way to log in to your Kubernetes clusters.</p>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<a class="button" href="https://github.com/vmware-tanzu/pinniped/blob/main/README.md">Get Started with Pinniped</a>
|
<a class="button" href="/docs/">Get Started with Pinniped</a>
|
||||||
<a class="button secondary" href="https://github.com/vmware-tanzu/pinniped/releases">Download Latest Release</a>
|
<a class="button secondary" href="https://github.com/vmware-tanzu/pinniped/releases">Download Latest Release</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,17 +4,17 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<img src="/img/simple.svg" />
|
<img src="/img/simple.svg" />
|
||||||
<h3>Simple</h3>
|
<h3>Simple</h3>
|
||||||
<p>Install and integrate with nearly any cluster in one step</p>
|
<p>Easily install on almost any Kubernetes cluster</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<img src="/img/frictionless.svg" />
|
<img src="/img/frictionless.svg" />
|
||||||
<h3>Frictionless</h3>
|
<h3>Frictionless</h3>
|
||||||
<p>Log in once to safely access many clusters</p>
|
<p>Use native command-line tools like kubectl</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<img src="/img/seamless.svg" />
|
<img src="/img/seamless.svg" />
|
||||||
<h3>Seamless</h3>
|
<h3>Seamless</h3>
|
||||||
<p>Leverage first class integration with Kubernetes and kubectl CLI</p>
|
<p>Log in once to safely access all your clusters</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,13 +2,6 @@
|
|||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<h2>The Pinniped Project Team:</h2>
|
<h2>The Pinniped Project Team:</h2>
|
||||||
<div class="grid three">
|
<div class="grid three">
|
||||||
<div class="bio">
|
|
||||||
<div class="image"><img src="/img/matt-moyer.png" /></div>
|
|
||||||
<div class="info">
|
|
||||||
<p class="name">Matt Moyer</p>
|
|
||||||
<p class="position">Engineer</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="bio">
|
<div class="bio">
|
||||||
<div class="image"><img src="/img/andrew-keesler.png" /></div>
|
<div class="image"><img src="/img/andrew-keesler.png" /></div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
@ -17,9 +10,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bio">
|
<div class="bio">
|
||||||
<div class="image"><img src="/img/ryan-richard.png" /></div>
|
<div class="image"><img src="/img/margo-crawford.png" /></div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<p class="name">Ryan Richard</p>
|
<p class="name">Margo Crawford</p>
|
||||||
|
<p class="position">Engineer</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bio">
|
||||||
|
<div class="image"><img src="/img/matt-moyer.png" /></div>
|
||||||
|
<div class="info">
|
||||||
|
<p class="name">Matt Moyer</p>
|
||||||
<p class="position">Engineer</p>
|
<p class="position">Engineer</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -30,6 +30,13 @@
|
|||||||
<p class="position">Engineer</p>
|
<p class="position">Engineer</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bio">
|
||||||
|
<div class="image"><img src="/img/nanci-lancaster.png" /></div>
|
||||||
|
<div class="info">
|
||||||
|
<p class="name">Nanci Lancaster</p>
|
||||||
|
<p class="position">Community Manager</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="bio">
|
<div class="bio">
|
||||||
<div class="image"><img src="/img/pablo-schuhmacher.png" /></div>
|
<div class="image"><img src="/img/pablo-schuhmacher.png" /></div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
@ -37,8 +44,15 @@
|
|||||||
<p class="position">Product Manager</p>
|
<p class="position">Product Manager</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bio">
|
||||||
|
<div class="image"><img src="/img/ryan-richard.png" /></div>
|
||||||
|
<div class="info">
|
||||||
|
<p class="name">Ryan Richard</p>
|
||||||
|
<p class="position">Engineer</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3>Contributing:</h3>
|
<h3>Contributing:</h3>
|
||||||
<p>The Pinniped project team welcomes contributions from the community, please see our <a href="https://github.com/vmware-tanzu/pinniped/blob/main/CONTRIBUTING.md">contributor’s guide</a> for more information.</p>
|
<p>The Pinniped project team welcomes contributions from the community, please see the <a href="https://github.com/vmware-tanzu/pinniped/blob/main/CONTRIBUTING.md">contributor’s guide</a> for more information.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,18 +1,18 @@
|
|||||||
<div class="wrapper use-cases">
|
<div class="wrapper use-cases">
|
||||||
<h2>Use Cases</h2>
|
<h2>Use cases</h2>
|
||||||
<div class="grid two">
|
<div class="grid two">
|
||||||
<div class="col image">
|
<div class="col image">
|
||||||
<img src="/img/administration.svg" />
|
<img src="/img/administration.svg" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col text">
|
<div class="col text">
|
||||||
<p class="strong">Cluster Administration</p>
|
<p class="strong">Cluster administration</p>
|
||||||
<p>Easily plug in external IDPs into Kubernetes clusters while offering a simple install and configuration experience. Leverage first class integration with Kubernetes and kubectl CLI.</p>
|
<p>Easily plug in external identity providers into Kubernetes clusters while offering a simple install and configuration experience. Leverage first class integration with Kubernetes and kubectl command-line.</p>
|
||||||
<!-- <p><a href="#" class="button tertiary">Read More</a></p> -->
|
<!-- <p><a href="#" class="button tertiary">Read More</a></p> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid two image-right">
|
<div class="grid two image-right">
|
||||||
<div class="col text">
|
<div class="col text">
|
||||||
<p class="strong">Seamless Authentication</p>
|
<p class="strong">Seamless authentication</p>
|
||||||
<p>Give users a consistent, unified login experience across all your clusters, including on-premises and managed cloud environments.</p>
|
<p>Give users a consistent, unified login experience across all your clusters, including on-premises and managed cloud environments.</p>
|
||||||
<!-- <p><a href="#" class="button tertiary">Read More</a></p> -->
|
<!-- <p><a href="#" class="button tertiary">Read More</a></p> -->
|
||||||
</div>
|
</div>
|
||||||
@ -25,8 +25,8 @@
|
|||||||
<img src="/img/security.svg" />
|
<img src="/img/security.svg" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col text">
|
<div class="col text">
|
||||||
<p class="strong">Security for Enterprises & Teams Alike</p>
|
<p class="strong">Security for enterprises & teams alike</p>
|
||||||
<p>Securely integrate with an enterprise IDP using standard protocols or use secure, externally-managed identities instead of relying on simple, shared credentials.</p>
|
<p>Securely integrate with an enterprise IDP using standard protocols or use secure, externally managed identities instead of relying on simple, shared credentials.</p>
|
||||||
<!-- <p><a href="#" class="button tertiary">Read More</a></p> -->
|
<!-- <p><a href="#" class="button tertiary">Read More</a></p> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
1
site/themes/pinniped/layouts/shortcodes/buttonicon.html
Normal file
1
site/themes/pinniped/layouts/shortcodes/buttonicon.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<img class="button-icon" src="/img/{{.Get 0 }}" />
|
2
site/themes/pinniped/layouts/shortcodes/buttonlink.html
Normal file
2
site/themes/pinniped/layouts/shortcodes/buttonlink.html
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{{- $href := .Get "href" -}}
|
||||||
|
<div class="button"><a href="{{ $href }}" class="button secondary">{{.Inner}}</a></div>
|
4
site/themes/pinniped/layouts/shortcodes/dangernote.html
Normal file
4
site/themes/pinniped/layouts/shortcodes/dangernote.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<div class="danger">
|
||||||
|
<img class="danger-icon" src="/img/alert-circle-outline.svg" />
|
||||||
|
<p>{{ .Inner | markdownify }}</p>
|
||||||
|
</div>
|
15
site/themes/pinniped/layouts/shortcodes/docsmenu.html
Normal file
15
site/themes/pinniped/layouts/shortcodes/docsmenu.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{{- $subsection := .Get 0 -}}
|
||||||
|
<ul>
|
||||||
|
{{- range .Site.Menus.docs -}}
|
||||||
|
{{- range .Children }}
|
||||||
|
{{- if eq $subsection .Parent -}}
|
||||||
|
<li>
|
||||||
|
<a href="{{ .URL }}">{{- .Page.Title -}}</a>
|
||||||
|
{{- with .Page.Description }}
|
||||||
|
<p>{{ . | markdownify }}</p>
|
||||||
|
{{- end -}}
|
||||||
|
</li>
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end }}
|
||||||
|
</ul>
|
1
site/themes/pinniped/static/img/alert-circle-outline.svg
Normal file
1
site/themes/pinniped/static/img/alert-circle-outline.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M11,15H13V17H11V15M11,7H13V13H11V7M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20Z" /></svg>
|
After Width: | Height: | Size: 474 B |
BIN
site/themes/pinniped/static/img/download.png
Normal file
BIN
site/themes/pinniped/static/img/download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 354 B |
BIN
site/themes/pinniped/static/img/margo-crawford.png
Normal file
BIN
site/themes/pinniped/static/img/margo-crawford.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
BIN
site/themes/pinniped/static/img/nanci-lancaster.png
Normal file
BIN
site/themes/pinniped/static/img/nanci-lancaster.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
@ -3,4 +3,7 @@
|
|||||||
function mobileNavToggle() {
|
function mobileNavToggle() {
|
||||||
var menu = document.getElementById("mobile-menu").parentElement;
|
var menu = document.getElementById("mobile-menu").parentElement;
|
||||||
menu.classList.toggle('mobile-menu-visible');
|
menu.classList.toggle('mobile-menu-visible');
|
||||||
}
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
document.getElementById('mobile-menu-button').addEventListener('click', mobileNavToggle);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user