# ADR 0001: Runtime Secret Provisioning

**Status:** Accepted
**Date:** 2026-03-30

## Context

CapaKraken historically allowed some operational runtime secrets to be persisted through `SystemSettings`.

That included values such as:

- primary AI API credentials
- dedicated DALL-E credentials
- Gemini credentials
- SMTP password
- anonymization seed

This was convenient for fast iteration, but it coupled operational secret material to the main application data plane and blurred the line between configuration metadata and deployment secrets.

The project is moving toward a production model where the running artifact should be immutable and environment-driven. That model is weakened if operators can still rotate runtime secrets through normal application writes.

## Decision

Operational runtime secrets must be provisioned outside the application database.

Allowed sources:

- deployment environment variables
- host-level secret files such as `.env.production` on self-managed infrastructure
- platform secret managers or encrypted environment facilities

Disallowed source for new secret values:

- admin updates that write runtime secrets into `SystemSettings`

`SystemSettings` remains valid for non-secret runtime metadata such as:

- provider selection
- endpoints
- model names
- SMTP host/user/from settings
- anonymization mode and domain

Legacy secret values that already exist in `SystemSettings` may still be read during migration for compatibility, but they are not the target state and should be cleared after equivalent deployment secrets are provisioned.

## Consequences

Positive:

- production updates become more predictable because images and runtime secrets are managed as separate deployment concerns
- operational secrets stop depending on ordinary application write paths
- admin tooling can expose status and diagnostics without pretending to be the system of record for secrets
- secret rotation becomes an infrastructure operation rather than a product mutation

Tradeoffs:

- smaller self-managed installs need a disciplined host bootstrap process
- operators must understand that updating app settings is no longer sufficient for secret rotation
- migration requires visibility into which secrets are still backed by database residue

## Implementation Notes

The implementation should follow these rules:

1. runtime consumers resolve supported secret values from environment first
2. admin settings reads expose presence and source status, not secret values
3. admin settings updates ignore incoming secret payloads
4. the UI explains the expected environment variables for each runtime secret
5. a dedicated cleanup action removes legacy database-stored secret values after migration

## Operational Guidance

For staging and production:

1. provision runtime secrets on the host or platform before starting a new release
2. deploy the already-built application image
3. restart the application so the new process reads the current secret source
4. verify runtime status in admin settings
5. clear any leftover legacy database secret values once the environment-backed source is confirmed

Secret rotation should follow the same model. In most cases, no application data mutation is needed. The operator updates the deployment secret source and restarts or redeploys the app.

## Follow-up

Still required after this decision:

- complete the canonical image-based staging/production rollout
- ensure staging and production hosts both use the same secret provisioning rules
- periodically verify that legacy database secret fields remain empty
