Authentication and Authorization
This outline describes authentication and authorization mechanisms within the client-go
library for interacting with Kubernetes clusters. client-go
provides support for various methods, including:
In-Cluster Authentication
- Service Account Tokens: This method leverages the
ServiceAccount
token mounted in pods at/var/run/secrets/kubernetes.io/serviceaccount
.client-go
automatically uses this token whenrest.InClusterConfig()
is employed. - Example: The
in-cluster-client-configuration
example showcases authentication within a Kubernetes cluster.
Out-of-Cluster Authentication
- Kubeconfig File: Authentication from outside a cluster is achieved using a
kubeconfig
file, which contains context information for connecting to the Kubernetes cluster. This file is also used by thekubectl
command-line tool for authentication. - Example: The
out-of-cluster-client-configuration
example illustrates the use of akubeconfig
file for authentication from outside the cluster.
Authentication Plugins
client-go
provides plugins that can be used for obtaining credentials from external sources. These plugins are not loaded by default and need to be imported explicitly.
- Loading All Plugins:
import _ "k8s.io/client-go/plugin/pkg/client/auth"
- Loading Specific Plugins:
import _ "k8s.io/client-go/plugin/pkg/client/auth/azure" import _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" import _ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
Authorization
client-go
supports various authorization mechanisms, including:
Impersonation: Allows a client to perform operations as a different user.
// ImpersonationConfig has all the available impersonation options type ImpersonationConfig struct { // UserName is the username to impersonate on each request. UserName string // UID is a unique value that identifies the user. UID string // Groups are the groups to impersonate on each request. Groups []string // Extra is a free-form field which can be used to link some authentication information // to authorization information. This field allows you to impersonate it. Extra map[string][]string }
Subject Access Reviews: Allow a client to check if a user has access to a specific resource.
/* type AuthorizationV1Interface interface { RESTClient() rest.Interface LocalSubjectAccessReviewsGetter SelfSubjectAccessReviewsGetter SelfSubjectRulesReviewsGetter SubjectAccessReviewsGetter }
Authentication Provider Interface
The AuthProvider
interface defines how plugins interact with the client-go
transport layer:
/*
type AuthProvider interface {
// WrapTransport allows the plugin to create a modified RoundTripper that
// attaches authorization headers (or other info) to requests.
WrapTransport(http.RoundTripper) http.RoundTripper
// Login allows the plugin to initialize its configuration. It must not
// require direct user interaction.
Login() error
}
Exec Plugin Authentication
The Exec
plugin provides a mechanism for obtaining credentials from an external process or service:
- Credential Refreshing: The plugin automatically refreshes credentials if they expire.
func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { // If a user has already set credentials, use that. This makes commands like // "kubectl get --token (token) pods" work. if req.Header.Get("Authorization") != "" { return r.base.RoundTrip(req) } creds, err := r.a.getCreds() if err != nil { return nil, fmt.Errorf("getting credentials: %v", err) } if creds.token != "" { req.Header.Set("Authorization", "Bearer "+creds.token) } res, err := r.base.RoundTrip(req) if err != nil { return nil, err } if res.StatusCode == http.StatusUnauthorized { if err := r.a.maybeRefreshCreds(creds); err != nil { klog.Errorf("refreshing credentials: %v", err) } } return res, nil } type roundTripper struct { a *Authenticator base http.RoundTripper } func (c *cache) get(s string) (*Authenticator, bool) { c.mu.Lock() defer c.mu.Unlock() a, ok := c.m[s] return a, ok }
- Credential Storage: Credentials are stored in a secure manner within the plugin.
// ExecCredentialStatus holds credentials for the transport to use. // // Token and ClientKeyData are sensitive fields. This data should only be // transmitted in-memory between client and exec plugin process. Exec plugin // itself should at least be protected via file permissions. type ExecCredentialStatus struct { // ExpirationTimestamp indicates a time when the provided credentials expire. // +optional ExpirationTimestamp *metav1.Time `json:"expirationTimestamp,omitempty"` // Token is a bearer token used by the client for request authentication. Token string `json:"token,omitempty" datapolicy:"token"` // PEM-encoded client TLS certificates (including intermediates, if any). ClientCertificateData string `json:"clientCertificateData,omitempty"` // PEM-encoded private key for the above certificate. ClientKeyData string `json:"clientKeyData,omitempty" datapolicy:"security-key"` }
- Prompting for Credentials: The plugin can prompt the user for credentials if they are not available.
// LoadAuth parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist. func (a *PromptingAuthLoader) LoadAuth(path string) (*clientauth.Info, error) { // Prompt for user/pass and write a file if none exists. if _, err := os.Stat(path); os.IsNotExist(err) { authPtr, err := a.Prompt() if err != nil { return nil, err } auth := *authPtr data, err := json.Marshal(auth) if err != nil { return &auth, err } err = os.WriteFile(path, data, 0600) return &auth, err } authPtr, err := clientauth.LoadFromFile(path) if err != nil { return nil, err } return authPtr, nil }
- Transport Layer Integration: The plugin modifies the
RoundTripper
to attach authentication information to requests.// maskValue masks credential content from authorization headers // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization func maskValue(key string, value string) string { if !strings.EqualFold(key, "Authorization") { return value } if len(value) == 0 { return "" } var authType string if i := strings.Index(value, " "); i > 0 { authType = value[0:i] } else { authType = value } if !knownAuthTypes[strings.ToLower(authType)] { return "" } if len(value) > len(authType)+1 { value = authType + " " } else { value = authType } return value }
Example: Managing Deployments
The create-update-delete-deployment
example demonstrates managing Kubernetes Deployment
resources.
This example covers fundamental operations like creating, listing, updating, and deleting resources via the Kubernetes API.
Other Resources
The client-go
library offers various resources and functionalities, including:
kubernetes
package: Provides the clientset for accessing the Kubernetes API.discovery
package: Enables discovery of APIs supported by a Kubernetes API server.dynamic
package: Offers a dynamic client for performing generic operations on arbitrary Kubernetes API objects.plugin/pkg/client/auth
packages: Contain optional authentication plugins for obtaining credentials from external sources.transport
package: Used to set up authentication and initiate connections.tools/cache
package: Useful for developing controllers.
Additional Examples
The client-go
repository includes various examples:
fake-client
: Using a fake client in tests.work-queues
: Creating a hotloop-free controller using a rate-limited work queue and the informer framework.custom-resource-definition
: Registering a custom resource type with the API, performing CRUD operations on this custom type, and writing a controller based on custom resource changes.leader-election
: Implementing HA controllers using the leader election package.
References
Top-Level Directory Explanations
applyconfigurations/ - This directory contains examples and tests for applying Kubernetes configurations using the client-go library.
discovery/ - This directory contains code related to service discovery in Kubernetes.
informers/ - This directory contains code for caching Kubernetes resources using informers.
kubernetes/ - This directory contains the main package for the client-go library, which provides types and functions for interacting with the Kubernetes API.
listers/ - This directory contains interfaces and implementations for listing Kubernetes resources.
openapi/ - This directory contains OpenAPI definitions for the Kubernetes API.
pkg/ - This directory contains compiled Go packages for the client-go library.
plugin/ - This directory contains code for loading plugins for the client-go library.
rest/ - This directory contains code for working with the REST API in the client-go library.
tools/ - This directory contains various tools for working with the client-go library.
util/ - This directory contains utility functions for the client-go library.