- Introduced guild charters for Scanner Deno, PHP, Ruby, Native, WebService, Java, Surface.Env, Surface.FS, Surface.Secrets, Surface.Validation, UI, Zastava Observer, Zastava Webhook, Zastava Core, and Plugin Platform. - Each charter outlines the mission, scope, required reading, and working agreements for the respective guilds. - Created task boards for Surface.Env, Surface.FS, Surface.Secrets, Surface.Validation, and Zastava components to track progress and dependencies. - Ensured all documents emphasize determinism, offline readiness, security, and integration with shared Surface libraries.
5.1 KiB
Surface.Secrets Design (Epic: SURFACE-SHARING)
Status: Draft v1.0 — aligns with tasks
SURFACE-SECRETS-01..06,SCANNER-SECRETS-01..03,ZASTAVA-SECRETS-01..02,OPS-SECRETS-01..02.Audience: Scanner/Zastava engineers, Security Guild, DevOps/Ops teams.
1. Goals
Surface.Secrets standardises how Scanner, Zastava, Scheduler, and related services obtain credentials and sensitive material required for surface operations (registry pull secrets, CAS tokens, manifest signing keys). Key requirements:
- Consistent, pluggable providers (Kubernetes Secret, file, inline, future vaults).
- Deterministic lookup keyed by tenant/component to avoid accidental leakage.
- Integration with Surface.Env & Surface.Validation for configuration and pre-flight checks.
- Minimal in-memory exposure; secrets wrapped in secure handles with automatic disposal.
2. Secret Types
| Secret Type | Description | Example Consumers |
|---|---|---|
cas-access |
Credentials for RustFS/S3 object storage (access key/secret, session token). | Scanner Worker/WebService, Zastava Observer/Webhook |
registry |
Container registry auth (username/password or token). | Scanner Worker (pulling layers for SBOM) |
attestation |
DSSE signing key material, Rekor API tokens. | Scanner WebService (delegation), Attestor (future integration) |
tls |
Client TLS certificates for Surface.FS or other services. | Scanner Worker, Zastava Observer |
Additional secret types can be registered via ISurfaceSecretTypeRegistry.
3. Provider Model
public interface ISurfaceSecretProvider
{
ValueTask<SurfaceSecretHandle> GetAsync(SurfaceSecretRequest request, CancellationToken ct = default);
}
public sealed record SurfaceSecretRequest
(
string Tenant,
string Component, // e.g. "Scanner.Worker"
string SecretType, // e.g. "cas-access"
string? Name // optional override (e.g., "primary", "mirror-eu")
);
3.1 Built-in providers
- Kubernetes – Reads from
Secretobjects. Configuration:namespace: derived fromSCANNER_SURFACE_SECRETS_ROOTor component override.- Secret name format:
surface-{tenant}-{component}-{secretType}. - Supports key mapping (e.g.,
accessKey,secretKey,sessionToken).
- File – Loads JSON/YAML files from a directory (for offline kit, dev). File path derived from root + tenant/component.
- Inline – Accepts base64 encoded JSON from env (useful for tests).
3.2 Secret Handle
SurfaceSecretHandle exposes typed accessors (AsCredentials(), AsTlsCertificate()) and ensures sensitive data is cleared when disposed.
4. Configuration
Surface.Env supplies provider configuration (SecretsProviderConfiguration). Example:
{
"provider": "kubernetes",
"namespace": "stellaops-runtime",
"prefix": "surface-",
"fallbackProvider": "file",
"file": {
"root": "/etc/stellaops/secrets"
}
}
Fallback provider allows offline development (use file provider if K8s secret missing).
5. Validation
Surface.Validation supplies validators:
SecretProviderValidator– ensures provider ID is known; checks required configuration (namespace/root).SecretExistenceValidator– optional check verifying required secret types exist at startup (configurable list).SecretRotationValidator– warns when secrets are older than rotation window (uses metadata stored in provider).
Failures produce error codes (SURFACE_SECRET_PROVIDER_UNKNOWN, SURFACE_SECRET_MISSING, SURFACE_SECRET_STALE).
6. Security Considerations
- Secrets returned as
SecureString/byte arrays; never log values. - Kubernetes provider caches secrets in-memory with TTL (default 10 minutes) to reduce API calls; cache invalidated when
generationchanges. - File provider enforces permissions (
0600); rejects world-readable files. - Inline provider meant for tests only; flag
Surface:Secrets:AllowInlineenables it explicitly.
7. Offline & Air-Gap Support
- Offline kits include
offline/secrets/with encrypted archive plus manifest file enumerating secret metadata (tenant, component, type, checksum). - Import script decrypts archive using site-specific key and populates file provider root.
- Documented workflow lives in
ops/offline-kit/TASKS.mdand associated runbooks.
8. Observability
- Metrics:
surface_secrets_requests_total{provider,result}. - Logs: only log secret identifiers, never values.
- Traces:
surface.secrets.getspan showing provider latency.
9. Testing Strategy
- Unit tests per provider with fake backends.
- Integration tests in Scanner/Zastava verifying provider selection, fallback, and rotation.
- Security tests ensuring secrets aren’t leaked in logs or exceptions.
10. Future Enhancements
- Support for HashiCorp Vault / AWS Secrets Manager providers.
- Built-in DSSE signing key management for Attestor/Signer.
- Automatic rotation notifications via Notifier.
11. References
docs/modules/scanner/design/surface-env.mddocs/modules/scanner/design/surface-fs.mddocs/modules/scanner/design/surface-validation.mddocs/modules/airgap/airgap-mode.md