Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.26.4"
go-version: "1.26.5"
- name: make test
run: make test TEST_WAIT_SHORT=20s TEST_WAIT_LONG=80s
- name: Run Proto Generation
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: "1.26.4"
go-version: "1.26.5"
- name: Install zip
uses: montudor/action-zip@v1
- name: Build standalone binaries
Expand Down
9 changes: 9 additions & 0 deletions .govulncheck-ignore.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@
- id: GO-2026-4883
module: github.com/docker/docker
reason: "No fix available — Moby off-by-one error in plugin privilege validation. Pulled in only via testcontainers-go from test/env/components.go (test infra); not linked into product binaries."
- id: GO-2026-5617
module: github.com/docker/docker
reason: "No fix available — Moby docker cp race condition allows bind mount redirection to host path. Pulled in only via testcontainers-go from test/env/components.go (test infra); not linked into product binaries."
- id: GO-2026-5668
module: github.com/docker/docker
reason: "No fix available — Moby docker cp race condition allows creation of arbitrary empty files on the host via symlink swap. Pulled in only via testcontainers-go from test/env/components.go (test infra); not linked into product binaries."
- id: GO-2026-5746
module: github.com/docker/docker
reason: "No fix available — Moby PUT /containers/{id}/archive executes container binary on the host. Pulled in only via testcontainers-go from test/env/components.go (test infra); not linked into product binaries."
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.26.4 AS builder
FROM golang:1.26.5 AS builder
ARG GIT_COMMIT='not set'
ARG GIT_TAG=development
ENV GIT_COMMIT=$GIT_COMMIT
Expand Down
2 changes: 1 addition & 1 deletion deploy/chorus/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Helm chart for Chorus S3 management software.
keywords: ["S3", "Backup", "Replication", "Migration"]
home: https://github.com/clyso/chorus
type: application
version: 0.2.0
version: 0.3.0
appVersion: "v0.6.1"
dependencies:
- name: redis
Expand Down
27 changes: 26 additions & 1 deletion deploy/chorus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ storage:

### Credentials

Stored in Kubernetes Secret, separate from storage config:
Stored in Kubernetes Secrets, separate from storage config. Worker and proxy
use different credential models:

**Worker** (`credentials`) - one credential per user per storage:

```yaml
credentials:
Expand All @@ -56,6 +59,28 @@ credentials:
secretAccessKey: "..."
```

**Proxy** (`proxyCredentials`) - multiple credentials per user, keyed by alias
(`user -> alias -> credential`). The proxy authenticates S3 clients by alias
access key and re-signs forwarded requests with the target storage's credential
of the same alias:

```yaml
proxyCredentials:
storages:
main:
user1:
laptop:
accessKeyID: "..."
secretAccessKey: "..."
ci:
accessKeyID: "..."
secretAccessKey: "..."
```

Required when the proxy is enabled with `proxy.config.auth.useStorage`. Routing
and replication policies stay keyed by user; aliases only affect proxy
authentication and request signing.

### Dynamic Credentials

Manage credentials via API instead of config files:
Expand Down
15 changes: 14 additions & 1 deletion deploy/chorus/examples/values-dynamic-credentials.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,25 @@ credentials:
accessKeyID: "AKIAIOSFODNN7EXAMPLE"
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

# Initial proxy credentials (user -> alias -> credential)
proxyCredentials:
storages:
main:
initial-admin:
default:
accessKeyID: "BKIAIOSFODNN7EXAMPLE"
secretAccessKey: "xJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

# After deployment, add more credentials via chorctl:
#
# Add S3 credentials:
# Add S3 worker credentials (used by the worker for replication):
# chorctl set-user --storage main --user new-user --type s3 \
# --access-key NEWAKEYID --secret-key NEWSECRETKEY
#
# Add S3 proxy alias credentials (accepted by the proxy s3 endpoint):
# chorctl set-user --storage main --user new-user --type s3 --alias laptop \
# --access-key ALIASKEYID --secret-key ALIASSECRETKEY
#
# Add Swift credentials:
# chorctl set-user --storage swift-main --user projectId123 --type swift \
# --swift-username myuser --swift-password mypassword \
Expand Down
15 changes: 15 additions & 0 deletions deploy/chorus/examples/values-external-redis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,28 @@ storage:
provider: Ceph
isSecure: true

# Worker credentials
credentials:
storages:
main:
user1:
accessKeyID: "AKIAIOSFODNN7EXAMPLE"
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

# Proxy credentials (user -> alias -> credential)
proxyCredentials:
storages:
main:
user1:
default:
accessKeyID: "BKIAIOSFODNN7EXAMPLE"
secretAccessKey: "xJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

proxy:
config:
auth:
useStorage: main

---
# Example with Redis Sentinel
# externalRedis:
Expand Down
31 changes: 29 additions & 2 deletions deploy/chorus/examples/values-s3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ storage:
isSecure: true
defaultRegion: eu-west-1

# Storage credentials (stored in Kubernetes Secret)
# Worker storage credentials (stored in Kubernetes Secret)
# One credential per user per storage, used by the worker for replication
credentials:
storages:
main:
Expand All @@ -42,13 +43,39 @@ credentials:
accessKeyID: "BKIAI44QH8DHBEXAMPLE"
secretAccessKey: "ke7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY"

# Proxy storage credentials (stored in a separate Kubernetes Secret)
# user -> alias -> credential: the proxy authenticates S3 clients by alias
# access key and re-signs forwarded requests with the target storage's
# credential of the same alias
proxyCredentials:
storages:
main:
admin:
default:
accessKeyID: "CKIAIOSFODNN7EXAMPLE"
secretAccessKey: "yJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
backup-service:
default:
accessKeyID: "CKIAI44QH8DHBEXAMPLE"
secretAccessKey: "le7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY"

follower:
admin:
default:
accessKeyID: "DKIAIOSFODNN7EXAMPLE"
secretAccessKey: "zJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
backup-service:
default:
accessKeyID: "DKIAI44QH8DHBEXAMPLE"
secretAccessKey: "me7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY"

# Proxy configuration
proxy:
enabled: true
replicas: 2
config:
auth:
# Use credentials from main storage for S3 proxy authentication
# Authenticate S3 clients against main storage proxy credentials
useStorage: main

# Worker configuration
Expand Down
23 changes: 16 additions & 7 deletions deploy/chorus/examples/values-swift.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ storage:
provider: Ceph
isSecure: true

# Credentials (stored in Kubernetes Secret)
# Worker credentials (stored in Kubernetes Secret)
credentials:
storages:
# Swift credentials - key must be OpenStack Project ID
Expand All @@ -53,18 +53,27 @@ credentials:
accessKeyID: "AKIAIOSFODNN7EXAMPLE"
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

# Proxy S3 credentials (stored in a separate Kubernetes Secret)
# user -> alias -> credential. Only needed for the S3 storage: for Swift the
# proxy does not perform authentication itself
proxyCredentials:
storages:
s3-backup:
swift-admin:
default:
accessKeyID: "BKIAIOSFODNN7EXAMPLE"
secretAccessKey: "xJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

# Proxy configuration
proxy:
enabled: true
replicas: 2
config:
auth:
# For Swift, you typically use custom credentials or disable auth
# since Swift handles its own authentication
custom:
swift-admin:
accessKeyID: "custom-access-key"
secretAccessKey: "custom-secret-key"
# S3 clients authenticate against the S3 storage proxy credentials.
# Swift requests are not authenticated by the proxy - Swift handles
# its own authentication
useStorage: s3-backup

# Worker configuration
worker:
Expand Down
20 changes: 20 additions & 0 deletions deploy/chorus/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ Credentials secret name
{{- end }}
{{- end }}

{{/*
Proxy credentials secret name
*/}}
{{- define "chorus.proxyCredentialsSecretName" -}}
{{- if .Values.existingProxyCredentialsSecret }}
{{- .Values.existingProxyCredentialsSecret }}
{{- else }}
{{- printf "%s-proxy-credentials" (include "chorus.fullname" .) }}
{{- end }}
{{- end }}

{{/*
Redis secret name
*/}}
Expand Down Expand Up @@ -121,6 +132,15 @@ true
{{- end }}
{{- end }}

{{/*
Check if proxy credentials secret should be created
*/}}
{{- define "chorus.createProxyCredentialsSecret" -}}
{{- if and (not .Values.existingProxyCredentialsSecret) .Values.proxyCredentials.storages }}
true
{{- end }}
{{- end }}

{{/*
Dynamic credentials secret name
*/}}
Expand Down
8 changes: 4 additions & 4 deletions deploy/chorus/templates/proxy/deployment-proxy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spec:
app.kubernetes.io/component: proxy
annotations:
checksum/config: {{ include (print $.Template.BasePath "/proxy/config.yaml") . | sha256sum }}
{{- if include "chorus.createCredentialsSecret" . }}
{{- if include "chorus.createProxyCredentialsSecret" . }}
checksum/secret: {{ include (print $.Template.BasePath "/secrets/secret.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.proxy.config.metrics.enabled }}
Expand Down Expand Up @@ -95,7 +95,7 @@ spec:
- name: config
mountPath: /bin/config/config.yaml
subPath: config.yaml
{{- if or .Values.existingCredentialsSecret (include "chorus.createCredentialsSecret" .) }}
{{- if or .Values.existingProxyCredentialsSecret (include "chorus.createProxyCredentialsSecret" .) }}
- name: credentials
mountPath: /bin/config/override.yaml
subPath: config.yaml
Expand All @@ -104,10 +104,10 @@ spec:
- name: config
configMap:
name: {{ include "chorus.fullname" . }}-proxy
{{- if or .Values.existingCredentialsSecret (include "chorus.createCredentialsSecret" .) }}
{{- if or .Values.existingProxyCredentialsSecret (include "chorus.createProxyCredentialsSecret" .) }}
- name: credentials
secret:
secretName: {{ include "chorus.credentialsSecretName" . }}
secretName: {{ include "chorus.proxyCredentialsSecretName" . }}
{{- end }}
{{- $nodeSelector := include "chorus.nodeSelector" (list .Values.proxy.nodeSelector .Values.global.nodeSelector) }}
{{- if $nodeSelector }}
Expand Down
24 changes: 23 additions & 1 deletion deploy/chorus/templates/secrets/secret.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- /* Storage credentials secret */}}
{{- /* Worker storage credentials secret (user -> credential) */}}
{{- if include "chorus.createCredentialsSecret" . }}
apiVersion: v1
kind: Secret
Expand All @@ -20,6 +20,28 @@ stringData:
{{- end }}
{{- end }}
---
{{- /* Proxy storage credentials secret (user -> alias -> credential) */}}
{{- if include "chorus.createProxyCredentialsSecret" . }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "chorus.proxyCredentialsSecretName" . }}
labels:
{{- include "chorus.labels" . | nindent 4 }}
type: Opaque
stringData:
config.yaml: |
{{- if .Values.proxyCredentials.storages }}
storage:
storages:
{{- range $storageName, $users := .Values.proxyCredentials.storages }}
{{ $storageName }}:
credentials:
{{- $users | toYaml | nindent 12 }}
{{- end }}
{{- end }}
{{- end }}
---
{{- /* Dynamic credentials master password secret */}}
{{- if include "chorus.createDynamicCredentialsSecret" . }}
apiVersion: v1
Expand Down
Loading
Loading