Add OIDC sign-in, group-derived roles and declarative instance configuration

Workspaces, group mappings and sign-in methods now come from a configuration
file synchronized at startup; workspaces dropped from it are disabled, never
deleted. Instance administrators (a new role) see and help every workspace and
may delete disabled ones; workspace administrators and employees are derived
from the user's groups at every SSO sign-in or administrator edit, and the
employee permission set belongs to the workspace. Self-registration is gone:
users come from SSO (only when their groups map) or from the administrator.
Break-glass bootstrap accounts get an HMAC-derived hourly password that all
replicas agree on. First SSO sign-in links a matching email contact to the
user. The demo runs on the same model with a generated per-start password.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Aleksandr BogomiakovandClaude committed 2026-10-07 13:28:43 +01:00
1 parent e37d583179
commit 4764f3545f
68 files changed
+7220 -964

No files matched your search

+39 -1
View File
@@ -14,8 +14,14 @@ pub struct UserRow {
pub display_name: String,
pub country: String,
pub timezone: Option<String>,
pub password_hash: String,
/// None for accounts that sign in only through SSO or whose bootstrap access was removed.
pub password_hash: Option<String>,
pub created_at: DateTime<Utc>,
pub email: Option<String>,
pub instance_admin: bool,
pub bootstrap: bool,
/// JSON array of group names that map to workspace roles through the instance configuration.
pub groups: String,
}
#[derive(Debug, Clone)]
@@ -47,6 +53,9 @@ pub struct WorkspaceRow {
pub document: String,
pub revision: i64,
pub created_at: DateTime<Utc>,
/// Stable identifier from the instance configuration; None for legacy workspaces.
pub key: Option<String>,
pub disabled_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone)]
@@ -112,3 +121,32 @@ pub struct ProviderObjectRow {
pub content: String,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
#[model(table_name = "oidc_flows")]
pub struct OidcFlowRow {
#[model(primary_key)]
pub state_hash: String,
pub nonce: String,
pub verifier: String,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Clone)]
#[model(table_name = "instance_state")]
pub struct InstanceStateRow {
#[model(primary_key)]
pub key: String,
pub value: String,
}
#[derive(Debug, Clone)]
#[model(table_name = "instance_audit")]
pub struct InstanceAuditRow {
#[model(primary_key)]
pub id: Auto<i64>,
pub actor_id: Option<String>,
pub action: String,
pub details: String,
pub created_at: DateTime<Utc>,
}