{"id":711,"date":"2026-10-07T10:34:10","date_gmt":"2026-10-07T08:34:10","guid":{"rendered":"https:\/\/www.computeq.de\/en\/?page_id=711"},"modified":"2026-10-07T10:37:13","modified_gmt":"2026-10-07T08:37:13","slug":"libretto-work-for-admins","status":"publish","type":"page","link":"https:\/\/www.computeq.de\/en\/produkte\/libretto-ios-app-unofficial-librechat-app\/libretto-work-for-admins\/","title":{"rendered":"Libretto Work for Admins"},"content":{"rendered":"\n<!-- Libretto Work \u2013 restricting speech output (EN, for administrators). Paste into WordPress as HTML\/code editor.\n     Replace the placeholder before publishing: WORK-PAGE-LINK (information page \"Libretto Work\"). As of: 7 October 2026 -->\n<h1>Libretto Work: restricting speech output<\/h1>\n<p>Guide for administrators. General information and licensing: <a href=\"https:\/\/www.computeq.de\/en\/produkte\/libretto-ios-app-unofficial-librechat-app\/libretto-work\/\">Libretto Work<\/a>.<\/p>\n\n<h2>What is this about?<\/h2>\n<p>Libretto reads answers aloud. By default the <strong>iOS system voice speaks locally on the device<\/strong>, so no text leaves the device. Users can optionally enable a cloud voice (OpenRouter, with their own key). Answer texts then go to that service. As an organization you can define which speech output is allowed.<\/p>\n<p><strong>Important:<\/strong> Employees <strong>cannot loosen<\/strong> a policy of the organization. Local settings or rules in the app can only restrict it further. What <em>all<\/em> sources (device management, server, local rule) allow is permitted. The system voice is always allowed.<\/p>\n<p>Two ways, which can be combined:<\/p>\n\n<h2>Way A: Managed app configuration (MDM)<\/h2>\n<p>For organizations with device management (Microsoft Intune, Jamf, Workspace ONE and others). The configuration applies to the whole app on the managed device, employees cannot change it, and changes arrive live in the app. App bundle ID: <code>net.keutgen.libretto<\/code>.<\/p>\n<table>\n<thead><tr><th>Key<\/th><th>Type<\/th><th>Meaning<\/th><\/tr><\/thead>\n<tbody>\n<tr><td><code>speechAllowedEngines<\/code><\/td><td>Array of strings<\/td><td>Allowed speech output for <strong>all<\/strong> profiles. Values: <code>system<\/code>, <code>openrouter<\/code><\/td><\/tr>\n<tr><td><code>speechRules<\/code><\/td><td>Array of objects<\/td><td>Allowed speech output <strong>per domain<\/strong>: <code>host<\/code> (domain, subdomains count) and <code>allowedEngines<\/code><\/td><\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Example 1:<\/strong> only the local system voice, on the whole device.<\/p>\n<pre><code>&lt;dict&gt;\n  &lt;key&gt;speechAllowedEngines&lt;\/key&gt;\n  &lt;array&gt;\n    &lt;string&gt;system&lt;\/string&gt;\n  &lt;\/array&gt;\n&lt;\/dict&gt;<\/code><\/pre>\n<p><strong>Example 2:<\/strong> only your domain gets the system voice, employees&#8217; private profiles stay unaffected.<\/p>\n<pre><code>&lt;dict&gt;\n  &lt;key&gt;speechRules&lt;\/key&gt;\n  &lt;array&gt;\n    &lt;dict&gt;\n      &lt;key&gt;host&lt;\/key&gt;\n      &lt;string&gt;firma.de&lt;\/string&gt;\n      &lt;key&gt;allowedEngines&lt;\/key&gt;\n      &lt;array&gt;\n        &lt;string&gt;system&lt;\/string&gt;\n      &lt;\/array&gt;\n    &lt;\/dict&gt;\n  &lt;\/array&gt;\n&lt;\/dict&gt;<\/code><\/pre>\n<p><strong>In Microsoft Intune:<\/strong> <em>Apps \u2192 iOS\/iPadOS \u2192 App configuration policies \u2192 Add \u2192 Managed devices<\/em>, select the Libretto app and choose &#8220;Enter XML data&#8221; as the format. Enter the <code>&lt;dict&gt;<\/code> from one of the examples. In <strong>Jamf<\/strong> you enter the same under the app&#8217;s <em>App Configuration<\/em>.<\/p>\n\n<h2>Way B: File on your LibreChat server<\/h2>\n<p>For organizations without device management. Your server delivers a small JSON file at<\/p>\n<pre><code>https:\/\/&lt;your-server&gt;\/.well-known\/libretto.json<\/code><\/pre>\n<pre><code>{\n  \"version\": 1,\n  \"speech\": { \"allowedEngines\": [\"system\"] }\n}<\/code><\/pre>\n<ul>\n<li>Libretto fetches the file when a profile loads and when the app returns to the foreground, and remembers the policy per server.<\/li>\n<li><strong>Offline<\/strong> the last known policy applies.<\/li>\n<li>If you remove the file, the policy ends at the next fetch. If the server returns the chat page (HTML) or 404, that counts as &#8220;no policy&#8221;.<\/li>\n<li>The file must be reachable without sign-in.<\/li>\n<\/ul>\n<p><strong>nginx:<\/strong><\/p>\n<pre><code>location = \/.well-known\/libretto.json {\n    default_type application\/json;\n    add_header Cache-Control \"no-store\";\n    return 200 '{\"version\":1,\"speech\":{\"allowedEngines\":[\"system\"]}}';\n}<\/code><\/pre>\n<p><strong>Apache:<\/strong><\/p>\n<pre><code>Alias \/.well-known\/libretto.json \/var\/www\/libretto.json\n&lt;Files \"libretto.json\"&gt;\n    ForceType application\/json\n&lt;\/Files&gt;<\/code><\/pre>\n\n<h2>How to check the effect<\/h2>\n<ol>\n<li>Install Libretto on a test device and create a profile for your instance.<\/li>\n<li>Open <em>\u2026 \u2192 Voice mode<\/em>. With way A the section <strong>&#8220;From your organization&#8221;<\/strong> appears at the top with your policies, and blocked engines are missing from the selection.<\/li>\n<li>In the profile, under &#8220;Voice mode&#8221;, try choosing OpenRouter. Below the selection a note says that a policy blocks the choice.<\/li>\n<li>Start a conversation. The profile&#8217;s debug log names the source, for example (the log is written in German): &#8220;Sprachausgabe: iOS-Systemstimme (Richtlinie des Servers f\u00fcr \u2026 sperrt OpenRouter)&#8221;.<\/li>\n<\/ol>\n\n<h2>Limits<\/h2>\n<ul>\n<li>The <strong>server file<\/strong> applies to the profile with that address. If an employee enters the same server under another address (IP address, own proxy), the app does not receive the file. A policy through <strong>MDM<\/strong> (per domain or for all profiles) cannot be bypassed this way. A list of allowed servers in the MDM configuration is planned.<\/li>\n<li>The policy protects the <strong>app&#8217;s speech output<\/strong>. Text can still be copied and read aloud elsewhere. It is protection against unintentional leakage, not complete data security.<\/li>\n<li>Speech recognition (speech to text) runs on the device by default. There is currently no central policy for it.<\/li>\n<\/ul>\n\n<h2>Contact<\/h2>\n<p>Technical questions: <a href=\"mailto:support@computeq.de\">support@computeq.de<\/a><br>\nLicenses and quotes: <a href=\"mailto:sales@computeq.de\">sales@computeq.de<\/a><\/p>\n<p><em>As of: 7 October 2026<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Libretto Work: restricting speech output Guide for administrators. General information and licensing: Libretto Work. What is this about? Libretto reads answers aloud. By default the iOS system voice speaks locally on the device, so no text leaves the device. Users can optionally enable a cloud voice (OpenRouter, with their own key). Answer texts then go<\/p><\/div>\n<div class=\"blog-btn\"><a href=\"https:\/\/www.computeq.de\/en\/produkte\/libretto-ios-app-unofficial-librechat-app\/libretto-work-for-admins\/\" class=\"home-blog-btn\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":703,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-711","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/pages\/711","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/comments?post=711"}],"version-history":[{"count":2,"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/pages\/711\/revisions"}],"predecessor-version":[{"id":714,"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/pages\/711\/revisions\/714"}],"up":[{"embeddable":true,"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/pages\/703"}],"wp:attachment":[{"href":"https:\/\/www.computeq.de\/en\/wp-json\/wp\/v2\/media?parent=711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}