Added support for reading policy files from Flatpak extension (#786)
Some checks are pending
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions

This commit is contained in:
Thorsten Sommer 2026-05-31 19:24:11 +02:00 committed by GitHub
parent b37f70d7ff
commit 86700847e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 6 deletions

View File

@ -1,5 +1,6 @@
# v26.6.1, build 241 (2026-06-xx xx:xx UTC) # v26.6.1, build 241 (2026-06-xx xx:xx UTC)
- Added support for up to 100 thousand enterprise configuration slots, using fixed-width slot names such as `config_00000` while keeping the existing first ten slot names compatible. - Added support for up to 100 thousand enterprise configuration slots, using fixed-width slot names such as `config_00000` while keeping the existing first ten slot names compatible.
- Added support for managed custom root certificate bundles and host allowlists for external HTTPS requests, helping Flatpak deployments connect to organization-internal services with private root CAs while keeping built-in cloud provider endpoints on system trust. - Added support for managed custom root certificate bundles and host allowlists for external HTTPS requests, helping Flatpak deployments connect to organization-internal services with private root CAs while keeping built-in cloud provider endpoints on system trust.
- Added support for reading enterprise policy files from a Flatpak provisioning extension.
- Added startup path and Linux package type details to the information page to make support easier. - Added startup path and Linux package type details to the information page to make support easier.
- Improved the enterprise configuration details on the information page by showing where each configuration comes from and which configuration slot was used. - Improved the enterprise configuration details on the information page by showing where each configuration comes from and which configuration slot was used.

View File

@ -79,6 +79,28 @@ AI Studio checks each directory listed in `$XDG_CONFIG_DIRS` and looks for a `mi
The directories from `$XDG_CONFIG_DIRS` are processed in order. The directories from `$XDG_CONFIG_DIRS` are processed in order.
#### Flatpak policy directory
When AI Studio runs as a Flatpak, it first checks this sandbox path before the regular Linux policy directories:
`/app/etc/MindWorkAI/`
This path is intended for a Flatpak provisioning extension like:
```yaml
add-extensions:
org.MindWorkAI.AIStudio.provisioning:
directory: etc/MindWorkAI
no-autodownload: true
```
Policy files can then be provided on the host through the extension directories. For example:
- System-wide, read-only: `/var/lib/flatpak/extension/org.MindWorkAI.AIStudio.provisioning/x86_64/stable/`
- User-specific: `$XDG_DATA_HOME/flatpak/extension/org.MindWorkAI.AIStudio.provisioning/x86_64/stable/`
Files placed there are mounted into the sandbox at `/app/etc/MindWorkAI/`. Use the same policy file names and YAML format described below.
#### macOS policy directory #### macOS policy directory
`/Library/Application Support/MindWork/AI Studio/` `/Library/Application Support/MindWork/AI Studio/`

View File

@ -22,6 +22,9 @@ const ENTERPRISE_REGISTRY_KEY_PATH: &str = r"Software\github\MindWork AI Studio\
const ENTERPRISE_POLICY_SECRET_FILE_NAME: &str = "config_encryption_secret.yaml"; const ENTERPRISE_POLICY_SECRET_FILE_NAME: &str = "config_encryption_secret.yaml";
#[cfg(any(target_os = "linux", test))]
const FLATPAK_ENTERPRISE_POLICY_DIRECTORY: &str = "/app/etc/MindWorkAI";
const ENTERPRISE_ENV_CONFIG_ID_PREFIX: &str = "MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID"; const ENTERPRISE_ENV_CONFIG_ID_PREFIX: &str = "MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_ID";
const ENTERPRISE_ENV_CONFIG_SERVER_URL_PREFIX: &str = "MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL"; const ENTERPRISE_ENV_CONFIG_SERVER_URL_PREFIX: &str = "MINDWORK_AI_STUDIO_ENTERPRISE_CONFIG_SERVER_URL";
const ENTERPRISE_ENV_CONFIGS: &str = "MINDWORK_AI_STUDIO_ENTERPRISE_CONFIGS"; const ENTERPRISE_ENV_CONFIGS: &str = "MINDWORK_AI_STUDIO_ENTERPRISE_CONFIGS";
@ -547,7 +550,7 @@ fn enterprise_policy_directories() -> Vec<PathBuf> {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn enterprise_policy_directories() -> Vec<PathBuf> { fn enterprise_policy_directories() -> Vec<PathBuf> {
let xdg_config_dirs = env::var("XDG_CONFIG_DIRS").ok(); let xdg_config_dirs = env::var("XDG_CONFIG_DIRS").ok();
linux_policy_directories_from_xdg(xdg_config_dirs.as_deref()) linux_policy_directories_from_xdg(xdg_config_dirs.as_deref(), is_flatpak())
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
@ -563,17 +566,23 @@ fn enterprise_policy_directories() -> Vec<PathBuf> {
} }
#[cfg(any(target_os = "linux", test))] #[cfg(any(target_os = "linux", test))]
fn linux_policy_directories_from_xdg(xdg_config_dirs: Option<&str>) -> Vec<PathBuf> { fn linux_policy_directories_from_xdg(xdg_config_dirs: Option<&str>, include_flatpak_provisioning: bool) -> Vec<PathBuf> {
let mut directories = Vec::new(); let mut directories = Vec::new();
if include_flatpak_provisioning {
directories.push(PathBuf::from(FLATPAK_ENTERPRISE_POLICY_DIRECTORY));
}
let mut has_linux_policy_directory = false;
if let Some(raw_directories) = xdg_config_dirs { if let Some(raw_directories) = xdg_config_dirs {
for path in raw_directories.split(':') { for path in raw_directories.split(':') {
if let Some(path) = normalize_enterprise_value(path) { if let Some(path) = normalize_enterprise_value(path) {
directories.push(PathBuf::from(path).join("mindwork-ai-studio")); directories.push(PathBuf::from(path).join("mindwork-ai-studio"));
has_linux_policy_directory = true;
} }
} }
} }
if directories.is_empty() { if !has_linux_policy_directory {
directories.push(PathBuf::from("/etc/xdg/mindwork-ai-studio")); directories.push(PathBuf::from("/etc/xdg/mindwork-ai-studio"));
} }
@ -1313,7 +1322,7 @@ mod tests {
#[test] #[test]
fn linux_policy_directories_from_xdg_preserves_order_and_falls_back() { fn linux_policy_directories_from_xdg_preserves_order_and_falls_back() {
assert_eq!( assert_eq!(
linux_policy_directories_from_xdg(Some(" /opt/company:/etc/xdg ")), linux_policy_directories_from_xdg(Some(" /opt/company:/etc/xdg "), false),
vec![ vec![
PathBuf::from("/opt/company/mindwork-ai-studio"), PathBuf::from("/opt/company/mindwork-ai-studio"),
PathBuf::from("/etc/xdg/mindwork-ai-studio"), PathBuf::from("/etc/xdg/mindwork-ai-studio"),
@ -1321,15 +1330,35 @@ mod tests {
); );
assert_eq!( assert_eq!(
linux_policy_directories_from_xdg(Some(" : ")), linux_policy_directories_from_xdg(Some(" : "), false),
vec![PathBuf::from("/etc/xdg/mindwork-ai-studio")] vec![PathBuf::from("/etc/xdg/mindwork-ai-studio")]
); );
assert_eq!( assert_eq!(
linux_policy_directories_from_xdg(None), linux_policy_directories_from_xdg(None, false),
vec![PathBuf::from("/etc/xdg/mindwork-ai-studio")] vec![PathBuf::from("/etc/xdg/mindwork-ai-studio")]
); );
} }
#[test]
fn linux_policy_directories_from_xdg_checks_flatpak_provisioning_first() {
assert_eq!(
linux_policy_directories_from_xdg(Some(" /opt/company:/etc/xdg "), true),
vec![
PathBuf::from("/app/etc/MindWorkAI"),
PathBuf::from("/opt/company/mindwork-ai-studio"),
PathBuf::from("/etc/xdg/mindwork-ai-studio"),
]
);
assert_eq!(
linux_policy_directories_from_xdg(None, true),
vec![
PathBuf::from("/app/etc/MindWorkAI"),
PathBuf::from("/etc/xdg/mindwork-ai-studio"),
]
);
}
#[test] #[test]
fn load_policy_values_from_directories_uses_first_directory_wins() { fn load_policy_values_from_directories_uses_first_directory_wins() {
let directory_a = tempdir().unwrap(); let directory_a = tempdir().unwrap();