k8s.io/test-infra@v0.0.0-20240520184403-27c6b4c223d8/gencred/README.md (about) 1 # Gencred 2 3 ## Description 4 5 `gencred` is a simple tool used to generate cluster auth credentials (w/ [**cluster-admin**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) permissions) for authenticating to a Kubernetes cluster. 6 > **NOTE:** since `gencred` creates credentials with `cluster-admin` level access, the kube context used **must** also be bound to the `cluster-admin` role. 7 8 ## Usage 9 10 ### Script 11 12 ```console 13 $ go run k8s.io/test-infra/gencred <options> 14 ``` 15 16 The following is a list of supported options for the `gencred` CLI. All options are *optional*. 17 18 ```console 19 -c, --certificate Authorize with a client certificate and key. 20 --context string The name of the kubeconfig context to use. 21 -n, --name string Context name for the kubeconfig entry. (default "build") 22 -o, --output string Output path for generated kubeconfig file. (default "/dev/stdout") 23 --overwrite Overwrite (rather than merge) output file if exists. 24 -s, --serviceaccount Authorize with a service account. (default true) 25 -d, --duration How many days the cred is valid. (default 7) 26 ``` 27 28 Create a kubeconfig entry with context name `mycluster` using `serviceaccount` authorization and output to a file `config.yaml`. 29 > `serviceaccount` authorization is the *default* if neither `-s, --serviceaccount` nor `-c, --certificate` is specified. 30 31 ```console 32 $ gencred --context my-current-context --name mycluster --output ./config.yaml --serviceaccount 33 ``` 34 35 The kubeconfig contents will be `output` to `./config.yaml`: 36 37 ```yaml 38 apiVersion: v1 39 clusters: 40 - cluster: 41 certificate-authority-data: fake-ca-data 42 server: https://1.2.3.4 43 name: mycluster 44 contexts: 45 - context: 46 cluster: mycluster 47 user: mycluster 48 name: mycluster 49 current-context: mycluster 50 kind: Config 51 preferences: {} 52 users: 53 - name: mycluster 54 user: 55 token: fake-token 56 ``` 57 58 Create a kubeconfig entry with **default** context name `build` using `certificate` authorization and output to the **default** `stdout`. 59 60 ```console 61 $ gencred --context my-current-context --certificate 62 ``` 63 64 The kubeconfig contents will be `output` to `stdout`: 65 66 ```yaml 67 apiVersion: v1 68 clusters: 69 - cluster: 70 certificate-authority-data: fake-ca-data 71 server: https://1.2.3.4 72 name: build 73 contexts: 74 - context: 75 cluster: build 76 user: build 77 name: build 78 current-context: build 79 kind: Config 80 preferences: {} 81 users: 82 - name: build 83 user: 84 client-certificate-data: fake-cert-data 85 client-key-data: fake-key-data 86 ``` 87 88 Specify the `--overwrite` flag to *replace* the `output` file if it exists. 89 90 ```console 91 $ gencred --context my-current-context --output ./existing.yaml --overwrite 92 ``` 93 94 Omit the `--overwrite` flag to *merge* the `output` file if it exists. 95 > Entries from the *existing* file take precedence on conflicts. 96 97 ```console 98 $ gencred --context my-current-context --name oldcluster --output ./existing.yaml 99 $ gencred --context my-current-context --name newcluster --output ./existing.yaml 100 ``` 101 102 The kubeconfig contents will be `output` to `./existing.yaml`: 103 104 ```yaml 105 apiVersion: v1 106 clusters: 107 - cluster: 108 certificate-authority-data: fake-ca-data 109 server: https://1.2.3.4 110 name: oldcluster 111 - cluster: 112 certificate-authority-data: fake-ca-data 113 server: https://1.2.3.4 114 name: newcluster 115 contexts: 116 - context: 117 cluster: oldcluster 118 user: oldcluster 119 name: oldcluster 120 - context: 121 cluster: newcluster 122 user: newcluster 123 name: newcluster 124 users: 125 - name: oldcluster 126 user: 127 client-certificate-data: fake-cert-data 128 client-key-data: fake-key-data 129 - name: newcluster 130 user: 131 client-certificate-data: fake-cert-data 132 client-key-data: fake-key-data 133 ``` 134 135 #### Merging into a kubeconfig in a Kubernetes secret. 136 If you store kubeconfig files in kubernetes secrets to allow pods to access other kubernetes clusters (like many of Prow's components require) consider using [`merge_kubeconfig_secret.py`](/gencred/merge_kubeconfig_secret.py) to merge the kubeconfig produced by `gencred` into the secret. 137 138 ```shell 139 # Generate a kubeconfig.yaml as described and shown above. 140 ./merge_kubeconfig_secret.py --auto --context=my-kube-context kubeconfig.yaml 141 # Note: The first time the script is used you may be prompted to rerun it with --src-key specified. 142 # Finish by updating references (e.g. `--kubeconfig` flags in Prow deployment files) to point to the updated secret key. The script will indicate which key was updated in its output. 143 ``` 144 145 The script exposes optional flags to override the secret namespace, name, keys, and pruning behavior. Run `./merge_kubeconfig_secret.py --help` to view all options. 146 147 ### Library 148 149 #### Generate a service account token for a cluster. 150 ✅ **PREFERRED** method. 151 152 ```go 153 // Import serviceaccount 154 import "k8s.io/test-infra/gencred/pkg/serviceaccount" 155 156 //... 157 158 // Create a Kubernetes clientset for interacting with the cluster. 159 // In this case we are simply using the `current-context` defined in our local `~/.kube/config`. 160 homedir, _ := os.UserHomeDir() 161 kubeconfig := filepath.Join(homedir, ".kube", "config") 162 config, _ := clientcmd.BuildConfigFromFlags("", kubeconfig) 163 clientset, _ := kubernetes.NewForConfig(config) 164 165 // Generate a service account token, as well as return the certificate authority that issued the token. 166 token, caPEM, err := serviceaccount.CreateClusterServiceAccountCredentials(clientset) 167 ``` 168 169 `token` will contain the **service account access token** and `caPEM` will contain the **server certificate authority**. 170 171 This requests a token valid for one week or until the service account is deleted. 172 173 ```go 174 import "encoding/base64" 175 176 //... 177 178 // Cast the `token` to a string to use in a kubeconfig. 179 accessToken := string(token) 180 // Base64 encode the `caPEM` to use in a kubeconfig. 181 ca := base64.StdEncoding.EncodeToString(caPEM) 182 183 fmt.Println("token:", accessToken) 184 fmt.Println("ca:", ca) 185 ``` 186 187 ```text 188 token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3Mit... 189 ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURER... 190 ``` 191 192 #### Generate a client key and certificate for a cluster. 193 ❌ **DEPRECATED** method. 194 195 ```go 196 // Import certificate 197 import "k8s.io/test-infra/gencred/pkg/certificate" 198 199 //... 200 201 // Create a Kubernetes clientset for interacting with the cluster. 202 // In this case we are simply using the `current-context` defined in our local `~/.kube/config`. 203 homedir, _ := os.UserHomeDir() 204 kubeconfig := filepath.Join(homedir, ".kube", "config") 205 config, _ := clientcmd.BuildConfigFromFlags("", kubeconfig) 206 clientset, _ := kubernetes.NewForConfig(config) 207 208 // Generate a client key and certificate, as well as return the certificate authority that issued the certificate. 209 certPEM, keyPEM, caPEM, err := certificate.CreateClusterCertificateCredentials(clientset) 210 ``` 211 212 `certPEM` will contain the **client certificate**, `keyPEM` will contain the **client key**, and `caPEM` will contain the **server certificate authority**. 213 214 ```go 215 import "encoding/base64" 216 217 //... 218 219 // Base64 encode the `certPEM`, `keyPEM`, and `caPEM` to use in a kubeconfig. 220 cert := base64.StdEncoding.EncodeToString(certPEM) 221 key := base64.StdEncoding.EncodeToString(keyPEM) 222 ca := base64.StdEncoding.EncodeToString(caPEM) 223 224 fmt.Println("cert:", cert) 225 fmt.Println("key:", key) 226 fmt.Println("ca:", ca) 227 ``` 228 229 ```text 230 cert: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1... 231 key: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNL... 232 ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURER... 233 ``` 234 235 #### Caveats to using client certificates: 236 * The use of [x509 client certificate](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs) with [super-user](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) privileges for cluster authentication/authorization has several drawbacks: 237 - Certificates **cannot** be revoked ([kubernetes/kubernetes#60917](https://github.com/kubernetes/kubernetes/issues/60917)) 238 - Authorization roles are essentially *global* and thus **cannot** be tweaked at the node level. 239 - Unless setup with near expiry and explicit rotation, certificates are *long-lived* and **increase** the risk of exposure. 240 241 * Client certificate authentication will be deprecated in future versions of Prow ([kubernetes/test-infra#13972](https://github.com/kubernetes/test-infra/issues/13972)).