Skip to content

Commit ad30827

Browse files
authored
Merge pull request #37 from FreakIsTea/main
feat: allow secrets as source for auth identity/secret
2 parents b1e490a + 63875a0 commit ad30827

11 files changed

Lines changed: 140 additions & 7 deletions

File tree

‎.github/workflows/functional-test.yaml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ jobs:
5858
values: ci/functional/values/filesystem.yaml
5959
- backend: transient
6060
values: ci/functional/values/transient.yaml
61+
- backend: auth-existing-secret
62+
values: ci/functional/values/auth-existing-secret.yaml
63+
authSecret: true
6164
- backend: azureblob
6265
values: ci/functional/values/azureblob.yaml
6366
mock: ci/functional/mocks/azurite.yaml
@@ -111,6 +114,16 @@ jobs:
111114
--from-file=keystore.p12=/tmp/keystore.p12 \
112115
--from-literal=keystore-password=changeit
113116
117+
- name: Create client auth Secret (auth existingSecret leg)
118+
if: matrix.authSecret
119+
# The identity/secret the smoke test signs with, in the Secret the chart
120+
# references via config.auth.existingSecret. Broken wiring leaves
121+
# s3proxy.identity/credential unset and the round-trip fails to authenticate.
122+
run: |
123+
kubectl -n "${NAMESPACE}" create secret generic s3proxy-auth \
124+
--from-literal=accessKeyId='test-access-key' \
125+
--from-literal=secretAccessKey='test-secret-key'
126+
114127
- name: Create Azure Blob key Secret (existingSecret leg)
115128
if: matrix.azureKeySecret
116129
# Azurite's devstoreaccount1 key in the Secret the chart references via

‎.github/workflows/lint-render.yaml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ jobs:
3030
- test-values/s3.yaml
3131
- test-values/azureblob.yaml
3232
- test-values/azureblob-existing-secret.yaml
33+
- test-values/auth-existing-secret.yaml
3334
- test-values/azureblob-managed-identity.yaml
3435
- test-values/gcs.yaml
3536
- test-values/b2.yaml

‎charts/s3proxy/Chart.yaml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type: application
1515
# This is the chart version. This version number should be incremented each time you make changes
1616
# to the chart and its templates, including the app version.
1717
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18-
version: 0.4.3
18+
version: 0.5.0
1919

2020
# This is the version number of the application being deployed. This version number should be
2121
# incremented each time you make changes to the application. Versions are not expected to

‎charts/s3proxy/README.md.gotmpl‎

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,41 @@ persistence:
236236
enabled: false
237237
```
238238

239+
## Client authentication credentials
240+
241+
`config.auth.identity` / `config.auth.secret` are the S3 Access Key ID and Secret
242+
Access Key that *clients* present to S3Proxy.
243+
244+
### Option A: existing Secret (recommended)
245+
246+
Point `config.auth.existingSecret` at a Secret you manage yourself, so the credentials
247+
never appear in the values file (e.g. in GitOps). It takes precedence over inline
248+
`identity`/`secret`; both credentials are read from it:
249+
250+
```yaml
251+
config:
252+
auth:
253+
type: "aws-v4"
254+
existingSecret: my-s3proxy-auth
255+
identityKey: accessKeyId # default; key holding the Access Key ID
256+
secretKey: secretAccessKey # default; key holding the Secret Access Key
257+
```
258+
259+
```bash
260+
kubectl create secret generic my-s3proxy-auth \
261+
--from-literal=accessKeyId='myaccesskey' \
262+
--from-literal=secretAccessKey='mysecretkey'
263+
```
264+
265+
Rotating the Secret does not restart the pod — roll the Deployment yourself, since the
266+
credentials are read once at startup.
267+
268+
### Option B: inline credentials
269+
270+
Set `config.auth.identity` / `config.auth.secret` directly, as in
271+
[Example 1](#example-1-filesystem-backend-with-authentication). Convenient for
272+
testing; both values are stored in plaintext in the chart's own Secret.
273+
239274
## Testing the Installation
240275

241276
Once deployed, you can test S3Proxy using the AWS CLI:
@@ -426,7 +461,7 @@ This will remove all resources created by the chart. If using persistence, the P
426461

427462
### Common Issues
428463

429-
1. **Authentication failures**: Ensure `config.auth.identity` and `config.auth.secret` are set correctly for client authentication.
464+
1. **Authentication failures**: Ensure `config.auth.identity` and `config.auth.secret` are set correctly (or, with `config.auth.existingSecret`, that the Secret exists and its `identityKey`/`secretKey` entries are present) for client authentication.
430465

431466
2. **Backend connection issues**: Verify backend credentials are correctly configured in the appropriate section (e.g., `config.backend.awsS3.*`).
432467

‎charts/s3proxy/override-values.example.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ config:
2626
# These should be changed to secure values
2727
identity: "admin"
2828
secret: "changeme123"
29+
# Or keep them out of this file entirely and read both from a Secret you
30+
# manage (takes precedence over the inline values above):
31+
# existingSecret: "my-s3proxy-auth"
32+
# identityKey: "accessKeyId"
33+
# secretKey: "secretAccessKey"
2934

3035
# Native in-pod HTTPS (S3Proxy secure-endpoint). When enabled, S3Proxy serves
3136
# HTTPS only on service.targetPort; TLS is terminated in the pod rather than at

‎charts/s3proxy/templates/NOTES.txt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@
106106
{{- if .Values.config.backends.filesystem.enabled }}
107107
- Using filesystem backend at: {{ .Values.config.backends.filesystem.basedir }}
108108
{{- end }}
109-
{{- if not .Values.config.auth.identity }}
110-
- WARNING: S3Proxy identity not configured. Remember to set config.auth.identity and config.auth.secret for authentication.
109+
{{- if and (not .Values.config.auth.identity) (not .Values.config.auth.existingSecret) }}
110+
- WARNING: S3Proxy identity not configured. Remember to set config.auth.identity and config.auth.secret (or config.auth.existingSecret) for authentication.
111111
{{- end }}
112112
{{- if .Values.config.backends.s3.enabled }}
113113
- Make sure to configure S3 backend credentials

‎charts/s3proxy/templates/deployment.yaml‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,18 @@ spec:
7272
cat "$COMMON_SECRET" >> "$output_file"
7373
fi
7474
75+
# Client auth from config.auth.existingSecret: each file under
76+
# /auth-secret/ is named for the S3Proxy property it holds.
77+
if [ -d "/auth-secret" ]
78+
then
79+
for prop_file in /auth-secret/*
80+
do
81+
[ -f "$prop_file" ] || continue
82+
echo "" >> "$output_file" # Add newline separator
83+
printf '%s=%s\n' "$(basename "$prop_file")" "$(cat "$prop_file")" >> "$output_file"
84+
done
85+
fi
86+
7587
# Append this backend's own secret: backend-<name>.properties
7688
# pairs with secret-<name>.properties
7789
backend="${filename#backend-}"
@@ -122,6 +134,11 @@ spec:
122134
mountPath: /tls-password
123135
readOnly: true
124136
{{- end }}
137+
{{- if .Values.config.auth.existingSecret }}
138+
- name: auth-secret
139+
mountPath: /auth-secret
140+
readOnly: true
141+
{{- end }}
125142
{{- range $s := (include "s3proxy.externalBackendSecrets" . | fromJsonArray) }}
126143
- name: {{ $s.name }}
127144
mountPath: /backend-secret/{{ $s.backend }}/{{ $s.prop }}
@@ -291,6 +308,16 @@ spec:
291308
- key: {{ .Values.config.backends.googleCloudStorage.privateKey.secretKey }}
292309
path: gcs-private.key
293310
{{- end }}
311+
{{- if .Values.config.auth.existingSecret }}
312+
- name: auth-secret
313+
secret:
314+
secretName: {{ .Values.config.auth.existingSecret }}
315+
items:
316+
- key: {{ .Values.config.auth.identityKey }}
317+
path: s3proxy.identity
318+
- key: {{ .Values.config.auth.secretKey }}
319+
path: s3proxy.credential
320+
{{- end }}
294321
{{- range $s := (include "s3proxy.externalBackendSecrets" . | fromJsonArray) }}
295322
- name: {{ $s.name }}
296323
secret:

‎charts/s3proxy/templates/secret.yaml‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ data:
1212
# into the text properties. Used only when keystore.existingSecret is empty.
1313
{{ .Values.config.tls.keystore.secretKey }}: {{ .Values.config.tls.keystore.value }}
1414
{{- end }}
15+
{{- with include "s3proxy.secret.stringData" . }}
1516
stringData:
1617
# Sensitive properties merged into the backend properties files by the
1718
# merge-configs initContainer:
@@ -20,7 +21,17 @@ stringData:
2021
# each backend gets its own jclouds.credential and never another backend's.
2122
# Local backends (filesystem/transient) need no secret file; their placeholder
2223
# jclouds.identity/credential come from the ConfigMap.
23-
{{- $hasClientAuth := and .Values.config.auth.identity .Values.config.auth.secret }}
24+
{{- . }}
25+
{{- end }}
26+
27+
{{- /*
28+
The stringData properties, captured so the key above is emitted only when non-empty
29+
(with every credential coming from an existingSecret, or auth disabled, a bare
30+
`stringData:` would render as null). Client auth from config.auth.existingSecret is
31+
mounted at /auth-secret and merged by the initContainer instead of landing here.
32+
*/}}
33+
{{- define "s3proxy.secret.stringData" -}}
34+
{{- $hasClientAuth := and .Values.config.auth.identity .Values.config.auth.secret (not .Values.config.auth.existingSecret) }}
2435
{{- $inlineKeystorePassword := and .Values.config.tls.enabled .Values.config.tls.keystorePassword.value (not .Values.config.tls.keystorePassword.existingSecret) }}
2536
{{- if or $hasClientAuth $inlineKeystorePassword }}
2637
secret-common.properties: |
@@ -71,3 +82,4 @@ stringData:
7182
# Rackspace Cloud Files backend credential
7283
jclouds.credential={{ .Values.config.backends.rackspaceCloudfiles.apiKey.value }}
7384
{{- end }}
85+
{{- end }}

‎charts/s3proxy/values.yaml‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,16 @@ config:
122122
auth:
123123
# -- Authorization type (none, aws-v2, aws-v4, aws-v2-or-v4)
124124
type: "aws-v4"
125-
# -- S3 Access Key ID for client authentication
125+
# -- S3 Access Key ID for client authentication, stored in the chart-owned Secret. Ignored when `existingSecret` is set.
126126
identity: ""
127-
# -- S3 Secret Access Key for client authentication
127+
# -- S3 Secret Access Key for client authentication, stored in the chart-owned Secret. Ignored when `existingSecret` is set.
128128
secret: ""
129+
# -- Name of an existing Secret holding both client authentication credentials (see `identityKey`/`secretKey`). Takes precedence over `identity`/`secret`, which are otherwise stored in plaintext in the chart-owned Secret; prefer this when the values file lives in Git.
130+
existingSecret: ""
131+
# -- Key within `existingSecret` that holds the S3 Access Key ID
132+
identityKey: "accessKeyId"
133+
# -- Key within `existingSecret` that holds the S3 Secret Access Key
134+
secretKey: "secretAccessKey"
129135

130136
tls:
131137
# -- Enable native in-pod HTTPS (S3Proxy `secure-endpoint`). When enabled, S3Proxy serves HTTPS only on `service.targetPort` (the plaintext endpoint is not bound), so TLS is terminated in the pod rather than at the ingress. Requires a PKCS12 (or JKS) keystore and its password. `tcpSocket` health probes are unaffected (they do not perform a TLS handshake).
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Functional-test values: client auth sourced from a pre-existing Secret
2+
# (config.auth.existingSecret, default identityKey/secretKey) on a self-contained
3+
# filesystem backend. The workflow creates the Secret with the credentials the smoke
4+
# test signs with.
5+
config:
6+
auth:
7+
type: aws-v4
8+
existingSecret: s3proxy-auth
9+
backends:
10+
filesystem:
11+
enabled: true
12+
nio2: true
13+
basedir: /data/s3proxy
14+
persistence:
15+
enabled: true
16+
size: 1Gi
17+
resources:
18+
requests:
19+
cpu: 100m
20+
memory: 256Mi

0 commit comments

Comments
 (0)