Skip to content

Commit 8a118c9

Browse files
committed
design: improved service account token volumes
1 parent 1f79ecc commit 8a118c9

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Service Account Token Volumes
2+
3+
Authors:
4+
@smarterclayton
5+
@liggitt
6+
@mikedanese
7+
8+
## Summary
9+
10+
Kubernetes is able to provide pods with unique identity tokens that can prove
11+
the caller is a particular pod to a Kubernetes API server. These tokens are
12+
injected into pods as secrets. This proposal proposes a new mechanism of
13+
distribution with support for [improved service account tokens][better-tokens]
14+
and explores how to migrate from the existing mechanism backwards compatibly.
15+
16+
## Motivation
17+
18+
Many workloads running on Kubernetes need to prove to external parties who they
19+
are in order to participate in a larger application environment. This identity
20+
must be attested to by the orchestration system in a way that allows a third
21+
party to trust that an arbitrary container on the cluster is who it says it is.
22+
In addition, infrastructure running on top of Kubernetes needs a simple
23+
mechanism to communicate with the Kubernetes APIs and to provide more complex
24+
tooling. Finally, a significant set of security challenges are associated with
25+
storing service account tokens as secrets in Kubernetes and limiting the methods
26+
whereby malicious parties can get access to these tokens will reduce the risk of
27+
platform compromise.
28+
29+
As a platform, Kubernetes should evolve to allow identity management systems to
30+
provide more powerful workload identity without breaking existing use cases, and
31+
provide a simple out of the box workload identity that is sufficient to cover
32+
the requirements of bootstrapping low-level infrastructure running on
33+
Kubernetes. We expect that other systems to cover the more advanced scenarios,
34+
and see this effort as necessary glue to allow more powerful systems to succeed.
35+
36+
With this feature, we hope to provide a backwards compatible replacement for
37+
service account tokens that strengthens the security and improves the
38+
scalability of the platform.
39+
40+
## Proposal
41+
42+
Kubernetes should:
43+
44+
1. Allow the automatic service account token injection to be disabled via
45+
configuration.
46+
1. Allow automatic service account token creation to occur only when a user
47+
explicitly requests.
48+
1. Implement a ServiceAccountToken volume projection that maintains a service
49+
account token requested by the node from the TokenRequest API.
50+
51+
### Token Volume Projection
52+
53+
A new volume projection will be implemented with an API that closely matches the
54+
TokenRequest API.
55+
56+
```go
57+
type ProjectedVolumeSource struct {
58+
Sources []VolumeProjection
59+
DefaultMode *int32
60+
}
61+
62+
type VolumeProjection struct {
63+
Secret *SecretProjection
64+
DownwardAPI *DownwardAPIProjection
65+
ConfigMap *ConfigMapProjection
66+
ServiceAccountToken *ServiceAccountTokenProjection
67+
}
68+
69+
// ServiceAccountTokenProjection represents a projected service account token
70+
// volume. This projection can be used to insert a service account token into
71+
// the pods runtime filesystem for use against APIs (Kubernetes API Server or
72+
// otherwise).
73+
type ServiceAccountTokenProjection struct {
74+
// Audience is the intended audience of the token. A recipient of a token
75+
// must identify itself with an identifier specified in the audience of the
76+
// token, and otherwise should reject the token.
77+
Audience string
78+
// ExpirationSeconds is the requested duration of validity of the service
79+
// account token. Defaults to 1 hour.
80+
ExpirationSeconds *int64
81+
// Path is the relative path of the file to project the token into.
82+
Path string
83+
}
84+
```
85+
86+
A volume plugin implemented in the kubelet will project a service account token
87+
sourced from the TokenRequest API into volumes created from
88+
ProjectedVolumeSources. As the token approaches expiration, the kubelet volume
89+
plugin will proactively rotate the service account token. The kubelet will start
90+
trying to rotate the token if the token is older than 80 percent of its time to
91+
live or if the token is older than 24 hours.
92+
93+
To replace the current service account token secrets, we also need to inject the
94+
clusters CA certificate bundle. Initially we will deploy to data in a configmap
95+
per-namespace and reference it using a ConfigMapProjection.
96+
97+
A projected volume source that is equivalent to the current service account
98+
secret:
99+
100+
```yaml
101+
sources:
102+
- serviceAccountToken:
103+
expirationSeconds: 3153600000 # 100 years
104+
path: token
105+
- configMap:
106+
name: kube-cacrt
107+
items:
108+
- key: ca.crt
109+
path: ca.crt
110+
- downwardAPI:
111+
items:
112+
- path: namespace
113+
fieldRef: metadata.namespace
114+
```
115+
116+
117+
This fixes one scalability issue with the current service account token
118+
deployment model where secret GETs are a large portion of overall apiserver
119+
traffic.
120+
121+
A projected volume source that requests a token for vault and Istio CA:
122+
123+
```yaml
124+
sources:
125+
- serviceAccountToken:
126+
path: vault-token
127+
audience: vault
128+
- serviceAccountToken:
129+
path: istio-token
130+
audience: ca.istio.io
131+
```
132+
133+
### Risks and Mitigations
134+
135+
Reducing the scope of service account tokens by not creating them automatically
136+
on service account creation is technically an API break. This would have to be
137+
opt-in, but like RBAC is about reducing the scope of vulnerability. Many people
138+
may opt not to disable it. For those who do disable it, we can preserve the
139+
existing behavior of being able to create a secret of type service-account-token
140+
(with the annotation to the service account that links to it) and have the
141+
controller auto populate it.
142+
143+
FlexVolume and CSI are the only way to deliver custom content to nodes today
144+
without persisting it in the API. In a virtual kubelet environment, these
145+
mechanisms may not work the same as on regular kubelets, so third party identity
146+
integrators may not be able to deliver their custom content. A container volume
147+
or init container might be a sufficient workaround.
148+
149+
### Alternatives
150+
151+
1. Instead of implementing a service account token volume projection, we could
152+
implement all injection as a flex volume or CSI plugin.
153+
1. Both flex volume and CSI are alpha and are unlikely to graduate soon.
154+
1. Virtual kubelets (like Fargate or ACS) may not be able to run flex
155+
volumes.
156+
1. Service account tokens are a fundamental part of our API.
157+
1. Remove service accounts and service account tokens completely from core, use
158+
an alternate mechanism that sits outside the platform.
159+
1. Other core features need service account integration, leading to all
160+
users needing to install this extension.
161+
1. Complicates installation for the majority of users.
162+
163+
164+
[better-tokens]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/auth/bound-service-account-tokens.md

0 commit comments

Comments
 (0)