mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): add direct Vault KV worker secret custody
This commit is contained in:
@@ -1032,6 +1032,22 @@ Kubernetes API permission. Version-pinned SecretRefs use a different hash and
|
||||
remain immutable by policy; retain their files until referenced Run/Artifact
|
||||
retention has completed.
|
||||
|
||||
For deployments that require direct external custody, use the optional
|
||||
`vault-kv-worker-secret` overlay instead of projecting value files:
|
||||
|
||||
```bash
|
||||
kubectl kustomize \
|
||||
deploy/kubernetes/ql3-cluster/vault-kv-worker-secret >/dev/null
|
||||
```
|
||||
|
||||
That overlay mounts only a private Vault CA and a short-lived, orphan,
|
||||
non-renewable read token. The adapter revalidates the token and fetches exact
|
||||
digest-derived KV v2 paths over TLS 1.3 for every authorized delivery; it has no
|
||||
cache, watcher, renewal loop or fallback to `mounted-files`. Follow the
|
||||
overlay's README for the exact policy, payload and token-rotation contract.
|
||||
External Vault HA, seal custody, audit devices, backup and disaster recovery
|
||||
remain deployment-specific gates.
|
||||
|
||||
Create a distinct migration Secret:
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Vault KV v2 Worker Secret custody
|
||||
|
||||
This overlay replaces the base `mounted-files` value projection with direct,
|
||||
TLS 1.3 Vault KV v2 resolution. The control Pods mount only the private Vault
|
||||
CA and one short-lived read token; Secret values and opaque Legacy Env bundles
|
||||
remain in Vault and are fetched only after the durable Worker delivery authority
|
||||
has been validated.
|
||||
|
||||
The exact Vault policy is read-only:
|
||||
|
||||
```hcl
|
||||
path "worker-secrets/data/values/production/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "auth/token/lookup-self" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
```
|
||||
|
||||
Issue an orphan, non-renewable service token with only that policy and a TTL no
|
||||
greater than 15 minutes. Rotate the projected `token` atomically before expiry;
|
||||
the adapter rereads and revalidates it for every authorized resolution. A Vault
|
||||
Agent or external Secret operator may own this projection, but must not project
|
||||
the actual Worker Secret values.
|
||||
|
||||
Store each value at
|
||||
`worker-secrets/data/values/production/<sha256(canonical SecretRef)>` with this
|
||||
exact KV payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"secretRefDigest": "<same 64-hex path key>",
|
||||
"encoding": "base64",
|
||||
"value": "<canonical base64 bytes>"
|
||||
}
|
||||
```
|
||||
|
||||
Create the two private Kubernetes Secret objects from
|
||||
`credentials.example.yaml` through the deployment authority, then render:
|
||||
|
||||
```sh
|
||||
kubectl kustomize deploy/kubernetes/ql3-cluster/vault-kv-worker-secret
|
||||
```
|
||||
|
||||
The overlay intentionally does not create a NetworkPolicy because the base
|
||||
control-plane deployment has no universal egress policy and external Vault
|
||||
topologies differ. If the namespace is default-deny, explicitly allow DNS,
|
||||
PostgreSQL, the artifact store and TCP 8200 only to the reviewed Vault identity.
|
||||
@@ -0,0 +1,20 @@
|
||||
# Create these objects through the deployment's Secret authority; do not commit
|
||||
# real CA or token material. The Vault token must be an orphan, non-renewable
|
||||
# service token with only ql3-worker-secret-read and at most a 15-minute TTL.
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ql3-cluster-worker-vault-trust
|
||||
namespace: qinglong3-system
|
||||
type: Opaque
|
||||
stringData:
|
||||
ca.pem: REPLACE_WITH_PRIVATE_VAULT_CA_PEM
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: ql3-cluster-worker-vault-auth
|
||||
namespace: qinglong3-system
|
||||
type: Opaque
|
||||
stringData:
|
||||
token: REPLACE_WITH_SHORT_LIVED_ORPHAN_VAULT_TOKEN
|
||||
@@ -0,0 +1,58 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ql3-cluster-control
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: cluster-control
|
||||
env:
|
||||
- name: QL3_WORKER_SECRET_PROVIDER
|
||||
value: vault-kv-v2
|
||||
- name: QL3_WORKER_SECRET_ROOT_DIRECTORY
|
||||
$patch: delete
|
||||
- name: QL3_WORKER_SECRET_VAULT_ENDPOINT
|
||||
value: https://vault.vault.svc.cluster.local:8200
|
||||
- name: QL3_WORKER_SECRET_VAULT_CA_FILE
|
||||
value: /var/run/secrets/qinglong3/worker-vault-trust/ca.pem
|
||||
- name: QL3_WORKER_SECRET_VAULT_TOKEN_FILE
|
||||
value: /var/run/secrets/qinglong3/worker-vault-auth/token
|
||||
- name: QL3_WORKER_SECRET_VAULT_KV_MOUNT
|
||||
value: worker-secrets
|
||||
- name: QL3_WORKER_SECRET_VAULT_PATH_PREFIX
|
||||
value: values/production
|
||||
- name: QL3_WORKER_SECRET_VAULT_EXPECTED_POLICY
|
||||
value: ql3-worker-secret-read
|
||||
- name: QL3_WORKER_SECRET_VAULT_MAX_TOKEN_TTL_SECONDS
|
||||
value: '900'
|
||||
- name: QL3_WORKER_SECRET_VAULT_REQUEST_TIMEOUT_MS
|
||||
value: '5000'
|
||||
- name: QL3_WORKER_SECRET_VAULT_MAX_CONCURRENCY
|
||||
value: '4'
|
||||
volumeMounts:
|
||||
- name: worker-secret-values
|
||||
$patch: delete
|
||||
- name: worker-vault-trust
|
||||
mountPath: /var/run/secrets/qinglong3/worker-vault-trust
|
||||
readOnly: true
|
||||
- name: worker-vault-auth
|
||||
mountPath: /var/run/secrets/qinglong3/worker-vault-auth
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: worker-secret-values
|
||||
$patch: delete
|
||||
- name: worker-vault-trust
|
||||
secret:
|
||||
secretName: ql3-cluster-worker-vault-trust
|
||||
defaultMode: 292
|
||||
items:
|
||||
- key: ca.pem
|
||||
path: ca.pem
|
||||
- name: worker-vault-auth
|
||||
secret:
|
||||
secretName: ql3-cluster-worker-vault-auth
|
||||
defaultMode: 288
|
||||
items:
|
||||
- key: token
|
||||
path: token
|
||||
@@ -0,0 +1,8 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- ../base
|
||||
|
||||
patches:
|
||||
- path: deployment-patch.yaml
|
||||
Reference in New Issue
Block a user