Configuration and Secrets Management
Relevant source files
The following files were used as context for generating this wiki page:The PeP5 application employs a multi-layered configuration strategy to manage settings and secrets across different environments. This approach combines standard ASP.NET Core configuration providers (like appsettings.json), environment-specific files, a database-driven model for dynamic platform settings, and Google Cloud Secret Manager for secure handling of production secrets.
This document outlines the architecture of configuration and secrets management, from application startup and local development to production deployment on Google Cloud. It covers how connection strings, API keys, and other application settings are loaded and accessed by various services.
Configuration Loading
The application's configuration is loaded at startup in Program.cs. It follows the standard ASP.NET Core hierarchical model, where settings from later providers override earlier ones.
The diagram below illustrates the flow of how configuration sources are loaded and prioritized.
This diagram shows the configuration loading hierarchy and how the IConfiguration service is consumed by different parts of the application.
Sources: Program.cs:9-12
Database Connection
The primary database connection string is retrieved from the DefaultConnection key within the ConnectionStrings section of the configuration. This is used to register the ApplicationDbContext.
Sources: Program.cs:10-11
Production Deployment & Secrets
For production environments, the application is designed to be deployed on Google Cloud Platform (GCP) using Cloud Run and Cloud SQL. Sensitive information, particularly the database connection string, is managed using Google Cloud Secret Manager.
Google Cloud Secret Management
The deployment guide specifies a secure method for handling the database connection string:
- A secret is created in Google Cloud Secret Manager to store the connection string.
- The Cloud Run service is granted IAM permissions (
roles/secretmanager.secretAccessor) to access this secret. - The secret is mounted into the Cloud Run service instance as an environment variable (
ConnectionStrings__DefaultConnection). This maps the secret's value to the configuration key the application expects.
The diagram below shows the interaction between services in a production environment.
This diagram illustrates how the Cloud Run service securely retrieves the database connection string from Secret Manager to connect to the Cloud SQL instance.
Sources: DEPLOY-GCLOUD.md:47-55, DEPLOY-GCLOUD.md:61-68
The deployment script (deploy-gcloud.ps1) also facilitates this process by setting up the necessary GCP services and configurations.
Sources: deploy-gcloud.ps1
Production Environment Variables
The following environment variables are configured for the Cloud Run service:
| Variable | Description | Source |
|---|---|---|
ConnectionStrings__DefaultConnection | The SQL Server connection string, sourced from Secret Manager. | DEPLOY-GCLOUD.md:65, DEPLOY-GCLOUD.md:80-82 |
ASPNETCORE_ENVIRONMENT | Set to Production to enable production-specific behaviors. | DEPLOY-GCLOUD.md:80-82 |
ExamAppUpdate__DownloadUrl | The public URL for downloading the ExamApp installer, typically hosted on Cloud Storage. | DEPLOY-GCLOUD.md:80-82 |
Sources: DEPLOY-GCLOUD.md:80-82
Application-Level Configuration
In addition to environment-based configuration, PeP5 uses two other mechanisms for managing settings: a database table for platform-wide settings and a dedicated configuration section for the desktop client.
Platform Settings
A PlatformSetting entity allows for dynamic configuration values to be stored and managed in the database. This is ideal for settings that may need to be changed by an administrator without redeploying the application, such as API keys or feature flags.
Data Model
The PlatformSetting model is defined in Models/ExamModels.cs and consists of a key-value pair with an optional description.
This ER diagram shows the schema for the PlatformSetting table.
Sources: Models/ExamModels.cs:202-215
Default Settings
On application startup, the database is seeded with a set of default platform settings. This ensures that the application has the necessary configuration keys available from the first run.
| Key | Default Value | Description |
|---|---|---|
PlatformName | PeP - Programming Examination Platform | The name of the platform displayed in the UI. |
Version | 5.0 | The current version of the web application. |
Company | Infinity Atom | The company name. |
Copyright | Copyright 2021 - 2025 | The copyright notice. |
OpenAIApiKey | "" (empty string) | The API key for the OpenAI service. Must be configured by an admin. |
DefaultExamDurationMinutes | 120 | Default exam duration in minutes. |
EmailServer | "" (empty string) | SMTP server for sending emails. |
EmailPort | 587 | Port for the SMTP server. |
EmailUsername | "" (empty string) | Username for the SMTP server. |
EmailPassword | "" (empty string) | Password for the SMTP server. |
Sources: Data/ApplicationDbContext.cs:176-187
Usage Example: OpenAI Service
The OpenAIService demonstrates how these database-driven settings are used. It retrieves the OpenAIApiKey and OpenAIModel from the PlatformSettings table to initialize the OpenAI client. This decouples the service from IConfiguration and allows the API key to be updated in the database at runtime.
// File: Services/OpenAIService.cs:91-95
var apiKeySetting = await _context.PlatformSettings.FirstOrDefaultAsync(s => s.Key == "OpenAIApiKey");
var apiKey = apiKeySetting?.Value;
if (string.IsNullOrWhiteSpace(apiKey))
{
throw new InvalidOperationException("OpenAI API key is not configured in Platform Settings.");
}
Sources: Services/OpenAIService.cs:91-99, Services/OpenAIService.cs:260-269
Exam App Update Configuration
The configuration for the PeP.ExamApp desktop client auto-updater is managed via the ExamAppUpdate section in appsettings.json. This information is exposed through an API endpoint.
Configuration Structure
The ExamAppUpdate section has the following structure:
| Key | Type | Description |
|---|---|---|
Version | string | The latest available version of the Exam App. |
DownloadUrl | string | The direct URL to the installer executable. |
ReleaseNotes | string | Notes for the new version, displayed to the user. |
ReleaseDate | DateTime | The date the update was released. |
IsMandatory | bool | If true, the user is forced to update. |
MinimumVersion | string | The minimum version required to run the app. |
Checksum | string | The SHA256 checksum of the installer file for verification. |
Sources: PeP.ExamApp/Installer/README.md:92-102
API Endpoint
The ExamAppController provides an endpoint at GET /api/exam-app/update that reads this configuration section and returns it as a JSON response to the desktop client.
The following sequence diagram shows the update check process.
This diagram shows the Exam App client requesting update information, and the API controller retrieving it from the application's configuration.
Sources: Controllers/ExamAppController.cs:26-42
Summary
PeP5's configuration system is robust and secure, adapting to different operational environments. It uses appsettings.json for base configuration, Google Cloud Secret Manager for production secrets, and a PlatformSettings database table for dynamic, administrator-managed values. This layered approach ensures that sensitive data is protected while providing flexibility for both developers and administrators.