[helm]: configure JWT expiration (#9940)

helm: configure JWT expiration
This commit is contained in:
Chris Lu
2026-06-12 21:11:30 -07:00
committed by GitHub
parent 5468707289
commit 871d7ddc02
4 changed files with 83 additions and 9 deletions
+49
View File
@@ -68,6 +68,55 @@ jobs:
grep -q "security-config" /tmp/security.yaml grep -q "security-config" /tmp/security.yaml
echo "Security configuration renders correctly" echo "Security configuration renders correctly"
echo ""
echo "=== Testing JWT expiration overrides ==="
helm template test $CHART_DIR \
--set global.seaweedfs.securityConfig.jwtSigning.expiresAfterSeconds.volumeWrite=11 \
> /tmp/jwt-volume-write-expiration.yaml
grep -q "security-config" /tmp/jwt-volume-write-expiration.yaml
grep -q "expires_after_seconds = 11" /tmp/jwt-volume-write-expiration.yaml
helm template test $CHART_DIR \
--set global.seaweedfs.securityConfig.jwtSigning.volumeRead=true \
--set global.seaweedfs.securityConfig.jwtSigning.filerWrite=true \
--set global.seaweedfs.securityConfig.jwtSigning.filerRead=true \
--set global.seaweedfs.securityConfig.jwtSigning.expiresAfterSeconds.volumeWrite=11 \
--set global.seaweedfs.securityConfig.jwtSigning.expiresAfterSeconds.volumeRead=22 \
--set global.seaweedfs.securityConfig.jwtSigning.expiresAfterSeconds.filerWrite=33 \
--set global.seaweedfs.securityConfig.jwtSigning.expiresAfterSeconds.filerRead=44 \
> /tmp/jwt-expiration.yaml
assert_jwt_expiration() {
local section="$1"
local seconds="$2"
awk -v section="[$section]" -v seconds="$seconds" '
/^[[:space:]]*\[.*\][[:space:]]*$/ {
in_section = index($0, section) > 0
}
in_section && $0 ~ "^[[:space:]]*expires_after_seconds = " seconds "$" {
found = 1
}
END { exit !found }
' /tmp/jwt-expiration.yaml
}
assert_jwt_expiration jwt.signing 11
assert_jwt_expiration jwt.signing.read 22
assert_jwt_expiration jwt.filer_signing 33
assert_jwt_expiration jwt.filer_signing.read 44
helm template test $CHART_DIR \
--set global.seaweedfs.enableSecurity=true \
--set global.seaweedfs.securityConfig.jwtSigning.volumeRead=true \
--set global.seaweedfs.securityConfig.jwtSigning.filerWrite=true \
--set global.seaweedfs.securityConfig.jwtSigning.filerRead=true \
> /tmp/jwt-default-expiration.yaml
if grep -q "expires_after_seconds =" /tmp/jwt-default-expiration.yaml; then
echo "FAIL: zero JWT expiration values should preserve runtime defaults"
exit 1
fi
echo "JWT expiration overrides render correctly"
echo "" echo ""
echo "=== Testing IAM gRPC opt-in path ===" echo "=== Testing IAM gRPC opt-in path ==="
# Regression test: the filer registers the IAM gRPC service the # Regression test: the filer registers the IAM gRPC service the
@@ -333,11 +333,13 @@ Create the name of the service account to use
{{- end -}} {{- end -}}
{{/* True when security.toml should be rendered and mounted. volumeWrite is {{/* True when security.toml should be rendered and mounted. volumeWrite is
excluded since it defaults to true. */}} excluded unless its non-default expiration is configured. */}}
{{- define "seaweedfs.securityConfigEnabled" -}} {{- define "seaweedfs.securityConfigEnabled" -}}
{{- $sec := (.Values.global.seaweedfs).securityConfig | default dict -}} {{- $sec := (.Values.global.seaweedfs).securityConfig | default dict -}}
{{- $jwt := $sec.jwtSigning | default dict -}} {{- $jwt := $sec.jwtSigning | default dict -}}
{{- if or .Values.global.seaweedfs.enableSecurity $jwt.volumeRead $jwt.filerWrite $jwt.filerRead -}} {{- $expiresAfterSeconds := $jwt.expiresAfterSeconds | default dict -}}
{{- $volumeWriteExpirationConfigured := and $jwt.volumeWrite (gt (int $expiresAfterSeconds.volumeWrite) 0) -}}
{{- if or .Values.global.seaweedfs.enableSecurity $volumeWriteExpirationConfigured $jwt.volumeRead $jwt.filerWrite $jwt.filerRead -}}
true true
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
@@ -19,40 +19,56 @@ data:
{{- $existing = lookup "v1" "ConfigMap" .Release.Namespace $legacyName }} {{- $existing = lookup "v1" "ConfigMap" .Release.Namespace $legacyName }}
{{- end }} {{- end }}
{{- $securityConfig := fromToml (dig "data" "security.toml" "" $existing) }} {{- $securityConfig := fromToml (dig "data" "security.toml" "" $existing) }}
{{- $securityConfigValues := .Values.global.seaweedfs.securityConfig | default dict }}
{{- $jwtSigning := $securityConfigValues.jwtSigning | default dict }}
{{- $expiresAfterSeconds := $jwtSigning.expiresAfterSeconds | default dict }}
security.toml: |- security.toml: |-
# this file is read by master, volume server, and filer # this file is read by master, volume server, and filer
{{- if .Values.global.seaweedfs.securityConfig.jwtSigning.volumeWrite }} {{- if $jwtSigning.volumeWrite }}
# the jwt signing key is read by master and volume server # the jwt signing key is read by master and volume server
# a jwt expires in 10 seconds # the jwt defaults to expire after 10 seconds
[jwt.signing] [jwt.signing]
key = "{{ dig "jwt" "signing" "key" (randAlphaNum 10 | b64enc) $securityConfig }}" key = "{{ dig "jwt" "signing" "key" (randAlphaNum 10 | b64enc) $securityConfig }}"
{{- if gt (int $expiresAfterSeconds.volumeWrite) 0 }}
expires_after_seconds = {{ int $expiresAfterSeconds.volumeWrite }}
{{- end }}
{{- end }} {{- end }}
{{- if .Values.global.seaweedfs.securityConfig.jwtSigning.volumeRead }} {{- if $jwtSigning.volumeRead }}
# this jwt signing key is read by master and volume server, and it is used for read operations: # this jwt signing key is read by master and volume server, and it is used for read operations:
# - the Master server generates the JWT, which can be used to read a certain file on a volume server # - the Master server generates the JWT, which can be used to read a certain file on a volume server
# - the Volume server validates the JWT on reading # - the Volume server validates the JWT on reading
# the jwt defaults to expire after 60 seconds
[jwt.signing.read] [jwt.signing.read]
key = "{{ dig "jwt" "signing" "read" "key" (randAlphaNum 10 | b64enc) $securityConfig }}" key = "{{ dig "jwt" "signing" "read" "key" (randAlphaNum 10 | b64enc) $securityConfig }}"
{{- if gt (int $expiresAfterSeconds.volumeRead) 0 }}
expires_after_seconds = {{ int $expiresAfterSeconds.volumeRead }}
{{- end }}
{{- end }} {{- end }}
{{- if .Values.global.seaweedfs.securityConfig.jwtSigning.filerWrite }} {{- if $jwtSigning.filerWrite }}
# If this JWT key is configured, Filer only accepts writes over HTTP if they are signed with this JWT: # If this JWT key is configured, Filer only accepts writes over HTTP if they are signed with this JWT:
# - f.e. the S3 API Shim generates the JWT # - f.e. the S3 API Shim generates the JWT
# - the Filer server validates the JWT on writing # - the Filer server validates the JWT on writing
# the jwt defaults to expire after 10 seconds. # the jwt defaults to expire after 10 seconds
[jwt.filer_signing] [jwt.filer_signing]
key = "{{ dig "jwt" "filer_signing" "key" (randAlphaNum 10 | b64enc) $securityConfig }}" key = "{{ dig "jwt" "filer_signing" "key" (randAlphaNum 10 | b64enc) $securityConfig }}"
{{- if gt (int $expiresAfterSeconds.filerWrite) 0 }}
expires_after_seconds = {{ int $expiresAfterSeconds.filerWrite }}
{{- end }}
{{- end }} {{- end }}
{{- if .Values.global.seaweedfs.securityConfig.jwtSigning.filerRead }} {{- if $jwtSigning.filerRead }}
# If this JWT key is configured, Filer only accepts reads over HTTP if they are signed with this JWT: # If this JWT key is configured, Filer only accepts reads over HTTP if they are signed with this JWT:
# - f.e. the S3 API Shim generates the JWT # - f.e. the S3 API Shim generates the JWT
# - the Filer server validates the JWT on reading # - the Filer server validates the JWT on reading
# the jwt defaults to expire after 10 seconds. # the jwt defaults to expire after 60 seconds
[jwt.filer_signing.read] [jwt.filer_signing.read]
key = "{{ dig "jwt" "filer_signing" "read" "key" (randAlphaNum 10 | b64enc) $securityConfig }}" key = "{{ dig "jwt" "filer_signing" "read" "key" (randAlphaNum 10 | b64enc) $securityConfig }}"
{{- if gt (int $expiresAfterSeconds.filerRead) 0 }}
expires_after_seconds = {{ int $expiresAfterSeconds.filerRead }}
{{- end }}
{{- end }} {{- end }}
{{- if .Values.global.seaweedfs.enableSecurity }} {{- if .Values.global.seaweedfs.enableSecurity }}
+7
View File
@@ -26,6 +26,13 @@ global:
volumeRead: false volumeRead: false
filerWrite: false filerWrite: false
filerRead: false filerRead: false
# Positive values override SeaweedFS token lifetime defaults.
# Zero keeps the runtime defaults: 10s for writes and 60s for reads.
expiresAfterSeconds:
volumeWrite: 0
volumeRead: 0
filerWrite: 0
filerRead: 0
# we will use this serviceAccountName for all ClusterRoles/ClusterRoleBindings # we will use this serviceAccountName for all ClusterRoles/ClusterRoleBindings
serviceAccountName: "seaweedfs" serviceAccountName: "seaweedfs"
serviceAccountAnnotations: {} serviceAccountAnnotations: {}