Skip to content

Commit d4f6627

Browse files
committed
feat: refactor Kubernetes service account token management with a sidecar and configurable token path.
1 parent 40d1fb4 commit d4f6627

File tree

6 files changed

+65
-23
lines changed

6 files changed

+65
-23
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# Ignore any binaries generated by the build process
2+
devenv
3+
manager
4+
15
# Example devenv config files
26
developers/
37

cmd/devenv/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import (
1010

1111
// CLIConfig represents the configuration for the CLI
1212
type CLIConfig struct {
13-
ManagerURL string `yaml:"managerURL"`
13+
ManagerURL string `yaml:"managerURL"`
14+
SATokenPath string `yaml:"saTokenPath"`
1415
}
1516

1617
// LoadCLIConfig loads configuration from multiple sources in order of precedence:

cmd/devenv/pods.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func runPodsList(ctx context.Context, args []string) error {
119119
// Create manager client
120120
// For now, we use K8s SA provider with default token path
121121
// In the future, we might support other auth methods
122-
authProvider := auth.NewK8sSAProvider(nil, "", "", "")
122+
authProvider := auth.NewK8sSAProvider(nil, "", "", config.SATokenPath)
123123
c := client.NewClient(config.ManagerURL, authProvider)
124124

125125
// List pods
@@ -166,7 +166,7 @@ func runPodsDelete(ctx context.Context, podName string) error {
166166
}
167167

168168
// Create manager client
169-
authProvider := auth.NewK8sSAProvider(nil, "", "", "")
169+
authProvider := auth.NewK8sSAProvider(nil, "", "", config.SATokenPath)
170170
c := client.NewClient(config.ManagerURL, authProvider)
171171

172172
// Delete pod

internal/manager/auth/k8s_sa_provider.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import (
1212

1313
const (
1414
// DefaultTokenPath is the default path for the projected service account token
15-
DefaultTokenPath = "/var/run/secrets/tokens/devenv-manager"
15+
// DefaultTokenPath = "/var/run/secrets/tokens/devenv-manager"
16+
DefaultTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
1617
)
1718

1819
// K8sSAProvider implements authentication via Kubernetes service account tokens

internal/templates/template_files/dev/manifests/statefulset.tmpl

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,45 @@ spec:
3636
priorityClassName: dev-gpu
3737
{{- end}}
3838

39-
{{- if .IsAdmin}}
40-
serviceAccountName: k8s-launcher
41-
{{- else}}
4239
serviceAccountName: devenv-{{.Name}}
43-
{{- end}}
40+
automountServiceAccountToken: false
4441

4542
containers:
43+
- name: token-syncer
44+
image: busybox:latest
45+
command:
46+
- /bin/sh
47+
- -c
48+
- |
49+
while true; do
50+
if [ -f /var/run/secrets/kubernetes.io/serviceaccount/token ]; then
51+
cp /var/run/secrets/kubernetes.io/serviceaccount/token /shared/token
52+
cp /var/run/secrets/kubernetes.io/serviceaccount/ca.crt /shared/ca.crt
53+
cp /var/run/secrets/kubernetes.io/serviceaccount/namespace /shared/namespace
54+
chmod 644 /shared/*
55+
fi
56+
sleep 60
57+
done
58+
securityContext:
59+
runAsUser: 0
60+
readOnlyRootFilesystem: true
61+
allowPrivilegeEscalation: false
62+
capabilities:
63+
drop: ["ALL"]
64+
resources:
65+
requests:
66+
cpu: "10m"
67+
memory: "16Mi"
68+
limits:
69+
cpu: "50m"
70+
memory: "32Mi"
71+
volumeMounts:
72+
- name: shared-token
73+
mountPath: /shared
74+
- name: sa-token-source # Mount the projected volume
75+
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
76+
readOnly: true
77+
4678
- name: {{.Name}}
4779
image: {{.Image}}
4880
workingDir: "/src"
@@ -104,9 +136,6 @@ spec:
104136
{{- end}}
105137

106138
volumeMounts:
107-
- name: devenv-manager-token
108-
mountPath: /var/run/secrets/tokens
109-
readOnly: true
110139
- name: dev-storage
111140
mountPath: /home/{{.Name}}
112141
- name: dev-linuxbrew
@@ -118,15 +147,12 @@ spec:
118147
- name: {{.Name}}
119148
mountPath: {{.ContainerPath}}
120149
{{- end}}
150+
- name: shared-token # Add this mount
151+
mountPath: /var/run/secrets/devenv
152+
readOnly: true
153+
121154

122155
volumes:
123-
- name: devenv-manager-token
124-
projected:
125-
sources:
126-
- serviceAccountToken:
127-
path: devenv-manager
128-
expirationSeconds: 3600
129-
audience: devenv-manager
130156
- name: dev-storage
131157
hostPath:
132158
path: /mnt/devenv/{{.Name}}/homedir
@@ -139,6 +165,16 @@ spec:
139165
configMap:
140166
name: startup-scripts-{{.Name}}
141167
defaultMode: 0755
168+
- name: shared-token # Add this volume
169+
emptyDir:
170+
sizeLimit: 1Mi
171+
- name: sa-token-source
172+
projected:
173+
sources:
174+
- serviceAccountToken:
175+
path: token
176+
expirationSeconds: 3600 # Token expires after 1 hour
177+
audience: devenv-manager # Your custom audience!
142178
{{- range .Volumes}}
143179
- name: {{.Name}}
144180
hostPath:

internal/templates/template_files/dev/scripts/templated/startup.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ set -e
66
TARGET_UID={{.GetUserID}}
77
TARGET_GID={{.GetUserID}}
88
DEV_USERNAME="{{.Name}}"
9+
SA_TOKEN_PATH="/var/run/secrets/devenv/token"
910

1011
# Path configuration
1112
PYTHON_BIN_PATH="{{.PythonBinPath}}"
12-
PYTHON_PATH="${PYTHON_BIN_PATH}/python3"
1313
ENV_INIT_SCRIPT="/home/${DEV_USERNAME}/.devenv_init.sh"
1414
ENV_BASH_SCRIPT="/home/${DEV_USERNAME}/.devenv_bash.sh"
1515

@@ -18,7 +18,7 @@ echo "Starting container setup for user: ${DEV_USERNAME} (UID: ${TARGET_UID})"
1818
# === SYSTEM PACKAGE INSTALLATION ===
1919
echo "Installing core system packages..."
2020
apt-get update
21-
apt-get install -y sudo openssh-server
21+
apt-get install -y sudo openssh-server python3 python3-pip
2222

2323
# Install Homebrew dependencies if Homebrew will be installed
2424
{{- if .InstallHomebrew}}
@@ -46,7 +46,7 @@ if id -u ${TARGET_UID} &>/dev/null; then
4646
usermod -l ${DEV_USERNAME} -s /bin/bash -d /home/${DEV_USERNAME} -g ${TARGET_GID} $(id -un ${TARGET_UID})
4747
else
4848
echo "Adding user ${DEV_USERNAME} with UID ${TARGET_UID}"
49-
useradd -u ${TARGET_UID} -m -s /bin/bash ${DEV_USERNAME}
49+
useradd -u ${TARGET_UID} -g ${TARGET_GID} -m -s /bin/bash ${DEV_USERNAME}
5050
fi
5151

5252
# Ensure home directory exists and has correct ownership
@@ -137,12 +137,12 @@ rm -rf /home/${DEV_USERNAME}/.local/lib/python*/site-packages/*
137137
# Install common python packages from requirements.txt
138138
if [ -f /scripts/requirements.txt ]; then
139139
echo "Installing Python packages from requirements.txt"
140-
/bin/bash /scripts/run_with_git.sh ${DEV_USERNAME} ${PYTHON_PATH} -m pip install --no-user --no-cache-dir -r /scripts/requirements.txt
140+
/bin/bash /scripts/run_with_git.sh ${DEV_USERNAME} ${PYTHON_BIN_PATH} -m pip install --user --no-cache-dir -r /scripts/requirements.txt
141141
fi
142142

143143
{{- if gt (len .Packages.Python) 0}}
144144
echo "Installing Python packages: {{range $i, $pkg := .Packages.Python}}{{if gt $i 0}} {{end}}{{$pkg}}{{end}}"
145-
/bin/bash /scripts/run_with_git.sh ${DEV_USERNAME} ${PYTHON_PATH} -m pip install --no-user --no-cache-dir{{range .Packages.Python}} {{.}}{{end}}
145+
/bin/bash /scripts/run_with_git.sh ${DEV_USERNAME} ${PYTHON_BIN_PATH} -m pip install --no-user --no-cache-dir{{range .Packages.Python}} {{.}}{{end}}
146146
{{- end}}
147147

148148
{{- if gt (len .Packages.Brew) 0}}

0 commit comments

Comments
 (0)