4
0

kubernetes.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. package rules
  2. import (
  3. "fmt"
  4. "github.com/zricethezav/gitleaks/v8/cmd/generate/config/utils"
  5. "github.com/zricethezav/gitleaks/v8/config"
  6. "github.com/zricethezav/gitleaks/v8/regexp"
  7. )
  8. // KubernetesSecret validates if we detected a kubernetes secret which contains data!
  9. func KubernetesSecret() *config.Rule {
  10. // Only match basic variations of `kind: secret`, we don't want things like `kind: ExternalSecret`.
  11. //language=regexp
  12. kindPat := `\bkind:[ \t]*["']?\bsecret\b["']?`
  13. // Only matches values (`key: value`) under `data:` that are:
  14. // - valid base64 characters
  15. // - longer than 10 characters (no "YmFyCg==")
  16. //language=regexp
  17. dataPat := `\bdata:(?:.|\s){0,100}?\s+([\w.-]+:(?:[ \t]*(?:\||>[-+]?)\s+)?[ \t]*(?:["']?[a-z0-9+/]{10,}={0,3}["']?|\{\{[ \t\w"|$:=,.-]+}}|""|''))`
  18. // define rule
  19. r := config.Rule{
  20. RuleID: "kubernetes-secret-yaml",
  21. Description: "Possible Kubernetes Secret detected, posing a risk of leaking credentials/tokens from your deployments",
  22. Regex: regexp.MustCompile(fmt.Sprintf(
  23. //language=regexp
  24. `(?i)(?:%s(?:.|\s){0,200}?%s|%s(?:.|\s){0,200}?%s)`, kindPat, dataPat, dataPat, kindPat)),
  25. Keywords: []string{
  26. "secret",
  27. },
  28. // Kubernetes secrets are usually yaml files.
  29. Path: regexp.MustCompile(`(?i)\.ya?ml$`),
  30. Allowlists: []config.Allowlist{
  31. {
  32. Regexes: []*regexp.Regexp{
  33. // Ignore empty or placeholder values.
  34. // variable: {{ .Values.Example }} (https://helm.sh/docs/chart_template_guide/variables/)
  35. // variable: ""
  36. // variable: ''
  37. regexp.MustCompile(`[\w.-]+:(?:[ \t]*(?:\||>[-+]?)\s+)?[ \t]*(?:\{\{[ \t\w"|$:=,.-]+}}|""|'')`),
  38. },
  39. },
  40. {
  41. // Avoid overreach between directives.
  42. RegexTarget: "match",
  43. Regexes: []*regexp.Regexp{
  44. regexp.MustCompile(`(kind:(.|\s)+\n---\n(.|\s)+\bdata:|data:(.|\s)+\n---\n(.|\s)+\bkind:)`),
  45. },
  46. },
  47. },
  48. }
  49. // validate
  50. tps := map[string]string{
  51. "base64-characters.yaml": `
  52. apiVersion: v1
  53. kind: Secret
  54. data:
  55. password: AAAAAAAAAAC7hjsA+H3owFygUv4w5B67lcSx14zff9FCPADiNbSwYWgE+O7Dhiy5tkRecs21ljjofvebe6xsYlA4cVmght0=`,
  56. "comment.yaml": `
  57. apiVersion: v1
  58. kind: Secret
  59. metadata:
  60. name: heketi-secret
  61. namespace: default
  62. data:
  63. # base64 encoded password. E.g.: echo -n "mypassword" | base64
  64. key: bXlwYXNzd29yZA==`,
  65. // The "data"-key is before the identifier "kind: Secret"
  66. "before-kubernetes.yaml": `apiVersion: v1
  67. data:
  68. extra: YWRtaW46cGFzc3dvcmQ=
  69. kind: secret
  70. metadata:
  71. name: secret-sa-sample
  72. annotations:
  73. kubernetes.io/service-account.name: 'sa-name'`,
  74. "before-kubernetes.yml": `apiVersion: v1
  75. data:
  76. password: UyFCXCpkJHpEc2I9
  77. username: YWRtaW4=
  78. kind: Secret
  79. metadata:
  80. creationTimestamp: '2022-06-28T17:44:13Z'
  81. name: db-user-pass
  82. namespace: default
  83. type: Opaque`,
  84. "before-comment.yml": `apiVersion: v1
  85. data:
  86. # the data is abbreviated in this example
  87. password: UyFCXCpkJHpEc2I9
  88. username: YWRtaW4=
  89. kind: Secret
  90. metadata:
  91. creationTimestamp: '2022-06-28T17:44:13Z'
  92. name: db-user-pass
  93. namespace: default
  94. type: Opaque`,
  95. "before-quoted-1.yaml": `apiVersion: 'v1'
  96. data:
  97. extra: 'YWRtaW46cGFzc3dvcmQ='
  98. kind: 'Secret'
  99. metadata:
  100. name: 'secret-sa-sample'
  101. annotations:
  102. kubernetes.io/service-account.name: 'sa-name'`,
  103. "before-quoted-2.yaml": `apiVersion: "v1"
  104. data:
  105. extra: "YWRtaW46cGFzc3dvcmQ="
  106. kind: "secret"
  107. metadata:
  108. name: "secret-sa-sample"
  109. annotations:
  110. kubernetes.io/service-account.name: "sa-name"`,
  111. "before-multiline-literal.yaml": `apiVersion: v1
  112. data:
  113. .dockercfg: |
  114. eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=
  115. metadata:
  116. name: secret-dockercfg
  117. type: kubernetes.io/dockercfg
  118. kind: Secret
  119. `,
  120. "before-multiline-folded.yaml": `apiVersion: v1
  121. data:
  122. .dockercfg: >
  123. eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=
  124. metadata:
  125. name: secret-dockercfg
  126. type: kubernetes.io/dockercfg
  127. kind: Secret`,
  128. // Sample Kubernetes Secret from https://kubernetes.io/docs/concepts/configuration/secret/
  129. // The "data"-key is after the identifier "kind: Secret"
  130. "after-kubernetes.yaml": `apiVersion: v1
  131. kind: secret
  132. data:
  133. extra: YWRtaW46cGFzc3dvcmQ=
  134. metadata:
  135. name: secret-sa-sample
  136. annotations:
  137. kubernetes.io/service-account.name: 'sa-name'`,
  138. "after-kubernetes.yml": `apiVersion: v1
  139. kind: Secret
  140. metadata:
  141. name: ca-secret
  142. type: Opaque
  143. data:
  144. ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR4RENDQXF5Z0F3SUJBZ0lVV3pqUDl5RUk0eHlRSnBzVHVERU4yV2ROaUFzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FERUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQWdUQms5eVpXZHZiakVSTUE4R0ExVUVCeE1JVUc5eQpkR3hoYm1ReEV6QVJCZ05WQkFvVENrdDFZbVZ5Ym1WMFpYTXhDekFKQmdOVkJBc1RBa05CTVJNd0VRWURWUVFECkV3cExkV0psY201bGRHVnpNQjRYRFRFMk1EZ3hNVEUyTkRnd01Gb1hEVEl4TURneE1ERTJORGd3TUZvd2FERUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFnVEJrOXlaV2R2YmpFUk1BOEdBMVVFQnhNSVVHOXlkR3hoYm1ReApFekFSQmdOVkJBb1RDa3QxWW1WeWJtVjBaWE14Q3pBSkJnTlZCQXNUQWtOQk1STXdFUVlEVlFRREV3cExkV0psCmNtNWxkR1Z6TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3QkhNOGN6anc0Q1cKK05wbklhV012RzZlcVhtelNZT20vbHdaNUhOMnVLck9xaTNHYUUyTjFKd2tzcGRmMXNOUGFZMHdPR2xkbURIZgoxSnlyTW8rUFdLVUVjWko1WGE4Vm02d2I0MlpjczN3MEp5dlEzWFJjaDQyMFJRWGRKayszcmMybWRvSVRkL0lmCnZjWms0N0RzQTMrQU5QSUlSTzdWRmZpS1JNRFpTUDR1OThnVjI2eW1zbjc0TzFVKzNVUHR1TEFTVTFLck9FTk4KR01FWG0ydTJpdmVvbTJrbjFlZTZuM1hCR1o2bU52cUNPdWUxRXdza0gvWkhoUVh1UDgyV1U5dVk0aGVORnoyQwpBNmR0Q0Q0c3Z6eHc3ZFQ2cVhsV0ZIWUYrc3VLVDhXNkczd3NkOWxzV0ZVY0ZWL0lwaTVobEVaTWprNFNoY3RqCjdpYnlrRURKM1FJREFRQUJvMll3WkRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RWdZRFZSMFRBUUgvQkFnd0JnRUIKL3dJQkFqQWRCZ05WSFE0RUZnUVVOdnhRZ3o5ZTNXS2VscU1KTmZXNE1KUHYzc0V3SHdZRFZSMGpCQmd3Rm9BVQpOdnhRZ3o5ZTNXS2VscU1KTmZXNE1KUHYzc0V3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUp1TUhYUms1TEVyCmxET1p4Mm9aRUNQZ29reXMzSGJsM05oempXd2pncXdxNVN6a011V3QrUnVkdnRTK0FUQjFtTjRjYTN0eSt2bWcKT09heTkvaDZoditmSE5jZHpYdWR5dFZYZW1KN3F4ZFoxd25DUUcwdnpqOWRZY0xFSGpJWi94dU1jNlY3dnJ4YwpSc0preGp5aE01UXBmRHd0eVZKeGpkUmVBZ0huSyswTkNieHdtQ3cyRGIvOXpudm9LWGk4TEQwbkQzOFQxY3R3CmhmdGxwTmRoZXFNRlpEZXBuTUYwY2g2cHo5TFV5Mkh1cnhrV2dkWVNjY2VNU0hPTzBMcG4xeVVBMWczOTJhUjUKWk81Zm5KMW95Vm1LVWFCeDJCMndsSVlUSXlES1ZiMnY1UXNHbnYvRHVTMDZhcmVLTmsvTGpHRTRlMXlHOHJkcwpacnZHMzNvUmtEbz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
  145. `,
  146. "after-comment.yml": `apiVersion: v1
  147. kind: Secret
  148. metadata:
  149. creationTimestamp: '2022-06-28T17:44:13Z'
  150. name: db-user-pass
  151. namespace: default
  152. type: Opaque
  153. data:
  154. # the data is abbreviated in this example
  155. password: UyFCXCpkJHpEc2I9
  156. username: YWRtaW4=
  157. `,
  158. "after-quoted-1.yaml": `apiVersion: 'v1'
  159. kind: 'Secret'
  160. data:
  161. password: 'UyFCXCpkJHpEc2I9'
  162. username: 'YWRtaW4='
  163. metadata:
  164. name: 'db-user-pass'
  165. namespace: 'default'
  166. type: 'Opaque'`,
  167. "after-quoted-2.yaml": `apiVersion: "v1"
  168. kind: "Secret"
  169. data:
  170. password: "UyFCXCpkJHpEc2I9"
  171. username: "YWRtaW4="
  172. metadata:
  173. name: "db-user-pass"
  174. namespace: "default"
  175. type: "Opaque"`,
  176. "after-multiline-literal.yaml": `apiVersion: v1
  177. kind: Secret
  178. metadata:
  179. name: secret-dockercfg
  180. type: kubernetes.io/dockercfg
  181. data:
  182. .dockercfg: |
  183. eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=
  184. `,
  185. "after-multiline-folded.yaml": `apiVersion: v1
  186. kind: Secret
  187. metadata:
  188. name: secret-dockercfg
  189. type: kubernetes.io/dockercfg
  190. data:
  191. .dockercfg: >
  192. eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUvdjEvIjp7ImF1dGgiOiJvcGVuc2VzYW1lIn19fQo=`,
  193. }
  194. fps := map[string]string{
  195. "empty-quotes1.yml": `apiVersion: v1
  196. kind: Secret
  197. metadata:
  198. name: registry-auth-data
  199. type: Opaque
  200. data:
  201. htpasswd: ''
  202. `,
  203. "empty-quotes2.yml": `apiVersion: v1
  204. kind: Secret
  205. metadata:
  206. name: registry-auth-data
  207. type: Opaque
  208. data:
  209. htpasswd: ""
  210. `,
  211. "overly-permissive1.yaml": `apiVersion: v1
  212. kind: Secret
  213. metadata:
  214. name: registry-auth-data
  215. type: Opaque
  216. data:
  217. htpasswd: {{ htpasswd }}
  218. ---
  219. apiVersion: v1
  220. kind: ReplicationController`,
  221. "overly-permissive2.yaml": `apiVersion: v1
  222. kind: Secret
  223. metadata:
  224. labels:
  225. k8s-app: kubernetes-dashboard
  226. addonmanager.kubernetes.io/mode: EnsureExists
  227. name: kubernetes-dashboard-csrf
  228. namespace: kubernetes-dashboard
  229. type: Opaque
  230. data:
  231. csrf: ""
  232. ---
  233. apiVersion: v1
  234. kind: Secret
  235. metadata:
  236. labels:
  237. k8s-app: kubernetes-dashboard
  238. addonmanager.kubernetes.io/mode: EnsureExists
  239. name: kubernetes-dashboard-key-holder
  240. namespace: kubernetes-dashboard
  241. type: Opaque
  242. `,
  243. "overly-permissive3.yaml": ` kind: Secret
  244. target:
  245. name: mysecret
  246. creationPolicy: Owner
  247. ---
  248. kind: ConfigMap
  249. data:
  250. conversionStrategy: Default
  251. decodingStrategy: None
  252. key: secret/mysecret
  253. property: foo
  254. secretKey: foo`,
  255. // https://github.com/gitleaks/gitleaks/issues/1644
  256. "wrong-kind.yaml": `apiVersion: external-secrets.io/v1beta1
  257. kind: ExternalSecret
  258. metadata:
  259. name: example
  260. namespace: example-ns
  261. spec:
  262. refreshInterval: 15s
  263. secretStoreRef:
  264. name: example
  265. kind: SecretStore
  266. target:
  267. name: mysecret
  268. creationPolicy: Owner
  269. data:
  270. - remoteRef:
  271. conversionStrategy: Default
  272. decodingStrategy: None
  273. key: secret/mysecret
  274. property: foo
  275. secretKey: foo
  276. `,
  277. "sopssecret.yaml": `apiVersion: isindir.github.com/v1alpha3
  278. kind: SopsSecret
  279. metadata:
  280. name: app1-sopssecret
  281. namespace: test
  282. spec:
  283. suspend: false
  284. secretTemplates:
  285. - name: ENC[AES256_GCM,data:W3PiZ6lD6bpfAdI=,iv:2qF98ZkchgfWF4tZo8fok6zY0ZLNRV3wFpl8n2iyC7I=,tag:FzoL+CZHkLEqfWKniRApBA==,type:str]
  286. labels:
  287. app: ENC[AES256_GCM,data:t9ujIQ==,iv:slZBpmKF+DOg/wVBWmq5iTqkRBZUMao0a3MdoxzJs3s=,tag:xJyhdJ4rn/cB/4mxHzmGig==,type:str]
  288. stringData:
  289. db-password: ENC[AES256_GCM,data:O+5l4g==,iv:c/dS4BCBMbnKsXYuzBuCuVQt8RV9bOv5HgdpL+iwmns=,tag:KkQfh6OymvCt4uC13p318g==,type:str]
  290. sops:
  291. kms: []
  292. gcp_kms: []
  293. azure_kv: []
  294. hc_vault: []
  295. lastmodified: '2021-10-21T10:56:37Z'
  296. mac: ENC[AES256_GCM,data:Tl1V1PuI5tZ0Hu3qxxzpDNeKQkuW0g/x/Mlp1yM6HaBqDr+r2FukLdYSYqjjJ3A8g+YkpvMib50M7j0V7zoX9sgCvMKEg86pRsWtThv8n/L+bsjClVTqnhJ9nfYlaPOMlvggbiMOE5hXPIuVz8WXYoVYJ2cVNCd/GfwOraUmj7I=,iv:n7HVI13okfbW3FS/ZsJ2GNmibudxc/TlkLa3umQQ+vc=,tag:R4ikep1wlxlDWlODJqFHHw==,type:str]
  297. pgp:
  298. - created_at: '2021-10-21T10:56:37Z'
  299. enc: |
  300. -----BEGIN PGP MESSAGE-----
  301. hQGMA3muqimBu2IIAQwAkhR19/6roLq06oaD12vqDMes3/8FweAHxa6TLKg+LRjp
  302. 2/ntiRJHPBP9DYYFZbkTo8lAmIdVF7KfGIqWgPm5JiNhqfVRhyGPCRgBE7+I8qH6
  303. EML9Vo/76kJLHtIjs5rOg7OXgwwitaibs1q6uyVY8TuaGXYIOO1iwL9xVtbayIry
  304. NMQd1tFcNb6Vb86Plqm+T1VnSOJMUvryxrLelx89UNM0ctepyVu6YY9jpBjV0QLJ
  305. NqNkKAGIMv3RNa9bZHTwveo9T0oXtFnk5H33BxH0ky/DGpD+5Ch1YgbzbqVnr+Bm
  306. RX0R/GRhS9IDInd+eiyVX6y3LR5di0fc8TuK43+96wTG+2+ck+lbMrkHYsL2UJNv
  307. bAjlOWmIcL4UwGlEOj4EzwcEx+xP3dq57pJ+DasfNwVqps2Kk+ofodR7d6gx7ELH
  308. UQmLypCtkRic9v8fVSA2vEL8hAlg9bT8tpHLhHMOwe228cL5dTzFD60RoP+ovRar
  309. jIU59Pnu1bnM4pXWEVA20l4BzJ8Fd6gj3TfAg/7Mat+dnTaUwnPgRSybFn0ZZHMW
  310. RJDBPkMGFfSGRDfLeD37d61mI31360/w/61LaVp1sdDYodBJCRZFA1YzbqZcxnDl
  311. YRjRmpcVRnO+o72CnU/P
  312. =V4l4
  313. -----END PGP MESSAGE-----
  314. fp: 73019E949C1D3C3D1BE8B718C7CD51A565AB592C
  315. encrypted_suffix: Templates
  316. version: 3.6.1`, // https://github.com/luca-iachini/argocd-test/blob/af0c8eaba270bc918108c8bc3b909f26a4fe995d/kustomize/base/app1/secrets.enc.yaml#L4
  317. // The "data"-key is before the identifier "kind: Secret"
  318. "before-min-length.yaml": `apiVersion: v1
  319. data:
  320. extra: YmFyCg==
  321. kind: secret
  322. metadata:
  323. name: secret-sa-sample
  324. annotations:
  325. kubernetes.io/service-account.name: 'sa-name'`,
  326. "before-template.yaml": `apiVersion: v1
  327. data:
  328. password: {{ .Values.Password }}
  329. kind: secret
  330. metadata:
  331. name: secret-sa-sample
  332. annotations:
  333. kubernetes.io/service-account.name: 'sa-name'`,
  334. "before-externalsecret1.yml": `apiVersion: 'kubernetes-client.io/v1'
  335. metadata:
  336. name: actions-exporter
  337. namespace: github-actions-exporter
  338. spec:
  339. backendType: secretsManager
  340. data:
  341. - key: MySecretManagerKey
  342. name: github_token
  343. property: github_token
  344. kind: ExternalSecret
  345. `,
  346. "before-externalsecret2.yml": `apiVersion: external-secrets.io/v1beta1
  347. spec:
  348. secretStoreRef:
  349. kind: ClusterSecretStore
  350. name: aws-secretsmanager
  351. refreshInterval: 1h
  352. target:
  353. creationPolicy: Owner
  354. data:
  355. - secretKey: api-key
  356. remoteRef:
  357. key: my-secrets-manager-secret
  358. metadata:
  359. name: api-key
  360. namespace: my-namespace
  361. kind: ExternalSecret
  362. `,
  363. "before-sopssecret.yml": `apiVersion: isindir.github.com/v1alpha3
  364. spec:
  365. secretTemplates:
  366. - name: my-secret-name-1
  367. labels:
  368. label1: value1
  369. annotations:
  370. key1: value1
  371. data:
  372. data-name1: ZGF0YS12YWx1ZTE=
  373. data-nameM: ZGF0YS12YWx1ZU0=
  374. kind: SopsSecret
  375. metadata:
  376. name: sopssecret-sample
  377. `, // https://github.com/isindir/sops-secrets-operator/blob/8aaf8bb368dc841a2d57f251bd839f08216a9328/config/samples/isindir_v1alpha3_sopssecret.yaml#L4
  378. // The "data"-key is after the identifier "kind: Secret"
  379. "after-min-length.yaml": `apiVersion: v1
  380. kind: secret
  381. data:
  382. extra: YmFyCg==
  383. metadata:
  384. name: secret-sa-sample
  385. annotations:
  386. kubernetes.io/service-account.name: 'sa-name'`,
  387. "after-externalsecret1.yml": `apiVersion: 'kubernetes-client.io/v1'
  388. kind: ExternalSecret
  389. metadata:
  390. name: actions-exporter
  391. namespace: github-actions-exporter
  392. spec:
  393. backendType: secretsManager
  394. data:
  395. - key: MySecretManagerKey
  396. name: github_token
  397. property: github_token
  398. - key: MySecretManagerKey`,
  399. "after-externalsecret2.yml": `apiVersion: external-secrets.io/v1beta1
  400. kind: ExternalSecret
  401. metadata:
  402. name: api-key
  403. namespace: my-namespace
  404. spec:
  405. secretStoreRef:
  406. kind: ClusterSecretStore
  407. name: aws-secretsmanager
  408. refreshInterval: 1h
  409. target:
  410. creationPolicy: Owner
  411. data:
  412. - secretKey: api-key
  413. remoteRef:
  414. key: my-secrets-manager-secret`,
  415. "after-sopssecret.yml": `apiVersion: isindir.github.com/v1alpha3
  416. kind: SopsSecret
  417. metadata:
  418. name: sopssecret-sample
  419. spec:
  420. secretTemplates:
  421. - name: my-secret-name-0
  422. labels:
  423. label0: value0
  424. labelK: valueK
  425. annotations:
  426. key0: value0
  427. keyN: valueN
  428. stringData:
  429. data-name0: data-value0
  430. data-nameL: data-valueL
  431. - name: my-secret-name-1
  432. labels:
  433. label1: value1
  434. annotations:
  435. key1: value1
  436. data:
  437. data-name1: ZGF0YS12YWx1ZTE=
  438. data-nameM: ZGF0YS12YWx1ZU0=`,
  439. "after-empty-data.yaml": `apiVersion: v1
  440. kind: Secret
  441. metadata:
  442. labels:
  443. k8s-app: kubernetes-dashboard
  444. addonmanager.kubernetes.io/mode: EnsureExists
  445. name: kubernetes-dashboard-csrf
  446. namespace: kubernetes-dashboard
  447. type: Opaque
  448. data:
  449. csrf: ""
  450. `,
  451. }
  452. return utils.ValidateWithPaths(r, tps, fps)
  453. }