- Introduced AuthorityAdvisoryAiOptions and related classes for managing advisory AI configurations, including remote inference options and tenant-specific settings. - Added AuthorityApiLifecycleOptions to control API lifecycle settings, including legacy OAuth endpoint configurations. - Implemented validation and normalization methods for both advisory AI and API lifecycle options to ensure proper configuration. - Created AuthorityNotificationsOptions and its related classes for managing notification settings, including ack tokens, webhooks, and escalation options. - Developed IssuerDirectoryClient and related models for interacting with the issuer directory service, including caching mechanisms and HTTP client configurations. - Added support for dependency injection through ServiceCollectionExtensions for the Issuer Directory Client. - Updated project file to include necessary package references for the new Issuer Directory Client library.
		
			
				
	
	
		
			133 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
# 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
 | 
						||
 | 
						||
```csharp
 | 
						||
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
 | 
						||
 | 
						||
1. **Kubernetes** – Reads from `Secret` objects. Configuration:
 | 
						||
   - `namespace`: derived from `SCANNER_SURFACE_SECRETS_ROOT` or component override.
 | 
						||
   - Secret name format: `surface-{tenant}-{component}-{secretType}`.
 | 
						||
   - Supports key mapping (e.g., `accessKey`, `secretKey`, `sessionToken`).
 | 
						||
2. **File** – Loads JSON/YAML files from a directory (for offline kit, dev). File path derived from root + tenant/component.
 | 
						||
3. **Inline** – Accepts base64 encoded JSON from env (useful for tests).
 | 
						||
 | 
						||
### 3.2 Secret Handle
 | 
						||
 | 
						||
`SurfaceSecretHandle` exposes typed accessors (`AsBytes()`, `AsCredentials()`, `AsTlsCertificate()`) and ensures sensitive data is cleared when disposed. Consumers that expect string material attempt UTF-8 decoding first and, if decoding fails, fall back to returning a base64 representation rather than dropping binary content.
 | 
						||
 | 
						||
### 3.3 Environment & Config References
 | 
						||
 | 
						||
Runtime configuration can reference secrets using the URI scheme `secret://{secretType}/{name?}`. Example:
 | 
						||
 | 
						||
```
 | 
						||
SCANNER_ENTRYTRACE_ENV__0=API_TOKEN=secret://registry/primary
 | 
						||
SCANNER_ENTRYTRACE_ENV__1=TLS_CERT=secret://tls/edge-gateway
 | 
						||
```
 | 
						||
 | 
						||
During scan execution, Scanner.Worker resolves each placeholder via `ISurfaceSecretProvider` before invoking analyzers, replacing the environment variable with the resolved value (base64 when non-text). Missing secrets raise `SurfaceSecretNotFoundException` and are surfaced as warnings without hard-failing the scan.
 | 
						||
 | 
						||
## 4. Configuration
 | 
						||
 | 
						||
Surface.Env supplies provider configuration (`SecretsProviderConfiguration`). Example:
 | 
						||
 | 
						||
```json
 | 
						||
{
 | 
						||
  "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 `generation` changes.
 | 
						||
- File provider enforces permissions (`0600`); rejects world-readable files.
 | 
						||
- Inline provider meant for tests only; flag `Surface:Secrets:AllowInline` enables 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.md` and associated runbooks.
 | 
						||
 | 
						||
## 8. Observability
 | 
						||
 | 
						||
- Metrics: `surface_secrets_requests_total{provider,result}`.
 | 
						||
- Logs: only log secret identifiers, never values.
 | 
						||
- Traces: `surface.secrets.get` span 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.md`
 | 
						||
- `docs/modules/scanner/design/surface-fs.md`
 | 
						||
- `docs/modules/scanner/design/surface-validation.md`
 | 
						||
- `docs/modules/airgap/airgap-mode.md`
 |