75 lines
4.1 KiB
Markdown
75 lines
4.1 KiB
Markdown
# Surface.Secrets provisioning playbook (OPS-SECRETS-01)
|
|
|
|
Audience: DevOps/Ops teams shipping Scanner/Zastava/Orchestrator bundles.
|
|
Scope: how to provision secrets for the `StellaOps.Scanner.Surface.Secrets` providers across Kubernetes, Docker Compose, and Offline Kit.
|
|
|
|
## Secret types (handles only)
|
|
- Registry pull creds (CAS / OCI / private feeds)
|
|
- CAS/attestation tokens
|
|
- TLS client certs for Surface.FS / RustFS (optional)
|
|
- Feature flag/token bundles used by Surface.Validation (non-sensitive payloads still go through handles)
|
|
|
|
All values are referenced via `secret://` handles inside service configs; plaintext never enters configs or SBOMs.
|
|
|
|
## Provider matrix
|
|
| Environment | Provider | Location | Notes |
|
|
| --- | --- | --- | --- |
|
|
| Kubernetes | `kubernetes` | Namespace-scoped `Secret` objects | Mount-free: providers read via API using service account; RBAC must allow `get/list` on the secret names. |
|
|
| Compose (connected) | `file` | Host-mounted path (e.g., `/etc/stellaops/secrets`) | Keep per-tenant subfolders; chmod 700 root; avoid embedding in images. |
|
|
| Airgap/Offline Kit | `file` | Unpacked bundle `surface-secrets/<tenant>/...` | Bundled as encrypted payloads; decrypt/unpack to the expected directory before first boot. |
|
|
| Tests | `inline` | Environment variables or minimal inline JSON | Only for unit/system tests; disable in prod (`SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false`). |
|
|
|
|
## Kubernetes workflow
|
|
1) Namespace: choose one per environment (e.g., `stellaops-prod`).
|
|
2) Secret layout: one K8s Secret per tenant+component to keep RBAC narrow.
|
|
```
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: scanner-secrets-default
|
|
namespace: stellaops-prod
|
|
stringData:
|
|
registry.json: |
|
|
{ "type": "registry", "name": "default", "username": "svc", "password": "********", "scopes": ["stella/*"] }
|
|
cas.json: |
|
|
{ "type": "cas-token", "name": "default", "token": "********" }
|
|
```
|
|
3) RBAC: service accounts for Scanner Worker/WebService and Zastava Observer/Webhook need `get/list` on these secrets.
|
|
4) Values: set in Helm via `surface.secrets.provider=kubernetes` and `surface.secrets.namespace=<ns>` (already templated in `values*.yaml`).
|
|
|
|
## Compose workflow
|
|
1) Create secrets directory (default `/etc/stellaops/secrets`).
|
|
2) Layout per schema (see `docs/modules/scanner/design/surface-secrets-schema.md`):
|
|
```
|
|
/etc/stellaops/secrets/
|
|
tenants/default/registry/default.json
|
|
tenants/default/cas/default.json
|
|
```
|
|
3) Set env in `.env` files:
|
|
```
|
|
SCANNER_SURFACE_SECRETS_PROVIDER=file
|
|
SCANNER_SURFACE_SECRETS_ROOT=/etc/stellaops/secrets
|
|
SCANNER_SURFACE_SECRETS_NAMESPACE=
|
|
SCANNER_SURFACE_SECRETS_ALLOW_INLINE=false
|
|
ZASTAVA_SURFACE_SECRETS_PROVIDER=${SCANNER_SURFACE_SECRETS_PROVIDER}
|
|
ZASTAVA_SURFACE_SECRETS_ROOT=${SCANNER_SURFACE_SECRETS_ROOT}
|
|
```
|
|
4) Ensure docker-compose mounts the secrets path read-only to the services that need it. Use `SURFACE_SECRETS_HOST_PATH` to point at the decrypted bundle on the host (defaults to `./offline/surface-secrets` in the Compose profiles).
|
|
|
|
## Offline Kit workflow
|
|
- The offline kit already ships encrypted `surface-secrets` bundles (see `docs/24_OFFLINE_KIT.md`).
|
|
- Operators must: (a) decrypt using the provided key, (b) place contents under `/etc/stellaops/secrets` (or override `*_SURFACE_SECRETS_ROOT`), (c) keep permissions 700/600.
|
|
- Set `*_SURFACE_SECRETS_PROVIDER=file` and root path envs as in Compose; Kubernetes provider is not available offline.
|
|
|
|
## Validation & observability
|
|
- Surface.Validation will fail readiness if required secrets are missing or malformed.
|
|
- Metrics/Logs: look for `surface.secrets.*` issue codes; readiness should fail on `Error` severities.
|
|
- For CI smoke: run service with `SURFACE_SECRETS_ALLOW_INLINE=true` and inject test secrets via env for deterministic integration tests.
|
|
|
|
## Quick checklist
|
|
- [ ] Provider selected per environment (`kubernetes`/`file`/`inline`)
|
|
- [ ] Secrets directory or namespace populated per schema
|
|
- [ ] RBAC (K8s) or file permissions (Compose/offline) locked down
|
|
- [ ] Env variables set for both Scanner (`SCANNER_*`) and Zastava (`ZASTAVA_*` prefixes)
|
|
- [ ] Readiness wired to Surface.Validation so missing secrets block rollout
|