feat(auth): support per-deploy login password key override
Multi-replica deployments need every Pod/container to share one RSA private key, otherwise public keys handed to the browser may not match the key that decrypts the resulting ciphertext. Introduce a `*.local.yaml` override layer that ops-config and tenant-config both load on top of the base config, ship example overrides plus compose/k3s wiring, and tolerate PEM bodies that arrive folded or escaped from Secrets.
This commit is contained in:
@@ -36,11 +36,22 @@ sudo k3s ctr images import images.tar
|
||||
- `SCHEDULER_INTERNAL_METRICS_TOKEN`
|
||||
- `BROWSER_FETCH_TOKEN`
|
||||
- `POSTGRES_PASSWORD` / `RABBITMQ_DEFAULT_PASS` / `MINIO_ROOT_*`
|
||||
- `config.local.yaml` 里的 `auth.password_cipher.private_key_pem`
|
||||
- `ops-config.local.yaml` 里的 `auth.password_cipher.private_key_pem`
|
||||
- `config/config.yaml` 里的 LLM / SiliconFlow API key
|
||||
- `config.local.yaml` 里对应的数据库、RabbitMQ、MinIO、JWT 配置
|
||||
|
||||
注意:应用运行时通过 `pgbouncer` / `monitoring-pgbouncer` 访问数据库;`migrate` 任务仍然直连 `postgres` / `monitoring-postgres`。数据库密码统一来自 `POSTGRES_PASSWORD` secret,应用配置和 PgBouncer 都会跟随这个 secret。
|
||||
|
||||
登录密码加密使用 RSA-OAEP-SHA256。多 Pod 部署时,同一类服务的所有副本必须读取同一把私钥和同一个 `key_id`,否则某个 Pod 下发的公钥对应密文可能被另一个 Pod 解不开。建议租户端和 ops 端分别生成不同私钥:
|
||||
|
||||
```bash
|
||||
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out login-password-rsa.pem
|
||||
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out ops-login-password-rsa.pem
|
||||
```
|
||||
|
||||
然后把完整 PEM 分别粘贴到 `deploy/k3s/secrets.yaml` 的 `config.local.yaml` 和 `ops-config.local.yaml`。
|
||||
|
||||
## 3. 部署
|
||||
|
||||
```bash
|
||||
|
||||
@@ -556,6 +556,11 @@ spec:
|
||||
items:
|
||||
- key: ops-config.yaml
|
||||
path: ops-config.yaml
|
||||
- secret:
|
||||
name: geo-rankly-app-secret
|
||||
items:
|
||||
- key: ops-config.local.yaml
|
||||
path: ops-config.local.yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
server:
|
||||
port: 8080
|
||||
mode: release
|
||||
# 生产环境请配置为真实前端域名,例如 https://app.example.com。
|
||||
# 留空时沿用开发环境 CORS 放开策略。
|
||||
allowed_origins: []
|
||||
security_headers:
|
||||
enabled: true
|
||||
trusted_proxies:
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
@@ -30,6 +35,47 @@ monitoring_database:
|
||||
|
||||
rabbitmq:
|
||||
url: amqp://geo:geo_dev@rabbitmq:5672/geo
|
||||
monitor_result_exchange: monitor.result
|
||||
monitor_result_routing_key: monitor.result.ingest
|
||||
monitor_result_queue: monitor.result.ingest
|
||||
monitor_result_dlx: monitor.result.dlx
|
||||
monitor_result_dlq: monitor.result.ingest.dlq
|
||||
monitor_result_dlq_routing_key: monitor.result.ingest.dlq
|
||||
monitor_projection_exchange: monitor.projection
|
||||
monitor_projection_routing_key: monitor.projection.rebuild
|
||||
monitor_projection_queue: monitor.projection.rebuild
|
||||
monitor_projection_dlx: monitor.projection.dlx
|
||||
monitor_projection_dlq: monitor.projection.rebuild.dlq
|
||||
monitor_projection_dlq_routing_key: monitor.projection.rebuild.dlq
|
||||
generation_exchange: generation.task
|
||||
generation_routing_key: generation.task.run
|
||||
generation_queue: generation.task.run
|
||||
generation_dlx: generation.task.dlx
|
||||
generation_dlq: generation.task.run.dlq
|
||||
generation_dlq_routing_key: generation.task.run.dlq
|
||||
generation_event_exchange: generation.event
|
||||
desktop_task_event_exchange: desktop.task.event
|
||||
desktop_dispatch_exchange: desktop.task.dispatch
|
||||
desktop_dispatch_publish_prefix: publish
|
||||
desktop_dispatch_monitor_prefix: monitor
|
||||
desktop_account_health_exchange: desktop.account.health
|
||||
desktop_account_health_routing_key: desktop.account.health.report
|
||||
desktop_account_health_queue: desktop.account.health.report
|
||||
desktop_account_health_dlx: desktop.account.health.dlx
|
||||
desktop_account_health_dlq: desktop.account.health.report.dlq
|
||||
desktop_account_health_dlq_routing_key: desktop.account.health.report.dlq
|
||||
template_assist_exchange: template.assist
|
||||
template_assist_routing_key: template.assist.run
|
||||
template_assist_queue: template.assist.run
|
||||
template_assist_dlx: template.assist.dlx
|
||||
template_assist_dlq: template.assist.run.dlq
|
||||
template_assist_dlq_routing_key: template.assist.run.dlq
|
||||
kol_assist_exchange: kol.assist
|
||||
kol_assist_routing_key: kol.assist.run
|
||||
kol_assist_queue: kol.assist.run
|
||||
kol_assist_dlx: kol.assist.dlx
|
||||
kol_assist_dlq: kol.assist.run.dlq
|
||||
kol_assist_dlq_routing_key: kol.assist.run.dlq
|
||||
compliance_review_exchange: compliance.review
|
||||
compliance_review_routing_key: compliance.review.run
|
||||
compliance_review_queue: compliance.review.run
|
||||
@@ -53,6 +99,9 @@ monitoring_workers:
|
||||
result_ingest_concurrency: 4
|
||||
projection_rebuild_concurrency: 2
|
||||
|
||||
monitoring_dispatch:
|
||||
desktop_tasks_rollout_percentage: 5
|
||||
|
||||
membership:
|
||||
default_plan_code: free
|
||||
plans:
|
||||
@@ -96,7 +145,6 @@ brand_library:
|
||||
max_keywords: 5
|
||||
max_questions_per_keyword: 5
|
||||
|
||||
|
||||
redis:
|
||||
addr: redis:6379
|
||||
db: 0
|
||||
@@ -126,6 +174,16 @@ jwt:
|
||||
access_ttl: 15m
|
||||
refresh_ttl: 720h
|
||||
|
||||
auth:
|
||||
login_guard:
|
||||
enabled: true
|
||||
password_cipher:
|
||||
# 留空 private_key_pem 时会在单进程内生成临时密钥;生产多 Pod 请在
|
||||
# geo-rankly-app-secret/config.local.yaml 中配置同一把私钥。
|
||||
enabled: true
|
||||
key_id: login-password-rsa-oaep-v1
|
||||
private_key_pem: ""
|
||||
|
||||
log:
|
||||
level: info,warn,error
|
||||
format: json
|
||||
@@ -182,14 +240,16 @@ browser_fetch:
|
||||
enabled: true
|
||||
provider: lightpanda
|
||||
service_url: http://browser-fetch:8082
|
||||
token: dev-browser-fetch-token
|
||||
queue_size: 64
|
||||
worker_concurrency: 2
|
||||
worker_concurrency: 3
|
||||
request_timeout: 45s
|
||||
cache_ttl: 6h
|
||||
allowed_domains:
|
||||
- zhuanlan.zhihu.com
|
||||
- zhihu.com
|
||||
- baidu.com
|
||||
- weixin.sogou.com
|
||||
trigger_status:
|
||||
- 403
|
||||
- 429
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
server:
|
||||
port: 8090
|
||||
mode: release
|
||||
# 生产环境请配置为真实运维后台域名,例如 https://ops.example.com。
|
||||
# 留空时沿用开发环境 CORS 放开策略。
|
||||
allowed_origins: []
|
||||
security_headers:
|
||||
enabled: true
|
||||
trusted_proxies:
|
||||
- 127.0.0.1
|
||||
- ::1
|
||||
@@ -43,6 +48,14 @@ jwt:
|
||||
secret: "geo-ops-15645415841"
|
||||
access_ttl: 8h
|
||||
|
||||
auth:
|
||||
password_cipher:
|
||||
# 留空 private_key_pem 时会在单进程内生成临时密钥;生产多 Pod 请在
|
||||
# geo-rankly-app-secret/ops-config.local.yaml 中配置同一把私钥。
|
||||
enabled: true
|
||||
key_id: ops-password-rsa-oaep-v1
|
||||
private_key_pem: ""
|
||||
|
||||
default_admin:
|
||||
username: admin
|
||||
display_name: system-admin
|
||||
|
||||
@@ -35,3 +35,25 @@ stringData:
|
||||
|
||||
browser_fetch:
|
||||
token: ${BROWSER_FETCH_TOKEN:geo-browser-fetch-change-me}
|
||||
|
||||
auth:
|
||||
password_cipher:
|
||||
enabled: true
|
||||
key_id: login-password-rsa-oaep-v1
|
||||
# 多 Pod 必须使用同一把私钥;上线前用 `openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048`
|
||||
# 生成后粘贴完整 PEM。不要把生产私钥提交到代码仓库。
|
||||
private_key_pem: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
REPLACE_WITH_TENANT_LOGIN_PASSWORD_RSA_PRIVATE_KEY
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
ops-config.local.yaml: |
|
||||
auth:
|
||||
password_cipher:
|
||||
enabled: true
|
||||
key_id: ops-password-rsa-oaep-v1
|
||||
# 建议与租户端使用不同私钥;所有 ops-api Pod 必须挂载同一份 Secret。
|
||||
private_key_pem: |
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
REPLACE_WITH_OPS_LOGIN_PASSWORD_RSA_PRIVATE_KEY
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Reference in New Issue
Block a user