Parámetros dinámicos¶
Este documento explica cómo funciona la configuración de la plataforma, los dos mecanismos en juego, su precedencia y los peligros que se deben tener en cuenta.
Resumen: dos sistemas separados¶
Gitrust utiliza dos sistemas de configuración independientes:
| Système | Source | Modifiable à chaud | Visible dans l'UI admin |
|---|---|---|---|
| Configuration statique | Fichier .env + variables d'environnement |
Non (restart requis) | Non |
| Configuration dynamique | Table app_settings (PostgreSQL) |
Oui (effet immédiat) | Oui (/admin/settings) |
Hay un caso híbrido para OAuth (base de datos prioritaria, .env como alternativa).
1. Configuración estática (.env)¶
Principio¶
Las variables de entorno se cargan una vez al inicio mediante dotenvy::dotenv() y se almacenan en estructuras Rust inmutables. Nunca se vuelven a leer después del arranque.
Archivos de referencia¶
| Fichier | Rôle |
|---|---|
.env.example |
Template documenté avec toutes les variables |
.env |
Configuration locale (gitignore) |
.env.production |
Configuration de déploiement |
.env.test |
Configuration de tests |
Estructuras de carga¶
| Struct | Variables concernées |
|---|---|
GitrustConfig |
GIT_REPOS_BASE_PATH, SSH_PORT, SSH_LISTEN_ADDR, SSH_HOST_KEY_PATH, CI_*, IMPORT_* |
AppConfig |
APP_NAME, APP_THEME, APP_DEBUG |
AuthConfig |
JWT_SECRET, JWT_EXPIRATION_MINUTES, SESSION_*, RATE_LIMIT_*, COOKIE_* |
EmailConfig |
SMTP_*, EMAIL_*, IMAP_* |
Comportamiento¶
- Cargado en
RustwardenApp::build()al inicio - Almacenado en
Arc<Config>compartido a través del estado axum - Cambiar el
.envsin reiniciar no tiene ningún efecto - Estas variables NO se muestran en la interfaz de administración
Lista de variables estáticas (no exhaustiva)¶
DATABASE_URL, SERVER_HOST, SERVER_PORT, RUST_LOG,
SSH_HOST_KEY_PATH, SSH_PORT, SSH_LISTEN_ADDR, SSH_PUBLIC_HOST,
JWT_SECRET, JWT_EXPIRATION_MINUTES, JWT_ISSUER,
REFRESH_TOKEN_EXPIRATION_DAYS, REMEMBER_ME_EXPIRATION_DAYS,
SESSION_TIMEOUT_MINUTES, SESSION_BACKEND,
RATE_LIMIT_LOGIN_PER_MINUTE, RATE_LIMIT_REFRESH_PER_MINUTE,
RATE_LIMIT_GENERAL_PER_MINUTE,
APP_DEBUG, COOKIE_SECURE, COOKIE_SAME_SITE,
ADMIN_USERNAME, ADMIN_EMAIL, ADMIN_PASSWORD,
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM,
EMAIL_BASE_URL, EMAIL_QUEUE_*,
APP_NAME, APP_THEME, DEFAULT_LOCALE,
GIT_REPOS_BASE_PATH,
CI_ENABLED, CI_MAX_CONCURRENT, CI_REMOTE_HOST, CI_WORKSPACE_PATH
2. Configuración dinámica (tabla app_settings)¶
Principio¶
Las configuraciones dinámicas se almacenan en la base de datos PostgreSQL en la tabla app_settings y se leen en cada solicitud a través de AppSettingsService. Un administrador puede modificarlos sobre la marcha desde la interfaz /admin/settings.
Diagrama de tabla¶
CREATE TABLE app_settings (
id UUID PRIMARY KEY,
key VARCHAR(100) UNIQUE NOT NULL,
value TEXT NOT NULL,
description TEXT,
updated_by UUID REFERENCES users(id) ON DELETE SET NULL,
updated_at TIMESTAMPTZ NOT NULL
);
Inicialización al inicio¶
En el arranque, AppSettingsService::initialize_default_settings() crea la configuración predeterminada solo si aún no existe en la base:
let existing = Self::get_setting(db, key).await?;
if existing.is_none() {
// ... insert valeur par défaut
}
Consecuencia crítica: una vez que existe una configuración en la base (creada en el primer inicio o modificada a través de la interfaz de usuario), nunca se sobrescribe en un reinicio posterior.
Lista de configuraciones dinámicas y sus valores predeterminados¶
| Clé | Défaut | Description |
|---|---|---|
app_domain |
env::var("APP_DOMAIN") ou "localhost" |
Domaine de l'application |
allow_registration |
false |
Autoriser l'inscription publique |
validation_email_required |
true |
Exiger la validation email |
audit_log_level |
INFO |
Niveau de log d'audit |
audit_log_actions |
["create","update","delete","reset_password"] |
Actions auditées |
password_min_length |
8 |
Longueur minimum mot de passe |
password_require_uppercase |
false |
Exiger des majuscules |
password_require_lowercase |
false |
Exiger des minuscules |
password_require_digits |
false |
Exiger des chiffres |
password_require_special |
false |
Exiger des caractères spéciaux |
password_change_require_email |
true |
Confirmation email pour changement mdp |
password_expiration_enabled |
false |
Activer l'expiration des mots de passe |
password_expiration_days |
0 |
Durée d'expiration (jours) |
password_expiration_alert_enabled |
false |
Alerte email avant expiration |
password_expiration_alert_days_before |
7 |
Jours avant expiration pour alerter |
oauth_enabled |
false |
Activer OAuth/SSO |
oauth_google_enabled |
false |
Activer Google OAuth |
oauth_github_enabled |
false |
Activer GitHub OAuth |
oauth_discord_enabled |
false |
Activer Discord OAuth |
oauth_microsoft_enabled |
false |
Activer Microsoft OAuth |
oauth_redirect_base_url |
"" |
URL de base pour les callbacks OAuth |
oauth_auto_register |
true |
Créer un compte auto au premier login OAuth |
oauth_link_existing_account |
true |
Lier un compte OAuth à un utilisateur existant |
oauth_{provider}_client_id |
"" |
Client ID du provider OAuth |
oauth_{provider}_client_secret |
"" |
Client secret (chiffré AES-256-GCM en base) |
oauth_microsoft_tenant |
"" |
Tenant Azure AD |
3. Caso híbrido: OAuth¶
OAuth es el único subsistema que combina ambas fuentes. La lógica en OAuthConfig::load():
Pour chaque réglage OAuth :
1. Chercher dans app_settings (DB)
→ si trouvé et non vide : utiliser cette valeur
2. Sinon : fallback sur la variable d'environnement
→ si absente : utiliser la valeur par défaut codée en dur
Importante: OAuthConfig::load() se llama al inicio. El resultado se almacena en un "Arc" y no se reproduce dinámicamente. ENTONCES :
- Cambiar una configuración de OAuth a través de la interfaz de usuario del administrador requiere un reinicio para que se vuelva a cargar
OAuthConfig - El
.enves solo un recurso alternativo si la base de datos no tiene valor
4. Comportamiento de precedencia y reinicio¶
Configuraciones estáticas (solo .env)¶
| Action | Effet immédiat | Après restart |
|---|---|---|
Modifier .env |
Non | Oui |
Configuraciones dinámicas (solo DB)¶
| Action | Effet immédiat | Après restart |
|---|---|---|
| Modifier via UI admin | Oui | Oui (valeur en DB persiste) |
Modifier le .env |
Aucun effet | Aucun effet |
Configuración híbrida (OAuth)¶
| Action | Effet immédiat | Après restart |
|---|---|---|
| Modifier via UI admin | Non (OAuthConfig est en Arc) | Oui (DB prime sur .env) |
Modifier .env |
Non | Seulement si aucune valeur en DB |
5. Error principal: variables fantasma .env¶
Ciertas variables presentes en .env.example dan la ilusión de configurar ajustes que en realidad son administrados por la base de datos:
Variable .env |
Réglage DB correspondant | La variable .env est-elle lue ? |
|---|---|---|
ALLOW_REGISTRATION=true |
allow_registration |
Non — valeur par défaut codée en dur ("false") |
EMAIL_VALIDATION_REQUIRED=true |
validation_email_required |
Non — valeur par défaut codée en dur ("true") |
OAUTH_ENABLED=true |
oauth_enabled |
Oui, mais seulement en fallback si la DB n'a pas de valeur |
Para ALLOW_REGISTRATION y EMAIL_VALIDATION_REQUIRED:
- La variable
.envestá documentada en.env.examplepero nunca se accede a ella medianteinitialize_default_settings() - El valor inicial está codificado en el servicio.
- Sólo el valor en la base de datos (modificable a través de
/admin/settings) es auténtico
Para app_domain, esta es la única configuración dinámica que lee .env como semilla inicial.
6. Diagrama de decisión¶
┌─────────────────────────────┐
│ Quel type de réglage ? │
└──────────┬──────────────────-┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Infrastructure Fonctionnel OAuth
(port, JWT, SMTP) (inscription, (providers,
mots de passe) secrets)
│ │ │
▼ ▼ ▼
.env seul DB seule DB + fallback .env
│ │ │
▼ ▼ ▼
Restart requis Effet immédiat Restart requis
via /admin/ (OAuthConfig en Arc)
settings
7. Guía para administradores¶
Cambiar una configuración de infraestructura¶
Edite .env (o .env.production) y luego reinicie el servicio:
Cambiar una configuración funcional¶
Inicie sesión como administrador, vaya a /admin/settings, modifique el valor y haga clic en "Guardar". El efecto es inmediato, no es necesario reiniciar.
Cambiar una configuración de OAuth¶
A través de /admin/settings, modifique los valores de OAuth y luego reinicie el servicio (la configuración de OAuth se carga en la memoria durante el arranque y no se vuelve a leer dinámicamente).
Verifique el valor real de una configuración¶
Para configuraciones dinámicas, consulte la base de datos directamente:
Para configuraciones estáticas, verifique los registros al inicio (RUST_LOG=debug).
8. Guía para desarrolladores¶
Agregar una nueva configuración dinámica¶
-
Agregue la tupla
(clave, valor_predeterminado, descripción)enAppSettingsService::initialize_default_settings(): -
Lea el valor en el código a través del servicio:
-
El valor aparecerá automáticamente en
/admin/settings.
Agregar una nueva configuración estática¶
- Agregue variable en
.env.examplecon documentación completa - Lea la variable en la estructura
Configcorrespondiente a través deenv::var() - El valor no será visible en la interfaz de administración.
Agregar configuración híbrida (DB + respaldo .env)¶
Siga el patrón OAuth en crates/rustwarden-core/src/config/oauth.rs: