# ADR-010: Secrets Management Strategy | Field | Value | |---|---| | **Status** | `Accepted` | | **Date** | 2026-05-19 | | **Deciders** | *Full Team* | | **Supersedes** | – | | **Superseded by**| – | --- ## Context The system consists of multiple repositories and components (Spring Boot backend, AI/Retrieval service, and frontend) deployed via GitHub Actions CI/CD pipelines. Each component requires sensitive configuration values such as: - Database credentials - JWT signing secrets - External API keys - Service-to-service authentication tokens This ADR defines the secrets management strategy **at the system level**, applying to all repositories. Per-service implementation details (e.g. how each stack reads environment variables) are documented in service-specific READMEs or ADRs. Exposing sensitive values in source control introduces a high-risk security surface, including credential leakage via Git history, accidental exposure in pull requests, and CI log artifacts containing secrets. A consistent, enforceable strategy is required across local development, CI/CD pipelines, and production environments. ## Decision Drivers - No credentials must ever be stored in any repository - Strategy must apply uniformly across all services regardless of tech stack - Developer onboarding must remain straightforward - Must be compatible with GitHub Actions-based CI/CD without additional infrastructure ## Considered Options - **Option A** – GitHub Secrets + `.env` (untracked) + `.env.template` (tracked) - **Option B** – Secrets stored in `application.yml` / config files per service - **Option C** – Dedicated secret manager (HashiCorp Vault / AWS Secrets Manager) ## Decision **Chosen option: Option A** – A hybrid approach using GitHub Secrets for CI/CD injection, untracked local `.env` files for development, and a tracked `.env.template` as a configuration contract shared across all repositories. ## Rationale Option A provides the right balance of security and operational simplicity for the current stage. GitHub Secrets are scoped per environment, injected only at workflow runtime, and never persisted in build artifacts. The `.env` + `.env.template` pattern ensures local development remains straightforward while the template file acts as a living contract that keeps all developers and services aligned on required configuration. No additional infrastructure is required. Each service reads environment variables in an idiomatic way for its stack: | Service | Stack | Env Resolution | |---|---|---| | Backend | Spring Boot / Kotlin | `application.yml` variable placeholders | | AI/Retrieval | Python | `os.environ` / `python-dotenv` | | Frontend | React / TypeScript | Build-time `VITE_*` / runtime config | ## Pros and Cons of the Options ### Option A – GitHub Secrets + `.env` + `.env.template` - ✅ No credentials stored in any repository - ✅ Clear separation between local, CI, and production environments - ✅ `.env.template` improves onboarding and acts as a cross-repo configuration contract - ✅ Compatible with GitHub Actions without additional infrastructure - ✅ Stack-agnostic — applies uniformly regardless of service language or framework - ❌ Developers must manually manage local `.env` files - ❌ Risk of local environments drifting if `.env` diverges from `.env.template` - ❌ No centralised secret rotation mechanism at this stage ### Option B – Secrets in config files (`application.yml` / `.env` committed) - ✅ Zero setup friction for developers - ❌ High risk of credential leakage via Git history - ❌ Violates baseline security practices - ❌ Not compatible with CI/CD security requirements ### Option C – Dedicated Secret Manager (Vault / AWS Secrets Manager) - ✅ Centralised rotation, auditing, and access control - ✅ Strong production-grade secret lifecycle management - ❌ Significant operational overhead and infrastructure complexity - ❌ Requires deployment environment maturity not present at this stage - ❌ Not justified for the current team size and project phase ## Consequences **Positive:** - No sensitive credentials are stored in version control across any repository - Onboarding is straightforward via `.env.template` in every repo - CI/CD pipelines remain simple — no external secret manager dependency **Negative / Trade-offs:** - No centralised secret rotation — secrets must be updated manually per GitHub environment - Developer discipline required to avoid logging environment variables locally or in CI **Follow-up actions:** - Every repository must include `.env.template` and a `.gitignore` entry blocking `.env` - CI pipelines must validate presence of required secrets before deployment steps - Logging configurations in all services must redact environment variables ## Links