Skip to content

Commit 77e6a74

Browse files
authored
release(aisix-cp): 0.3.0 (#308)
1 parent 36e27a4 commit 77e6a74

6 files changed

Lines changed: 90 additions & 3 deletions

File tree

charts/aisix-cp/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apiVersion: v2
22
name: aisix-cp
33
description: Helm chart for AISIX control plane (cp-api, dp-manager, dashboard)
44
type: application
5-
version: 0.2.0
6-
appVersion: "0.2.0"
5+
version: 0.3.0
6+
appVersion: "0.3.0"
77

88
maintainers:
99
- name: API7

charts/aisix-cp/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# aisix-cp
22

3-
![Version: 0.2.0](https://img.shields.io/badge/Version-0.2.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.2.0](https://img.shields.io/badge/AppVersion-0.2.0-informational?style=flat-square)
3+
![Version: 0.3.0](https://img.shields.io/badge/Version-0.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square)
44

55
Helm chart for AISIX control plane (cp-api, dp-manager, dashboard)
66

@@ -98,6 +98,10 @@ Helm chart for AISIX control plane (cp-api, dp-manager, dashboard)
9898
| serviceAccount.annotations | object | `{}` | |
9999
| serviceAccount.create | bool | `true` | |
100100
| serviceAccount.name | string | `""` | |
101+
| twoDSN.enabled | bool | `false` | |
102+
| twoDSN.existingSecret | string | `""` | |
103+
| twoDSN.existingSecretKey | string | `"serving-password"` | |
104+
| twoDSN.servingPassword | string | `""` | |
101105
| ui.affinity | object | `{}` | |
102106
| ui.defaultLocale | string | `"en"` | |
103107
| ui.extraEnvVars | list | `[]` | |

charts/aisix-cp/templates/_helpers.tpl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,37 @@ Uses $(PGPASSWORD) env var substitution for runtime secret injection.
118118
postgres://{{ include "aisix-cp.pgUser" . }}:$(PGPASSWORD)@{{ include "aisix-cp.pgHost" . }}:{{ include "aisix-cp.pgPort" . }}/{{ include "aisix-cp.pgDatabase" . }}?sslmode={{ include "aisix-cp.pgSSLMode" . }}
119119
{{- end }}
120120

121+
{{/*
122+
Serving database URL for two-DSN mode: same host/port/db, but connecting
123+
as the non-superuser cp_api_app role. Uses $(SERVING_PGPASSWORD) env-var
124+
substitution for runtime secret injection.
125+
*/}}
126+
{{- define "aisix-cp.servingDatabaseURL" -}}
127+
postgres://cp_api_app:$(SERVING_PGPASSWORD)@{{ include "aisix-cp.pgHost" . }}:{{ include "aisix-cp.pgPort" . }}/{{ include "aisix-cp.pgDatabase" . }}?sslmode={{ include "aisix-cp.pgSSLMode" . }}
128+
{{- end }}
129+
130+
{{/*
131+
Name of the Secret holding the cp_api_app serving-role password.
132+
*/}}
133+
{{- define "aisix-cp.servingPasswordSecretName" -}}
134+
{{- if .Values.twoDSN.existingSecret }}
135+
{{- .Values.twoDSN.existingSecret }}
136+
{{- else }}
137+
{{- include "aisix-cp.secretName" . }}
138+
{{- end }}
139+
{{- end }}
140+
141+
{{/*
142+
Secret key holding the cp_api_app serving-role password.
143+
*/}}
144+
{{- define "aisix-cp.servingPasswordSecretKey" -}}
145+
{{- if .Values.twoDSN.existingSecret }}
146+
{{- .Values.twoDSN.existingSecretKey | default "serving-password" }}
147+
{{- else }}
148+
{{- "serving-password" }}
149+
{{- end }}
150+
{{- end }}
151+
121152
{{/*
122153
Secret name for aisix-cp secrets.
123154
*/}}

charts/aisix-cp/templates/api-deployment.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,24 @@ spec:
4242
secretKeyRef:
4343
name: {{ include "aisix-cp.pgSecretName" . }}
4444
key: {{ include "aisix-cp.pgPasswordSecretKey" . }}
45+
{{- if .Values.twoDSN.enabled }}
46+
- name: SERVING_PGPASSWORD
47+
valueFrom:
48+
secretKeyRef:
49+
name: {{ include "aisix-cp.servingPasswordSecretName" . }}
50+
key: {{ include "aisix-cp.servingPasswordSecretKey" . }}
51+
{{- end }}
4552
- name: AISIX_CLOUD_LISTEN
4653
value: ":8080"
54+
{{- if .Values.twoDSN.enabled }}
55+
- name: AISIX_CLOUD_ADMIN_DATABASE_URL
56+
value: {{ include "aisix-cp.databaseURL" . }}
57+
- name: AISIX_CLOUD_DATABASE_URL
58+
value: {{ include "aisix-cp.servingDatabaseURL" . }}
59+
{{- else }}
4760
- name: AISIX_CLOUD_DATABASE_URL
4861
value: {{ include "aisix-cp.databaseURL" . }}
62+
{{- end }}
4963
- name: AISIX_CLOUD_PUBLIC_BASE_URL
5064
value: {{ .Values.api.publicBaseURL | quote }}
5165
- name: AISIX_CLOUD_MASTER_KEY

charts/aisix-cp/templates/secret.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ password. Skipped when an existingSecret injects the credentials.
2323
{{- end }}
2424
{{- end }}
2525
{{- end }}
26+
{{/*
27+
Two-DSN serving-role password: when chart-managed (no existingSecret),
28+
hold it to the same standard as the app secrets above so cp_api_app can't
29+
be provisioned with an empty/placeholder login.
30+
*/}}
31+
{{- if and .Values.twoDSN.enabled (not .Values.twoDSN.existingSecret) }}
32+
{{- if or (eq .Values.twoDSN.servingPassword "") (hasPrefix "CHANGE_ME" .Values.twoDSN.servingPassword) }}
33+
{{- fail "twoDSN.servingPassword must be set to a real password when twoDSN.enabled=true (generate a URL-safe one with: openssl rand -hex 24) — or inject it via twoDSN.existingSecret." }}
34+
{{- end }}
35+
{{- end }}
2636
apiVersion: v1
2737
kind: Secret
2838
metadata:
@@ -35,3 +45,6 @@ type: Opaque
3545
data:
3646
master-key: {{ .Values.secrets.masterKey | b64enc }}
3747
better-auth-secret: {{ .Values.secrets.betterAuthSecret | b64enc }}
48+
{{- if and .Values.twoDSN.enabled (not .Values.twoDSN.existingSecret) }}
49+
serving-password: {{ .Values.twoDSN.servingPassword | b64enc }}
50+
{{- end }}

charts/aisix-cp/values.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,28 @@ externalDatabase:
191191
## If existingSecret is empty, this password is used directly.
192192
password: ""
193193
sslmode: disable
194+
195+
## @section Two-DSN tenant isolation (SaaS / multi-tenant only)
196+
## When enabled, cp-api opens TWO pools against the same database:
197+
## - an admin pool on the privileged DSN above (builtin postgres or the
198+
## externalDatabase user) that runs migrations + the cross-tenant paths;
199+
## - a serving pool that connects AS the non-superuser `cp_api_app` role,
200+
## so every tenant query is Row-Level-Security filtered and a path that
201+
## forgets to scope fails closed (zero rows) instead of leaking.
202+
## cp-api provisions cp_api_app's LOGIN + password (from servingPassword)
203+
## on the admin pool at boot — you do NOT pre-create the role.
204+
##
205+
## Leave DISABLED for single-tenant / private (OP) deployments: there every
206+
## org is one trust domain, RLS is inert, and the single privileged DSN
207+
## handles everything (the current default behavior). See the internal
208+
## docs/rls-architecture.md for the full model.
209+
twoDSN:
210+
enabled: false
211+
## Password cp-api assigns to the cp_api_app serving role and uses in the
212+
## serving DSN. Required when enabled unless existingSecret is set.
213+
## Use a URL-safe value (no + / =): it is embedded in a postgres:// DSN.
214+
servingPassword: ""
215+
## Optionally source the serving password from an existing Secret instead
216+
## of servingPassword above. Key defaults to "serving-password".
217+
existingSecret: ""
218+
existingSecretKey: "serving-password"

0 commit comments

Comments
 (0)