{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Perses Blog",
  "home_page_url": "https://perses.dev/blog/",
  "feed_url": "https://perses.dev/blog/feed.json",
  "description": "News, release notes and stories from the Perses community.",
  "icon": "https://perses.dev/assets/images/favicon.png",
  "language": "en",
  "items": [
    {
      "id": "https://perses.dev/blog/2026/10/21/release-v0550/",
      "url": "https://perses.dev/blog/2026/10/21/release-v0550/",
      "title": "Release v0.55.0",
      "summary": "Welcome to the v0.55.0 release!",
      "content_html": "\n<p>Welcome to the v0.55.0 release!</p>\n<p>This release first comes with a large number of security fixes, several of them critical, so we strongly recommend\nupgrading as soon as possible.</p>\n<p>On the dashboard side, you can now repeat a single panel, define annotations per panel, drag and drop panels between\ngroups and lock the plugin versions used by a dashboard. Prometheus exemplars are supported, the search has been\nrewritten on the backend, and two new plugins are available: Canvas and JSON.</p>\n<p>As usual, this blog post doesn't cover every change. For the complete list, check the\n<a href=\"https://github.com/perses/perses/releases/tag/v0.55.0\">changelog</a>.</p>\n<!-- more -->\n<h2 id=\"security\">Security</h2>\n<p>This release fixes a significant number of security vulnerabilities, several of them critical. Most of them can be\nexploited without authentication when Perses runs with its default configuration (<code>security.enable_auth: false</code>).\nWe strongly recommend upgrading as soon as possible.</p>\n<p>Some of these fixes are breaking changes, check the <a href=\"https://perses.dev/docs/perses/latest/upgrade/v0.55.0/\">upgrade guide</a>\nbefore upgrading and or the section <a href=\"https://perses.dev/blog/2026/10/21/release-v0550/#breaking-changes\">Breaking changes</a> below for more details.</p>\n<p>We also published a <a href=\"https://perses.dev/docs/perses/latest/security/\">security considerations</a> page\n(<a href=\"https://github.com/perses/perses/pull/4512\">#4512</a>) describing how to deploy Perses safely.</p>\n<h3 id=\"authentication-bypass-via-forged-jwts-ghsa-mpfg-6jh9-3jmg\">Authentication bypass via forged JWTs (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-mpfg-6jh9-3jmg\">GHSA-mpfg-6jh9-3jmg</a>)</h3>\n<p>When authentication was enabled without setting <code>security.encryption_key</code> (or <code>security.encryption_key_file</code>), Perses\nfell back to a key hardcoded in its public source code. This key is also used to sign the JWTs, so anyone could forge a\nvalid token for any user, including an admin.</p>\n<p>Perses now refuses to start when authentication is enabled and no encryption key is provided.</p>\n<h3 id=\"server-side-request-forgery-in-the-datasource-proxy-ghsa-58wc-w2cq-7vf3\">Server-Side Request Forgery in the datasource proxy (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-58wc-w2cq-7vf3\">GHSA-58wc-w2cq-7vf3</a>)</h3>\n<p>The datasource proxy (HTTP and SQL) connected to whatever destination the datasource defined. Combined with the\n\"unsaved\" proxy endpoints, Perses could be used to read any service reachable from the server: loopback, cloud metadata\nendpoints, the Kubernetes API, etc.</p>\n<p>The destination of the proxy is now verified when a datasource is saved and before each request, including on every\nresolved IP address. Loopback, link-local, the cloud metadata endpoints and the Kubernetes API are denied by default.\nPrivate networks remain allowed. The restrictions can be adjusted in the new <code>datasource.proxy</code> configuration section:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">datasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  proxy</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    allowed_networks</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: [</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"127.0.0.0/8\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"::1/128\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">]</span></span></code></pre>\n<h3 id=\"arbitrary-file-read-through-secrets-ghsa-2qpg-wfx2-frv2\">Arbitrary file read through secrets (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-2qpg-wfx2-frv2\">GHSA-2qpg-wfx2-frv2</a>)</h3>\n<p>Secrets can reference files (<code>passwordFile</code>, <code>credentialsFile</code>, <code>clientSecretFile</code>, <code>caFile</code>, <code>certFile</code>, <code>keyFile</code>).\nThese files could be anywhere on the server, so a user able to create a secret could exfiltrate any file readable by\nPerses through the datasource proxy.</p>\n<p>File references are now rejected by default. They are only allowed in the directories listed in the new\n<code>security.secret_file_allowed_directories</code> configuration.</p>\n<h3 id=\"caller-credentials-forwarded-to-the-datasource-ghsa-phr8-237x-w7mj\">Caller credentials forwarded to the datasource (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-phr8-237x-w7mj\">GHSA-phr8-237x-w7mj</a>)</h3>\n<p>The HTTP datasource proxy forwarded the <code>Cookie</code> and <code>Authorization</code> headers of the caller to the datasource. Anyone\ncontrolling a datasource could steal the Perses session of its users (including the refresh token) and take over their\naccount.</p>\n<p>The <code>Cookie</code> header of the caller is no longer forwarded, and neither is the <code>Authorization</code> header when the native\nauthorization is enabled. To authenticate against a datasource, use a secret or the <code>oauthPassthrough</code> option.</p>\n<h3 id=\"stored-xss-through-the-datasource-proxy-ghsa-8hm2-fqjh-pgj2\">Stored XSS through the datasource proxy (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-8hm2-fqjh-pgj2\">GHSA-8hm2-fqjh-pgj2</a>)</h3>\n<p>The responses of the datasource proxy are served from the Perses origin, almost unchanged. A malicious datasource could\nserve HTML and JavaScript running with the session of any user opening a link to it, set cookies on the Perses domain,\nor redirect users anywhere.</p>\n<p>The proxy responses are now sandboxed with a strict <code>Content-Security-Policy</code>, and the headers that apply to the Perses\norigin (<code>Set-Cookie</code>, CORS headers, absolute redirections, etc.) are removed. As a consequence, the UI of a datasource\n(e.g. the Prometheus UI) can no longer be browsed through the proxy.</p>\n<h3 id=\"sql-proxy-vulnerabilities\">SQL proxy vulnerabilities</h3>\n<p>Several vulnerabilities have been fixed in the SQL proxy:</p>\n<ul>\n<li><strong>Read-only restriction bypass</strong> (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-r457-39g6-wpc6\">GHSA-r457-39g6-wpc6</a>):\nqueries modifying the data or the schema could get through the keyword check. Queries must now start with a read\nkeyword (<code>SELECT</code>, <code>WITH</code>, <code>SHOW</code>, etc.) and are executed in a read-only transaction. MySQL <code>multiStatements</code>, as\nwell as <code>SELECT ... INTO OUTFILE / DUMPFILE</code>, are rejected.</li>\n<li><strong>Arbitrary file read with MySQL/MariaDB</strong> (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-92jg-r5jf-x5fh\">GHSA-92jg-r5jf-x5fh</a>):\nthe <code>allowAllFiles</code> driver option could be enabled from the datasource params, letting the database server read any\nfile of the Perses server. This option, as well as <code>allowCleartextPasswords</code> and <code>allowOldPasswords</code>, is now always\ndisabled.</li>\n<li><strong>MySQL/MariaDB TLS config mix-up</strong> (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-jg7f-c7hw-wxgw\">GHSA-jg7f-c7hw-wxgw</a>):\ntwo datasources with colliding names could use each other's TLS configuration (CA, client certificate, verification\nsettings). The TLS configuration is now set per connection.</li>\n</ul>\n<h3 id=\"missing-secret-authorization-in-dashboard-datasources-ghsa-mc34-vgvh-gpr7\">Missing secret authorization in dashboard datasources (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-mc34-vgvh-gpr7\">GHSA-mc34-vgvh-gpr7</a>)</h3>\n<p>A user allowed to edit a dashboard, but not to read secrets, could embed a datasource referencing any secret of the\nproject and make the proxy send it to a server they control. Perses now checks that the user can read the secret used\nby a datasource embedded in a dashboard.</p>\n<h3 id=\"wiping-the-database-with-a-single-request-ghsa-j8hv-r356-hfw6\">Wiping the database with a single request (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-j8hv-r356-hfw6\">GHSA-j8hv-r356-hfw6</a>)</h3>\n<p>With the file system database, deleting the project <code>..</code> (<code>DELETE /api/v1/projects/..</code>) deleted the entire database.\nThe name of the resource in the URL was never validated. Every parameter of the URL is now validated before being used.</p>\n<h3 id=\"path-traversal-in-the-file-system-database-ghsa-63qw-3pm6-j4f3-ghsa-2wxp-jhwc-h2ff\">Path traversal in the file system database (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-63qw-3pm6-j4f3\">GHSA-63qw-3pm6-j4f3</a>, <a href=\"https://github.com/perses/perses/security/advisories/GHSA-2wxp-jhwc-h2ff\">GHSA-2wxp-jhwc-h2ff</a>)</h3>\n<p>The fix released in v0.54.0 for <a href=\"https://github.com/perses/perses/security/advisories/GHSA-vr5f-w35q-98jp\">CVE-2026-63445</a>\ncould be bypassed with a project named <code>..</code> (e.g. <code>GET /api/v1/variables?project=..</code>), returning the whole database. The\nanonymous endpoint <code>POST /api/validate/dashboards</code> was also using the <code>metadata.project</code> of the dashboard without any\nvalidation.</p>\n<p>The project name is now validated for every HTTP method and in the body of the requests, and the file system database\nitself rejects any key that would escape its directory.</p>\n<p>Note that these issues (as well as the previous one) don't affect the SQL database.</p>\n<aside class=\"admonition\" data-type=\"info\" data-severity=\"info\" data-title=\"Implementation details\">\n<p>If you want to see how these vulnerabilities have been fixed, here are the related pull requests:</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Vulnerability</th><th>Pull request(s)</th><th>Advisory</th></tr></thead><tbody><tr><td>Forged JWTs (default encryption key)</td><td><a href=\"https://github.com/perses/perses/pull/4550\">#4550</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-mpfg-6jh9-3jmg\">GHSA-mpfg-6jh9-3jmg</a></td></tr><tr><td>SSRF in the datasource proxy</td><td><a href=\"https://github.com/perses/perses/pull/4518\">#4518</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-58wc-w2cq-7vf3\">GHSA-58wc-w2cq-7vf3</a></td></tr><tr><td>Arbitrary file read through secrets</td><td><a href=\"https://github.com/perses/perses/pull/4503\">#4503</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-2qpg-wfx2-frv2\">GHSA-2qpg-wfx2-frv2</a></td></tr><tr><td>Caller credentials forwarded to the datasource</td><td><a href=\"https://github.com/perses/perses/pull/4553\">#4553</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-phr8-237x-w7mj\">GHSA-phr8-237x-w7mj</a></td></tr><tr><td>Stored XSS through the datasource proxy</td><td><a href=\"https://github.com/perses/perses/pull/4558\">#4558</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-8hm2-fqjh-pgj2\">GHSA-8hm2-fqjh-pgj2</a></td></tr><tr><td>SQL proxy vulnerabilities</td><td><a href=\"https://github.com/perses/perses/pull/4522\">#4522</a>, <a href=\"https://github.com/perses/perses/pull/4535\">#4535</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-r457-39g6-wpc6\">GHSA-r457-39g6-wpc6</a>, <a href=\"https://github.com/perses/perses/security/advisories/GHSA-92jg-r5jf-x5fh\">GHSA-92jg-r5jf-x5fh</a>, <a href=\"https://github.com/perses/perses/security/advisories/GHSA-jg7f-c7hw-wxgw\">GHSA-jg7f-c7hw-wxgw</a></td></tr><tr><td>Missing secret authorization in dashboard datasources</td><td><a href=\"https://github.com/perses/perses/pull/4487\">#4487</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-mc34-vgvh-gpr7\">GHSA-mc34-vgvh-gpr7</a></td></tr><tr><td>Wiping the database with a single request</td><td><a href=\"https://github.com/perses/perses/pull/4499\">#4499</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-j8hv-r356-hfw6\">GHSA-j8hv-r356-hfw6</a></td></tr><tr><td>Path traversal in the file system database</td><td><a href=\"https://github.com/perses/perses/pull/4485\">#4485</a>, <a href=\"https://github.com/perses/perses/pull/4488\">#4488</a>, <a href=\"https://github.com/perses/perses/pull/4491\">#4491</a>, <a href=\"https://github.com/perses/perses/pull/4492\">#4492</a></td><td><a href=\"https://github.com/perses/perses/security/advisories/GHSA-63qw-3pm6-j4f3\">GHSA-63qw-3pm6-j4f3</a>, <a href=\"https://github.com/perses/perses/security/advisories/GHSA-2wxp-jhwc-h2ff\">GHSA-2wxp-jhwc-h2ff</a></td></tr></tbody></table>\n</aside>\n<h2 id=\"breaking-changes\">Breaking changes</h2>\n<h3 id=\"removal-of-the-package-perses-devcore\">Removal of the package <code>@perses-dev/core</code></h3>\n<p>As announced in v0.54.0, <code>@perses-dev/core</code> is no longer published\n(<a href=\"https://github.com/perses/perses/pull/4325\">#4325</a>). Its code has been dispatched in <code>@perses-dev/spec</code>,\n<code>@perses-dev/client</code>, <code>@perses-dev/plugin-system</code> and <code>@perses-dev/components</code>. It is also no longer shared with the\nplugins at runtime (<a href=\"https://github.com/perses/shared/pull/246\">perses/shared#246</a>), so plugins still importing it must\nbe migrated.</p>\n<h3 id=\"dependency-upgrades-react-17-dropped-node-24-typescript-7-and-end-of-commonjs\">Dependency upgrades: React 17 dropped, Node 24, TypeScript 7 and end of CommonJS</h3>\n<p>The frontend toolchain has been modernized across all the repositories:</p>\n<ul>\n<li><strong>React 17 is no longer supported</strong> (<a href=\"https://github.com/perses/perses/pull/4391\">#4391</a>,\n<a href=\"https://github.com/perses/shared/pull/269\">perses/shared#269</a>, <a href=\"https://github.com/perses/plugins/pull/790\">perses/plugins#790</a>),\nas planned in the <a href=\"https://github.com/perses/perses/blob/main/ROADMAP.md\">roadmap</a>.</li>\n<li><strong>Node.js 24 (LTS) and ES2023</strong> are now the target (<a href=\"https://github.com/perses/perses/pull/4380\">#4380</a>,\n<a href=\"https://github.com/perses/shared/pull/248\">perses/shared#248</a>, <a href=\"https://github.com/perses/spec/pull/78\">perses/spec#78</a>,\n<a href=\"https://github.com/perses/plugins/pull/779\">perses/plugins#779</a>).</li>\n<li><strong>Packages are published as ESM only</strong>: the CommonJS output has been removed.</li>\n<li><strong>TypeScript 7</strong>, as well as newer versions of Zod and React Hook Form (<a href=\"https://github.com/perses/perses/pull/4421\">#4421</a>).</li>\n</ul>\n<p>If you embed Perses in your own application, you now have to register the Perses packages shared with the plugins\nbefore rendering your app (<a href=\"https://github.com/perses/shared/pull/268\">perses/shared#268</a>):</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-typescript\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> *</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> as</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PersesClient </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/client'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> *</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> as</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PersesComponents </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/components'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> *</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> as</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PersesDashboards </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/dashboards'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> *</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> as</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PersesExplore </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/explore'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> *</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> as</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PersesPluginSystem </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/plugin-system'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { registerHostSharedModules } </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/plugin-system'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> *</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> as</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PersesSpec </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '@perses-dev/spec'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">registerHostSharedModules</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  '@perses-dev/spec'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: PersesSpec,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  '@perses-dev/client'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: PersesClient,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  '@perses-dev/components'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: PersesComponents,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  '@perses-dev/plugin-system'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: PersesPluginSystem,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  '@perses-dev/explore'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: PersesExplore,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  '@perses-dev/dashboards'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: PersesDashboards,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});</span></span></code></pre>\n<h3 id=\"removal-of-the-old-dashboard-and-datasource-specification\">Removal of the old dashboard and datasource specification</h3>\n<p>Since v0.54.0, the dashboard and datasource specifications live in <a href=\"https://github.com/perses/spec\">perses/spec</a>. The\ndeprecated copies remaining in Perses have been removed (<a href=\"https://github.com/perses/perses/pull/4326\">#4326</a>): the Go\npackages <code>pkg/model/api/v1/{common,dashboard,datasource,plugin,variable}</code> and their CUE equivalents. If you still import\nthem, switch to the ones provided by <code>github.com/perses/spec</code> (e.g. <code>github.com/perses/spec/go/dashboard</code>).</p>\n<h3 id=\"go-sdk-datasourceselector-is-now-a-union-type\">Go SDK: <code>datasource.Selector</code> is now a union type</h3>\n<p>A datasource selector can now reference a variable, which is serialized as a plain string (e.g. <code>\"$myDatasource\"</code>)\n(<a href=\"https://github.com/perses/perses/pull/4545\">#4545</a>). As a result, <code>datasource.Selector</code> no longer has the <code>Kind</code> and\n<code>Name</code> fields, but a <code>Static</code> or a <code>Variable</code> selector. Use the new constructors instead of a struct literal\n(<a href=\"https://github.com/perses/perses/pull/4557\">#4557</a>):</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Before</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">sel </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> &#x26;</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">datasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Selector</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{Kind: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"PrometheusDatasource\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, Name: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"myPrometheus\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// After</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">static </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> datasource.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">NewStaticSelector</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"PrometheusDatasource\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"myPrometheus\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">variable, err </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> datasource.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">NewVariableSelector</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"myDatasource\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Or let the SDK detect a variable reference (\"$foo\" or \"${foo}\")</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">auto, err </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> datasource.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">NewSelector</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"PrometheusDatasource\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, name)</span></span></code></pre>\n<p>The official plugins have been updated (<a href=\"https://github.com/perses/plugins/pull/857\">perses/plugins#857</a>): their\n<code>Selector</code> helper now detects variable references, and a new <code>VariableSelector</code> helper is available. If you maintain\nyour own datasource plugin with a <code>Selector</code> helper, update it the same way.</p>\n<p>Likewise, the deprecated CUE package <code>cue/common/proxy</code> has been removed from perses/shared\n(<a href=\"https://github.com/perses/shared/pull/327\">perses/shared#327</a>). Use <code>github.com/perses/spec/cue/datasource/proxy/http</code>\nand <code>github.com/perses/spec/cue/datasource/proxy/sql</code> instead.</p>\n<h3 id=\"api-changes-in-the-typescript-packages\">API changes in the TypeScript packages</h3>\n<p>If you develop plugins or embed Perses, these changes in the <code>@perses-dev/*</code> packages may require an update:</p>\n<ul>\n<li><code>useDeepMemo</code> and <code>useMemoized</code> are removed, use React <code>useMemo</code> instead. The <code>spec</code> of a <code>Resource</code> and the cell\nvalues of <code>TableColumnConfig</code> are now <code>unknown</code> instead of <code>any</code> (<a href=\"https://github.com/perses/shared/pull/310\">perses/shared#310</a>).</li>\n<li><code>useId</code> is no longer exported from <code>@perses-dev/components</code>, use React <code>useId()</code> instead\n(<a href=\"https://github.com/perses/shared/pull/348\">perses/shared#348</a>).</li>\n<li>Zod schemas are typed with <code>z.ZodType&#x3C;T, T></code> instead of <code>z.ZodType&#x3C;T></code> or the deprecated <code>z.ZodSchema&#x3C;T></code>\n(<a href=\"https://github.com/perses/shared/pull/282\">perses/shared#282</a>, <a href=\"https://github.com/perses/spec/pull/95\">perses/spec#95</a>).</li>\n<li>The <code>PanelEditorValues</code> type and its schema are removed from <code>@perses-dev/spec</code>, use the ones from\n<code>@perses-dev/plugin-system</code> (<a href=\"https://github.com/perses/spec/pull/59\">perses/spec#59</a>).</li>\n<li>Annotations are now fetched on demand, only by the panels displaying them\n(<a href=\"https://github.com/perses/shared/pull/330\">perses/shared#330</a>). The <code>annotationState</code> store field and the\n<code>setAnnotationState</code> action are removed, and <code>usePanelAnnotationsWithData</code> no longer returns hidden annotations.</li>\n</ul>\n<h3 id=\"security-changes\">Security changes</h3>\n<p>Some of the <a href=\"https://perses.dev/blog/2026/10/21/release-v0550/#security\">security fixes</a> require a configuration change on your side:</p>\n<ul>\n<li><strong>Encryption key</strong>: if authentication is enabled, <code>security.encryption_key</code> (or <code>security.encryption_key_file</code>) must be\nset, otherwise Perses won't start. If you were relying on the default key, the secrets previously stored can no longer\nbe decrypted and must be re-created, and users will have to log in again.</li>\n<li><strong>Datasource proxy destinations</strong>: datasources pointing to loopback, link-local addresses, cloud metadata endpoints or\nthe Kubernetes API are now rejected. If you rely on such datasources (e.g. a Prometheus running next to Perses on\n<code>localhost</code>), allow them through <code>datasource.proxy.allowed_networks</code> or <code>datasource.proxy.allowed_hosts</code>. URLs\ncontaining credentials (<code>https://user:password@host</code>) are also refused: use a secret instead.</li>\n<li><strong>Files referenced in secrets</strong>: they are rejected by default. List the directories containing them in\n<code>security.secret_file_allowed_directories</code>.</li>\n<li><strong>Resource names</strong>: a name can no longer contain <code>..</code>, nor start or end with <code>.</code>\n(<a href=\"https://github.com/perses/spec/pull/102\">perses/spec#102</a>). Rename the resources using such a name.</li>\n<li><strong>Proxy headers</strong>: the <code>Authorization</code> header of the caller is no longer forwarded to the datasource when the native\nauthorization is enabled, and the UI of a datasource can no longer be browsed through the proxy.</li>\n</ul>\n<p>See the <a href=\"https://perses.dev/docs/perses/latest/upgrade/v0.55.0/\">upgrade guide</a> for more details.</p>\n<h2 id=\"performance-improvements\">Performance improvements</h2>\n<p>This release comes with several performance improvements on the backend. The numbers below come from the benchmarks\nshared in the corresponding pull requests.</p>\n<h3 id=\"datasource-proxy-reuses-its-connections\">Datasource proxy reuses its connections</h3>\n<p>Until now, the proxy created a new HTTP transport for every proxied request, so no TCP or TLS connection was ever\nreused. Perses now keeps one transport per saved datasource\n(<a href=\"https://github.com/perses/perses/pull/4521\">#4521</a>), which is particularly visible with HTTPS datasources:</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Case</th><th>Before</th><th>After</th><th>Gain</th></tr></thead><tbody><tr><td>HTTP, sequential</td><td>153 µs/op</td><td>70 µs/op</td><td>~2.2x</td></tr><tr><td>HTTP, parallel (10 CPUs)</td><td>60 µs/op</td><td>22 µs/op</td><td>~2.8x</td></tr><tr><td>HTTPS, sequential</td><td>1.69 ms/op</td><td>72 µs/op</td><td><strong>~23x</strong></td></tr><tr><td>HTTPS, parallel (10 CPUs)</td><td>295 µs/op</td><td>23 µs/op</td><td><strong>~13x</strong></td></tr></tbody></table>\n<p>It also uses ~4x less memory per request. On a real network, each request additionally saves the round trips of the\nTCP and TLS handshakes. The connection limits can be tuned with the new <code>datasource.proxy.http</code> configuration:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">datasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  proxy</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    http</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      max_conns_per_host</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\"> # 0 = no limit</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      max_idle_conns</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">100</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      max_idle_conns_per_host</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10</span></span></code></pre>\n<h3 id=\"faster-native-authorization\">Faster native authorization</h3>\n<p>The permission cache of the native authorization is rebuilt at startup, periodically, on every RBAC change and on the\nfirst login of every OAuth/OIDC user. Its build now runs in linear time\n(<a href=\"https://github.com/perses/perses/pull/4540\">#4540</a>). With 10,000 users and 1,000 projects:</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Benchmark</th><th>Before</th><th>After</th><th>Delta</th></tr></thead><tbody><tr><td>Cache refresh</td><td>2.81 s</td><td>21 ms</td><td><strong>−99.25%</strong></td></tr><tr><td>25 simultaneous first OAuth logins</td><td>12.68 s</td><td>149 ms</td><td><strong>−98.82%</strong></td></tr></tbody></table>\n<p>The cache is now also an immutable snapshot read without any lock\n(<a href=\"https://github.com/perses/perses/pull/4537\">#4537</a>). It fixes a deadlock that could hang every authorization check\nuntil a restart, and makes permission checks under concurrent load <strong>~7x faster</strong> (from ~145 ns to ~20 ns per check).</p>\n<h3 id=\"faster-plugin-extraction-at-startup\">Faster plugin extraction at startup</h3>\n<p>Plugin archives are now extracted in parallel (<a href=\"https://github.com/perses/perses/pull/4507\">#4507</a>), and the ones\nalready extracted are skipped (<a href=\"https://github.com/perses/perses/pull/4534\">#4534</a>). With the default plugins (32\narchives, ~9,000 files), the extraction step goes from <strong>~1–2 s to ~1 ms</strong> when the archives are already extracted, and\nthe whole plugin initialization from ~1.35 s to ~0.3 s.</p>\n<p>Skipping the archives benefits binary installations and deployments where the plugin folder is kept between restarts\n(e.g. mounted on a volume). With the official container image and its default setup, every new container still extracts\nall archives, but in parallel.</p>\n<h3 id=\"better-browser-caching-of-static-assets\">Better browser caching of static assets</h3>\n<p>Content-hashed JS and CSS bundles (<a href=\"https://github.com/perses/perses/pull/4475\">#4475</a>), as well as fonts and images\nfrom the app and the plugins (<a href=\"https://github.com/perses/perses/pull/4533\">#4533</a>), are now served as immutable assets.\nBrowsers no longer download or revalidate them on every page load.</p>\n<h2 id=\"dashboard-lock-mode\">Dashboard lock mode</h2>\n<p>Dashboards don't pin the version of the plugins they use, so a plugin upgrade can change how a panel looks. The new lock\nmode (<a href=\"https://github.com/perses/shared/pull/243\">perses/shared#243</a>) pins every plugin of a dashboard to the latest\ninstalled version. When a newer version is available, a button lets you update the plugins, with a preview of the\nchange based on the first panel using it. If a pinned version is no longer installed, an error is displayed.</p>\n<p>The panel type selector also shows the plugin version when several versions are installed.</p>\n<p>The feature is disabled by default (<a href=\"https://github.com/perses/perses/pull/4370\">#4370</a>):</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">frontend</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  enable_lock_mode</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span></code></pre>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/lock-mode-update.png\" alt=\"Update locked plugins\"></p>\n<h2 id=\"drag-and-drop-panels-between-panel-groups\">Drag and drop panels between panel groups</h2>\n<p>The grid layout library has been replaced by Snapgrid (<a href=\"https://github.com/perses/shared/pull/296\">perses/shared#296</a>),\nso panels can now be dragged from one panel group to another. Drag and drop in lists (e.g. item actions) is also only\ntriggered from the drag handle, so you can select text again (<a href=\"https://github.com/perses/shared/pull/335\">perses/shared#335</a>).</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/drag-and-drop.gif\" alt=\"Drag and drop panels between panel groups\"></p>\n<h2 id=\"panel-repeat\">Panel repeat</h2>\n<p>Until now, only a panel group could be repeated over the values of a variable. A single panel can now be repeated as\nwell (<a href=\"https://github.com/perses/spec/pull/32\">perses/spec#32</a>,\n<a href=\"https://github.com/perses/shared/pull/149\">perses/shared#149</a>). In the <code>Layout</code> tab of the panel editor, choose the\nvariable, the alignment (<code>horizontal</code> or <code>vertical</code>) and the maximum number of panels per row or column:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">layouts</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">Grid</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      items</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">x</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">          y</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          width</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">12</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          height</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">6</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          content</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">            $ref</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'#/spec/panels/cpu'</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          repeatVariable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">            value</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">instance</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">            alignment</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">horizontal</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">            maxPer</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">4</span></span></code></pre>\n<p>Only the selected values are used, and a group repeat takes precedence over a panel repeat. Repeated panels are also\nsupported by the Grafana migration (<a href=\"https://github.com/perses/perses/pull/4328\">#4328</a>).</p>\n<video controls>\n  <source src=\"https://perses.dev/assets/images/blog/v055/panel-repeat.mp4\" type=\"video/mp4\">\n  Your browser does not support the video tag.\n</video>\n<h2 id=\"panel-level-annotations\">Panel-level annotations</h2>\n<p>v0.54.0 introduced annotations at the dashboard level. They can now be defined on a panel as well\n(<a href=\"https://github.com/perses/spec/pull/61\">perses/spec#61</a>, <a href=\"https://github.com/perses/shared/pull/206\">perses/shared#206</a>,\n<a href=\"https://github.com/perses/perses/pull/4356\">#4356</a>). The panel displays the dashboard annotations plus its own ones.</p>\n<p>A new <code>Annotations</code> tab is available in the panel editor for the plugins supporting it. For now, only the\n<code>TimeSeriesChart</code> does (<a href=\"https://github.com/perses/plugins/pull/754\">perses/plugins#754</a>). Panel annotations are\nvalidated by the backend like the dashboard ones (<a href=\"https://github.com/perses/perses/pull/4299\">#4299</a>), and the Go SDK\ncan now build both of them (<a href=\"https://github.com/perses/perses/pull/4448\">#4448</a>).</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/panel-annotations.png\" alt=\"Panel annotations editor\"></p>\n<h2 id=\"exemplars-support\">Exemplars support</h2>\n<p>The Prometheus datasource can now fetch <a href=\"https://prometheus.io/docs/prometheus/latest/feature_flags/#exemplars-storage\">exemplars</a>\n(<a href=\"https://github.com/perses/plugins/pull/799\">perses/plugins#799</a>). It is disabled by default and must be enabled per\ndatasource:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">GlobalDatasource</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">metadata</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">prometheus</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  plugin</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">PrometheusDatasource</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      exemplars</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        enable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      proxy</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">HTTPProxy</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          url</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">https://prometheus.example.com</span></span></code></pre>\n<p>Exemplars are then fetched with range queries and displayed by the <code>TimeSeriesChart</code> as diamonds on top of their series\n(<a href=\"https://github.com/perses/plugins/pull/800\">perses/plugins#800</a>). Hovering one shows its labels (e.g. the trace ID),\nvalue and timestamp, and clicking it pins the tooltip (<a href=\"https://github.com/perses/shared/pull/278\">perses/shared#278</a>).</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/exemplars.png\" alt=\"Exemplars in a TimeSeriesChart\"></p>\n<h2 id=\"improved-search-experience\">Improved search experience</h2>\n<p>The search is now done by the backend, through the new endpoint <code>/api/v1/search/dashboards</code>\n(<a href=\"https://github.com/perses/perses/pull/4355\">#4355</a>). Dashboards are indexed in memory and matched with a fuzzy search.\nWith a SQL database, every Perses instance periodically checks for changes to keep its index in sync. By default, the\nname and the display name are indexed, but you can index any attribute, like the panel names:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">search</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  index_keys</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    dashboard</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">metadata.name</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">spec.display.name</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">spec.panels.@dig:display.name</span></span></code></pre>\n<p>The project view also uses this endpoint to list the dashboards, without loading their full definition\n(<a href=\"https://github.com/perses/perses/pull/4366\">#4366</a>), and its search bar now matches tags too\n(<a href=\"https://github.com/perses/perses/pull/4446\">#4446</a>).</p>\n<p>Finally, the important dashboards of the home page can be organized in groups, and an entire project can be marked as\nimportant (<a href=\"https://github.com/perses/perses/pull/4506\">#4506</a>). The previous flat list is still supported but\ndeprecated.</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">frontend</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  important_dashboards</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">Perses demos</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      dashboards</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">perses</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">testing</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">Quick links</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      description</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">Highlighted dashboards</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      dashboards</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">perses</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          dashboard</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">nodeexporter</span></span></code></pre>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/important-dashboards.png\" alt=\"Grouped important dashboards\"></p>\n<h2 id=\"authentication-authorization\">Authentication &#x26; authorization</h2>\n<ul>\n<li>\n<p><strong>Roles from OAuth/OIDC claims</strong> (<a href=\"https://github.com/perses/perses/pull/4172\">#4172</a>): roles can be assigned from the\nclaims of the identity provider token, without creating any RoleBinding. Without <code>project</code>, the role is a GlobalRole.</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">security</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  authentication</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    providers</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      oidc</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">slug_id</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">keycloak</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">          # ...</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          claims</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">claim_name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">roles</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">              mappings</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">claim_value</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">admin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">                  role_name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">admin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">                - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">claim_value</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">ops</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">                  role_name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">editor</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">                  project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">platform</span></span></code></pre>\n</li>\n<li>\n<p><strong>OAuth pass-through</strong> (<a href=\"https://github.com/perses/perses/pull/4404\">#4404</a>): with <code>oauthPassThrough: true</code> in its\n<code>HTTPProxy</code>, a datasource is queried with the OAuth/OIDC token of the current user. The token is refreshed when needed.</p>\n</li>\n<li>\n<p><strong>Kubernetes impersonation</strong> (<a href=\"https://github.com/perses/perses/pull/4339\">#4339</a>): with the Kubernetes authorization,\nthe <code>Impersonate-User</code> header is honored if the caller is allowed to impersonate this user.</p>\n</li>\n<li>\n<p><strong>Pre-hashed passwords</strong> (<a href=\"https://github.com/perses/perses/pull/4423\">#4423</a>): users can be provisioned with a bcrypt\nhash (<code>spec.nativeProvider.passwordHash</code>) instead of a cleartext password.</p>\n</li>\n<li>\n<p><strong>OIDC login property</strong> (<a href=\"https://github.com/perses/perses/pull/4468\">#4468</a>): like the OAuth provider, the OIDC\nprovider supports <code>custom_login_property</code> to choose the user info field used as login (e.g. <code>preferred_username</code>).</p>\n</li>\n</ul>\n<h2 id=\"http-proxy-improvements\">HTTP proxy improvements</h2>\n<p>The HTTP proxy used by the datasources received a lot of attention in this release: it is safer, faster and more\nconfigurable.</p>\n<h3 id=\"header-filtering-policies\">Header filtering policies</h3>\n<p>Some datasources don't play well with certain headers sent by the browser or added by Perses (e.g. <code>X-Forwarded-For</code>).\nThe <code>HTTPProxy</code> spec now supports two optional header policies\n(<a href=\"https://github.com/perses/perses/pull/4428\">#4428</a>):</p>\n<ul>\n<li><code>allowHeaders</code>: only the listed headers are forwarded to the datasource.</li>\n<li><code>dropHeaders</code>: the listed headers are removed, and the others are forwarded.</li>\n</ul>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">Datasource</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">metadata</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">prometheus</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">my-project</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  default</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  plugin</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">PrometheusDatasource</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      proxy</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">HTTPProxy</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          url</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">https://prometheus.example.com</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          dropHeaders</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">X-Forwarded-For</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">User-Agent</span></span></code></pre>\n<p>Header names are case-insensitive and only one of the two lists can be set. The filtering is applied after the headers\ndefined in the datasource, but before the secret authentication, so there is no need to allow <code>Authorization</code> when the\ndatasource uses a secret.</p>\n<h3 id=\"configurable-timeout\">Configurable timeout</h3>\n<p>The <code>HTTPProxy</code> spec also accepts a new optional <code>timeout</code> field, available in the datasource editor as well\n(<a href=\"https://github.com/perses/perses/pull/4525\">#4525</a>). To avoid letting users hold goroutines and sockets against\nunreachable hosts for too long, the timeout of a datasource is bounded by the server configuration:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">datasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  proxy</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    http</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      default_timeout</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">30s</span><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\"> # used when the datasource doesn't define a timeout</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      max_timeout</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">1m</span><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\"> # highest timeout a datasource can define</span></span></code></pre>\n<p>A datasource defining a timeout greater than <code>max_timeout</code> is rejected when it is saved, and its timeout is clamped when\nit is used.</p>\n<h3 id=\"security-hardening\">Security hardening</h3>\n<p>As described in the <a href=\"https://perses.dev/blog/2026/10/21/release-v0550/#security\">Security</a> section, the proxy has been hardened in many ways:</p>\n<ul>\n<li>its destination is verified against a list of allowed and denied networks/hosts (loopback, link-local, cloud metadata\nendpoints and Kubernetes API denied by default), configurable through <code>datasource.proxy</code>. The allowed schemes can be\nrestricted with <code>datasource.proxy.http.allowed_schemes</code>;</li>\n<li>the <code>Cookie</code> header of the caller is never forwarded, and neither is the <code>Authorization</code> header when the native\nauthorization is enabled. An <code>Authorization</code> header defined in the <code>headers</code> of a datasource is ignored: use a secret\ninstead;</li>\n<li>its responses are sandboxed with a strict <code>Content-Security-Policy</code>, and the headers applying to the Perses origin are\nremoved.</li>\n</ul>\n<p>Some of these changes may require a configuration update, check the <a href=\"https://perses.dev/blog/2026/10/21/release-v0550/#security-changes\">Security changes</a> section and\nthe <a href=\"https://perses.dev/docs/perses/latest/concepts/proxy/\">proxy documentation</a> for more details.</p>\n<h3 id=\"connection-reuse\">Connection reuse</h3>\n<p>Finally, the proxy now keeps one HTTP transport per datasource and reuses its connections, making HTTPS requests up to\n~23x faster. See <a href=\"https://perses.dev/blog/2026/10/21/release-v0550/#datasource-proxy-reuses-its-connections\">Datasource proxy reuses its connections</a> for the numbers\nand the new connection limits.</p>\n<h2 id=\"refresh-interval-configuration\">Refresh interval configuration</h2>\n<p>The auto-refresh options of the dashboards can now be configured (<a href=\"https://github.com/perses/perses/pull/4432\">#4432</a>),\nor the auto-refresh can be disabled entirely (<a href=\"https://github.com/perses/perses/pull/4338\">#4338</a>). In that case, the\ninterval picker is hidden and the <code>refreshInterval</code> of the dashboards, as well as the <code>?refresh=</code> URL parameter, are\nignored.</p>\n<p>Similarly, administrators can define the default timezone, theme and number of rows per page, used when a user hasn't\nchosen their own (<a href=\"https://github.com/perses/perses/pull/4268\">#4268</a>).</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">frontend</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  auto_refresh</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    options</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: [</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"0s\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"30s\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"1m\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"5m\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">]</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  default_user_preferences</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    timezone</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">UTC</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    theme</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">dark</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    rows_per_page</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">50</span></span></code></pre>\n<h2 id=\"provisioning-improvements\">Provisioning improvements</h2>\n<ul>\n<li>Perses can now watch the provisioning folders and apply the changes right away, instead of waiting for the next\ninterval (<a href=\"https://github.com/perses/perses/pull/4136\">#4136</a>). Resources are also only updated when they actually\nchanged, which avoids unnecessary writes and ever-increasing versions.</li>\n<li>A provisioning file can contain several resources separated by <code>---</code> (<a href=\"https://github.com/perses/perses/pull/4332\">#4332</a>).</li>\n</ul>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">provisioning</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  enable_watch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  folders</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">/etc/perses/provisioning</span></span></code></pre>\n<h2 id=\"cli-improvements\">CLI improvements</h2>\n<ul>\n<li>The new command <code>percli dac watch</code> rebuilds your Dashboard-as-Code files on every change, including the dashboards\ndepending on a modified library file (<a href=\"https://github.com/perses/perses/pull/3903\">#3903</a>). Combined with the\nprovisioning watch mode, it gives you a live reload of your dashboards.</li>\n<li><code>percli dac preview</code> supports the <code>--create-project</code> flag, like <code>percli apply</code>\n(<a href=\"https://github.com/perses/perses/pull/4413\">#4413</a>).</li>\n</ul>\n<h2 id=\"dashboard-and-plugin-schemas-api\">Dashboard and plugin schemas API</h2>\n<p>Perses now exposes the CUE schemas of the dashboards and of the installed plugins\n(<a href=\"https://github.com/perses/perses/pull/4505\">#4505</a>). It is particularly useful for tools generating dashboards, like\nthe <a href=\"https://github.com/perses/mcp-server\">Perses MCP server</a>:</p>\n<ul>\n<li><code>GET /api/v1/schemas/dashboards</code>: the complete dashboard schema, including the plugin schemas.</li>\n<li><code>GET /api/v1/schemas/plugins</code>: the schemas of all plugins.</li>\n<li><code>GET /api/v1/schemas/plugins/&#x3C;plugin_name></code>: the schema of a single plugin, with the optional <code>version</code> and\n<code>registry</code> query parameters.</li>\n</ul>\n<h2 id=\"datasource-improvements\">Datasource improvements</h2>\n<p>The datasource editor has a new <code>Test Connection</code> button to check the datasource is reachable before saving it\n(<a href=\"https://github.com/perses/perses/pull/4396\">#4396</a>, <a href=\"https://github.com/perses/shared/pull/99\">perses/shared#99</a>).\nIt is available for Prometheus (<a href=\"https://github.com/perses/plugins/pull/620\">perses/plugins#620</a>), OpenSearch\n(<a href=\"https://github.com/perses/plugins/pull/797\">perses/plugins#797</a>) and AlertManager\n(<a href=\"https://github.com/perses/plugins/pull/798\">perses/plugins#798</a>).</p>\n<video controls>\n  <source src=\"https://perses.dev/assets/images/blog/v055/test-connection.mp4\" type=\"video/mp4\">\n  Your browser does not support the video tag.\n</video>\n<p>The Kubernetes datasource discovery can also mark a discovered datasource as the default one, based on its labels or\nannotations (<a href=\"https://github.com/perses/perses/pull/4368\">#4368</a>):</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">datasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  global</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    discovery</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">prometheus</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        kubernetes_sd</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">          # ...</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">          default</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">            enable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">            labels</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">              app.kubernetes.io/name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">prometheus</span></span></code></pre>\n<h2 id=\"new-plugins\">New plugins</h2>\n<h3 id=\"canvas\">Canvas</h3>\n<p>The Canvas panel (<a href=\"https://github.com/perses/plugins/pull/729\">perses/plugins#729</a>) is a free-form diagram editor to\nbuild weathermap-like visualizations. Place nodes, connect them with edges and add background shapes or images. Nodes\nand edges can be bound to a query: their color then follows thresholds and the edge thickness can scale with the value.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/canvas.png\" alt=\"Canvas weathermap\"></p>\n<h3 id=\"json\">Json</h3>\n<p>The new JSON datasource and query (<a href=\"https://github.com/perses/plugins/pull/770\">perses/plugins#770</a>) can query any HTTP\nendpoint returning JSON, with <code>GET</code> or <code>POST</code>, query parameters and variables. The response can be transformed with a\n<a href=\"https://jsonata.org/\">JSONata</a> expression, and the result displayed in a <code>Table</code> panel.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/json-query.png\" alt=\"JSON query\"></p>\n<h2 id=\"plugin-improvements\">Plugin improvements</h2>\n<ul>\n<li><strong>TimeSeriesChart</strong>:\n<ul>\n<li>the color palette can be selected again (<a href=\"https://github.com/perses/plugins/pull/845\">perses/plugins#845</a>). <code>Auto</code>\nkeeps the current color by series name, the categorical palettes give more distinct colors.</li>\n<li>rendering is faster, especially with many series (<a href=\"https://github.com/perses/plugins/pull/832\">perses/plugins#832</a>).</li>\n</ul>\n</li>\n<li><strong>StatChart</strong>: multiple series are laid out in a grid adapting to the panel size, instead of a single row\n(<a href=\"https://github.com/perses/plugins/pull/812\">perses/plugins#812</a>, <a href=\"https://github.com/perses/plugins/pull/814\">perses/plugins#814</a>).\nTheir values and legends also share the same font size, which can be customized (<a href=\"https://github.com/perses/plugins/pull/778\">perses/plugins#778</a>).</li>\n<li><strong>Table</strong>: sorting can be enabled for all columns at once (<a href=\"https://github.com/perses/plugins/pull/759\">perses/plugins#759</a>),\nand the new <code>PivotByLabel</code> transform turns series into a time × label matrix (<a href=\"https://github.com/perses/shared/pull/288\">perses/shared#288</a>).</li>\n<li><strong>BarChart</strong>: colors can be overridden with regexes on the series or bar names (<a href=\"https://github.com/perses/plugins/pull/774\">perses/plugins#774</a>).</li>\n<li><strong>PieChart</strong>: the inner and outer radius can be configured, e.g. to display a donut (<a href=\"https://github.com/perses/plugins/pull/823\">perses/plugins#823</a>).</li>\n<li><strong>Markdown</strong>: external links open in a new tab (<a href=\"https://github.com/perses/plugins/pull/815\">perses/plugins#815</a>).</li>\n<li><strong>Prometheus</strong>: a query can be executed as an instant query, regardless of the panel (<a href=\"https://github.com/perses/plugins/pull/752\">perses/plugins#752</a>).</li>\n<li><strong>Pyroscope</strong>: profiles are queried through the Connect API instead of the legacy <code>/render</code> endpoint\n(<a href=\"https://github.com/perses/plugins/pull/763\">perses/plugins#763</a>). The minimum step can be configured on the\ndatasource (<a href=\"https://github.com/perses/plugins/pull/810\">perses/plugins#810</a>), and the profile types and labels\nproposed are restricted to the selected service (<a href=\"https://github.com/perses/plugins/pull/820\">perses/plugins#820</a>,\n<a href=\"https://github.com/perses/plugins/pull/835\">perses/plugins#835</a>).</li>\n</ul>\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>TimeSeriesChart color palette</th><th>StatChart grid layout</th></tr></thead><tbody><tr><td><img src=\"https://perses.dev/assets/images/blog/v055/palette.png\" alt=\"TimeSeriesChart color palette\"></td><td><img src=\"https://perses.dev/assets/images/blog/v055/statchart-layout.png\" alt=\"StatChart grid layout\"></td></tr></tbody></table>\n<h2 id=\"other-improvements\">Other improvements</h2>\n<ul>\n<li>\n<p><strong>Duplicate a dashboard into another project</strong> (<a href=\"https://github.com/perses/perses/pull/4536\">#4536</a>), including from\na project where you only have read access.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v055/duplicate-dashboard.png\" alt=\"Duplicate a dashboard into another project\"></p>\n</li>\n<li>\n<p><strong>Open in a new tab</strong>: the project and admin tabs, as well as the ephemeral dashboards, are now real links\n(<a href=\"https://github.com/perses/perses/pull/4252\">#4252</a>).</p>\n</li>\n<li>\n<p><strong>Page title</strong>: the browser tab title now reflects the current page (<a href=\"https://github.com/perses/perses/pull/4489\">#4489</a>).</p>\n</li>\n<li>\n<p><strong>Collapsed panel groups</strong> show the number of panels they contain (<a href=\"https://github.com/perses/shared/pull/309\">perses/shared#309</a>).</p>\n</li>\n<li>\n<p><strong>Custom unit label</strong>: a panel can display its own unit label (e.g. <code>trx/s</code>) while keeping the formatting of a\nstandard unit (<a href=\"https://github.com/perses/shared/pull/297\">perses/shared#297</a>).</p>\n</li>\n<li>\n<p><strong>Grafana migration</strong>: the default time range, the refresh interval and the timezone of the Grafana dashboard are kept\n(<a href=\"https://github.com/perses/perses/pull/4555\">#4555</a>). Table thresholds are migrated to cell settings\n(<a href=\"https://github.com/perses/plugins/pull/808\">perses/plugins#808</a>), and datasource variables for Jaeger and\nOpenSearch are supported (<a href=\"https://github.com/perses/plugins/pull/769\">perses/plugins#769</a>).</p>\n</li>\n<li>\n<p><strong>Compressed requests</strong>: the API accepts request bodies compressed with gzip (<code>Content-Encoding: gzip</code>)\n(<a href=\"https://github.com/perses/perses/pull/4381\">#4381</a>).</p>\n</li>\n<li>\n<p><strong>Custom fetch</strong>: apps embedding Perses can override the <code>fetch</code> used by the client and the datasources through a\nfetch provider, e.g. to add custom headers (<a href=\"https://github.com/perses/shared/pull/214\">perses/shared#214</a>,\n<a href=\"https://github.com/perses/shared/pull/316\">perses/shared#316</a>, <a href=\"https://github.com/perses/plugins/pull/854\">perses/plugins#854</a>).</p>\n</li>\n</ul>",
      "date_published": "2026-10-21T00:00:00Z",
      "tags": [
        "Release notes"
      ]
    },
    {
      "id": "https://perses.dev/blog/2026/07/29/release-v0540/",
      "url": "https://perses.dev/blog/2026/07/29/release-v0540/",
      "title": "Release v0.54.0",
      "summary": "Welcome in the v0.54.0 release !",
      "content_html": "\n<p>Welcome in the v0.54.0 release !</p>\n<p>First of all this release includes several security fixes that patches some breach in the permission system included in\nPerses, so we strongly recommend to upgrade to this version as soon as possible.</p>\n<p>Then, you will be happy to know that this release includes new plugins: Jaeger, GreptimeDB, Splunk, LogExplorer,\nAlertManager and OpenSearch.</p>\n<p>As adding more plugins is increasing the size of the container image, likely we will remove some of them in future\nrelease. It does not mean we will remove the support for these plugins, it is just we won't include them into the\ndefault image. You will have to add them manually. The drop will occur once we are able to provide a good way to add\nplugins to an existing installation without having to rebuild the image. In the meantime, if you don't want to use these\nplugins, you can choose to enable or disable them by configuration.</p>\n<p>We are also happy to announce it includes the long awaited sub-folder system to better organize your dashboards and\nimprove the accessibility by adding keyboard shortcuts.</p>\n<p>This release is also the last release for the package <code>@perses-dev/core</code> that is now deprecated. For that we are\nintroducing two new packages <code>@perses-dev/spec</code> and <code>@perses-dev/client</code>.</p>\n<ul>\n<li><code>@perses-dev/spec</code> contains the dashboard and datasource specifications.</li>\n<li><code>@perses-dev/client</code> contains the client to interact with the Perses API.</li>\n</ul>\n<p>The code from <code>@perses-dev/core</code> has been dispatched in these these two packages and in others (like\n<code>@perses-dev/plugin-system</code> and <code>@perses-dev/components</code>) to better separate the concerns and make it easier to\nmaintain.</p>\n<p>Finally, thank you to all the contributors who made this release possible, you are more and more, and we are really\nhappy to see the community growing and contributing to make Perses better and better!</p>\n<p>As usual, this blog post does not cover all the changes and improvements included in this release. We are only talking\nabout the changes that should interest you the most. If you want to have a complete list of all the changes, please\nrefer to the <a href=\"https://github.com/perses/perses/releases/tag/v0.54.0\">changelog</a></p>\n<!-- more -->\n<h2 id=\"security-issues\">Security issues</h2>\n<p>On top of the various features and improvements, we have fixed several security issues in this release that compromised\nthe permission system of the Perses application. We strongly recommend to upgrade to this version as soon as possible.</p>\n<h3 id=\"use-query-parameter-project-to-list-resources-without-having-access-to-cve-2026-63458\">Use query parameter project to list resources without having access to (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-cjgj-2fwf-4c2w\">CVE-2026-63458</a>)</h3>\n<p>In previous versions, it was possible to list resources (dashboards, datasources, etc.) that you don't have access to by\nusing the query parameter <code>project</code> in the API.</p>\n<p>For example, if you have access to the project <code>project-a</code> but not to <code>project-b</code>, you could list all dashboards in\n<code>project-b</code> by calling the API endpoint <code>/api/v1/dashboards?project=project-b</code>. This would return a list of dashboards\nin <code>project-b</code> even if you don't have access to that project.</p>\n<p>Now, if you try to list resources that you don't have access to, you will get a 403 Forbidden error.</p>\n<h3 id=\"unvalidated-project-parameter-enables-filesystem-path-traversal-cve-2026-63445\">Unvalidated project parameter enables filesystem path traversal (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-vr5f-w35q-98jp\">CVE-2026-63445</a>)</h3>\n<p>In previous versions, it was possible to use the <code>project</code> query parameter to access files outside the Perses\ninstallation directory. This could be exploited by an attacker to read sensitive files on the server.</p>\n<p>It was also possible to use this query parameter to get access to other resources contained in the database by using a\nproject name that contains a path traversal sequence (e.g. <code>../secrets</code>).</p>\n<p>For example <code>/api/v1/dashboards?project=../projects</code> returns the list of the project while it must not return anything.</p>\n<p>Now, if you try to use a project name that contains a path traversal sequence, you will get a 400 Bad Request error.</p>\n<p>Note that this attack is not possible if you are using an SQL database instead of the default fileSystem database.</p>\n<h3 id=\"missing-authorization-in-datasource-proxy-allows-cross-scope-secret-disclosure-cve-2026-63199\">Missing authorization in datasource proxy allows cross-scope secret disclosure (<a href=\"https://github.com/perses/perses/security/advisories/GHSA-4227-9989-jrhx\">CVE-2026-63199</a>)</h3>\n<p>In previous versions, it was possible to contact datasources protected by secrets that you don't necessary have access\nto by using the datasource proxy.</p>\n<p>This was because the datasource proxy did not check if you have access to the secret used to connect to the datasource\nwhile testing the connection to the same datasource.</p>\n<p>Now, if you are creating a datasource or testing a connection to a datasource, the datasource proxy will check if you\nhave access to the secret used to connect to the datasource. If you don't have access to the secret, you will get a 403\nForbidden error.</p>\n<h2 id=\"introduction-of-the-perses-specification\">Introduction of the Perses specification</h2>\n<p>We have created a new repository called <a href=\"https://github.com/perses/spec\">perses/spec</a> that contains the Dashboard and\nDatasource specifications in different languages (Go, TypeScript, Cuelang).</p>\n<p>The goal of this repository is to provide a single source of truth for the specifications and make it easier for\ndevelopers to work with them in different programming languages, independently of the Perses project.</p>\n<p>The specifications are now used in the Perses app, the Go and CUE SDKs, and the CLI. This means that if you use the SDKs\nand/or the CLI, you will need to update your code to use the new specifications and upgrade the CLI to v0.54.0.</p>\n<h2 id=\"package-perses-devcore-deprecation\">Package <code>@perses-dev/core</code> deprecation</h2>\n<p>As part of the introduction of the Perses specification, we are deprecating the package <code>@perses-dev/core</code>. We have\ncreated a final version of this package that is compatible with the new specifications and will be available in the npm\nregistry. However, we recommend migrating your code to use the new specifications instead of using this package.</p>\n<p>Also, if you are using the <code>@perses-dev/core</code> package in your code, you may be using more than just the specifications.\nIn this case, you will also need to update your imports to use the new <code>@perses-dev/client</code> package.</p>\n<p>Please read the <a href=\"https://perses.dev/docs/perses/latest/upgrade/v0.54.0/\">migration guide</a> for more details about how to migrate\nyour code to use the new specifications and the new package.</p>\n<h2 id=\"enable-or-disable-plugins-through-configuration\">Enable or disable plugins through configuration</h2>\n<p>As we are adding more and more plugins to Perses, we have introduced a new configuration option to enable or disable\nplugins. This gives users more fine-grained control over which plugins are available in their Perses instance and\nreduces noise and issues caused by unused plugins.</p>\n<p>For example, with the following configuration:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">plugin</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  disabled</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"pyroscope\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"victoriaLogs\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"clickHouse\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"tempo\"</span></span></code></pre>\n<p>Prometheus will be the only datasource enabled in the default Perses installation.</p>\n<p>Another way to achieve the same result is to explicitly enable only the plugins you want to use:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">plugin</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  enabled</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"prometheus\"</span></span></code></pre>\n<p>In this example, only the Prometheus plugin will be enabled and all other plugins will be disabled.</p>\n<p>Note that, a consequence of this configuration is that every panels, variables and queries are also disabled.</p>\n<p>This also means that if you add a new plugin in the future, it will be disabled by default, and you will need to\nexplicitly enable it in the configuration.</p>\n<h2 id=\"annotations\">Annotations</h2>\n<p>Perses now supports annotations, which add information such as events to panels.</p>\n<p>Panels must support annotations; for now, only the TimeSeries Chart panel does. In addition, only annotations based on\nPrometheus PromQL are supported. However, thanks to the Perses plugin architecture, support for annotations can easily\nbe added to any datasource (as source of data) or panel (for the display).</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/annotation-editor.png\" alt=\"TimeSeries Chart Editor\">\n<img src=\"https://perses.dev/assets/images/blog/v054/annotations.png\" alt=\"TimeSeries Chart Annotation\"></p>\n<h2 id=\"keyboard-shortcuts\">Keyboard shortcuts</h2>\n<p>Perses v0.54.0 introduces built-in keyboard shortcuts to help you navigate and operate dashboards faster without having\nto using a mouse. Press <code>?</code> anywhere in the UI to open the shortcuts help modal, which lists all available shortcuts\ngrouped by category.</p>\n<p>Some highlights:</p>\n<ul>\n<li><strong><code>?</code></strong> — Open the keyboard shortcuts help modal</li>\n<li><strong><code>Ctrl</code>/<code>⌘</code> + <code>K</code></strong> — Open the search dialog</li>\n<li><strong><code>G</code> + <code>H</code></strong> — Go to the Home page</li>\n<li><strong><code>Ctrl</code>/<code>⌘</code> + <code>S</code></strong> — Save the current dashboard</li>\n<li><strong><code>D</code> + <code>M</code></strong> — Toggle between edit and view mode</li>\n<li><strong><code>E</code></strong> — Edit the focused panel (in edit mode)</li>\n<li><strong><code>V</code></strong> — Toggle fullscreen on the focused panel</li>\n</ul>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/keyboard-shortcuts.gif\" alt=\"Keyboard shortcuts in action\"></p>\n<p>Keyboard shortcuts are enabled by default. To disable them, set the following in your Perses configuration:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">frontend</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  enable_keyboard_shortcuts</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span></span></code></pre>\n<h2 id=\"sub-folder-support\">Sub-folder support</h2>\n<p>Perses now supports folders — a way to organise dashboards within a project using a tree structure. A folder's\n<code>spec.items</code> can contain both dashboard references and nested subfolders, allowing you to mirror how your teams\nstructure their observability content.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/subfolder-tree-view.png\" alt=\"Sub-folder tree view\"></p>\n<p>The project's dashboard list displays dashboards in a tree view, where you can browse, create, edit, and delete folders\nand subfolders. The same operations are available through the API and CLI (<code>percli apply</code>, <code>percli get folder</code>, etc.).</p>\n<p>For example, the <code>demos</code> folder visible in the screenshot above is defined as:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-json\"><span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">  \"kind\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Folder\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">  \"metadata\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    \"name\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"demos\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    \"project\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"perses\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">  \"spec\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    \"items\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"kind\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Dashboard\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"name\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"demo\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"kind\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Dashboard\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"name\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"benchmark\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"kind\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Folder\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"name\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"infrastructure\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        \"items\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: [</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">          {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">            \"kind\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Dashboard\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">            \"name\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"nodeexporter\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">          }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        ]</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    ]</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<h2 id=\"new-plugins\">New plugins</h2>\n<h3 id=\"opensearch\">OpenSearch</h3>\n<p>This version of Perses now ships a bundled OpenSearch datasource along with a LogQuery plugin. Users can now query and\nview their logs directly in a Perses dashboard, right next to the other panels with metrics and traces.</p>\n<p>Connecting to an existing OpenSearch cluster is easy, using either a proxy or a direct connection. The recommended setup\nroutes requests through the Perses backend proxy: the browser talks to Perses and Perses talks to OpenSearch, so any\ncredentials stay server-side and you don't need to enable CORS on your cluster. A direct connection is also available\nfor local experimentation.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/opensearch-datasource.png\" alt=\"OpenSearch datasource configuration\"></p>\n<p>Logs are queried\nwith <a href=\"https://opensearch.org/docs/latest/search-plugins/sql/ppl/index/\">PPL (Piped Processing Language)</a>. You add a\n<strong>Logs Table</strong> panel, pick the <strong>OpenSearch Log Query</strong> query type, point it at an index pattern, and write a PPL\nquery — for example, showing the most recent <code>ERROR</code> lines from a service.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/recent-logs.png\" alt=\"OpenSearch Log Query panel editor\"></p>\n<p>Results are rendered as log entries, with every other column in the row kept as a label so you can filter and display\nfields like <code>service.name</code>, <code>severityText</code>, or <code>traceId</code>. You can drop several log panels on a single dashboard. For\ninstance, a broad \"Recent Logs\" view alongside a filtered \"Error Logs\" one.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/log-dashboard.png\" alt=\"OpenSearch log panels on a dashboard\"></p>\n<p>A couple of things happen automatically to make this feel native. Queries are bound to the dashboard's current time\nrange. The plugin injects a timestamp filter for you, so the logs follow the time picker (you can turn this off per\nquery). And because OpenSearch indices are schema-flexible, the plugin auto-detects the timestamp and message fields\nfrom common names, with per-query overrides when your index uses different ones. Since <code>traceId</code> is just another field,\nyou can even setup an OpenSearch logs panel next to a Tempo or Jaeger trace panel on the same dashboard and pivot from a\ntrace straight to the logs it produced.</p>\n<h3 id=\"jaeger\">Jaeger</h3>\n<p>This release adds support for Jaeger. With this integration, you can run trace queries against Jaeger from Perses dashboards or explorer.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/jaeger.png\" alt=\"Jaeger Dashboard\"></p>\n<h3 id=\"greptimedb\">GreptimeDB</h3>\n<p>This release adds support for GreptimeDB as a datasource in Perses.</p>\n<blockquote>\n<p>GreptimeDB is an open-source observability database built for Observability 2.0 — treating metrics, logs, and traces\nas one unified data model (wide events) instead of three separate pillars.</p>\n</blockquote>\n<p>With this integration, you can run log, trace, and time series queries against GreptimeDB directly from Perses\ndashboards.</p>\n<p>The images below show a dashboard example and the corresponding query editors.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/greptimedb_dashboard.png\" alt=\"GreptimeDB Dashboard\"></p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>GreptimeDB Log Query</th><th>GreptimeDB Time Series Query</th></tr></thead><tbody><tr><td><img src=\"https://perses.dev/assets/images/blog/v054/greptimedb_logquery.png\" alt=\"GreptimeDB Log Query\"></td><td><img src=\"https://perses.dev/assets/images/blog/v054/greptimedb_tsquery.png\" alt=\"GreptimeDB Time Series Query\"></td></tr></tbody></table>\n<h3 id=\"splunk\">Splunk</h3>\n<p>Perses now supports Splunk as a datasource, bringing Splunk's search capabilities directly into your Perses dashboards.</p>\n<p>The Splunk plugin lets you connect to Splunk Enterprise or Splunk Cloud and query data using SPL (Splunk Processing\nLanguage) — the same query language you already use in Splunk. Once connected, you can visualize results as time series\ncharts or explore raw log data, all within the Perses UI.</p>\n<ul>\n<li>Time Series Queries - Run SPL queries (e.g., timechart) and render results in Perses panel that accepts time series data.</li>\n<li>Log Queries - Retrieve and display log results from Splunk indexes directly in a logs panel.</li>\n</ul>\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>TimeSeries</th><th>Logs</th></tr></thead><tbody><tr><td><img src=\"https://perses.dev/assets/images/blog/v054/Splunk-Time-Series.jpg\" alt=\"Splunk Time Series\"></td><td><img src=\"https://perses.dev/assets/images/blog/v054/Splunk-Log-Query.jpg\" alt=\"Splunk Log Query\"></td></tr></tbody></table>\n<h3 id=\"alertmanager\">Alertmanager</h3>\n<p>Perses now supports <a href=\"https://prometheus.io/docs/alerting/latest/alertmanager/\">Alertmanager</a> as a datasource. This\nallows you to visualize and manage alerts and silences directly from a Perses dashboard.</p>\n<ul>\n<li>The new Alert Table allows you to view, search, group, filter and silence alerts. It also allows to confgure custom\ncolumns and label coloring, as many alert queries can be included for a single table it also supports deduplication.</li>\n<li>The new Silence Table allows you to view, search and expire silences. It also allows to configure its columns.</li>\n</ul>\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Alerts</th><th>Silences</th></tr></thead><tbody><tr><td><img src=\"https://perses.dev/assets/images/blog/v054/alerts-table.png\" alt=\"Alerts Table\"></td><td><img src=\"https://perses.dev/assets/images/blog/v054/silences-table.png\" alt=\"Silences Table\"></td></tr></tbody></table>\n<h3 id=\"log-explorer\">Log Explorer</h3>\n<p>Perses has been extended with a generic Log Explorer. This allows you to visualize and explore logs from any datasource\nthat supports logs, such as Loki, VictoriaMetrics, ClickHouse, GreptimeDB, etc.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v054/logexplorer.png\" alt=\"Log Explorer\"></p>\n<p>This is a really great addition to Perses, as it will avoid the need to implement an explorer for each datasources\nsupporting logs.</p>\n<p>We are thinking about doing the same for traces in the future, but we are still evaluating the best approach to do so.</p>",
      "date_published": "2026-07-29T00:00:00Z",
      "tags": [
        "Release notes"
      ]
    },
    {
      "id": "https://perses.dev/blog/2026/01/31/release-v0530/",
      "url": "https://perses.dev/blog/2026/01/31/release-v0530/",
      "title": "Release v0.53.0",
      "summary": "Welcome to Perses v0.53.0! In this release, on top of many improvements and bug fixes, we have introduced several changes that break the compatibility with previous versions.",
      "content_html": "\n<p>Welcome to Perses v0.53.0! In this release, on top of many improvements and bug fixes, we have introduced several\nchanges that break the compatibility with previous versions.</p>\n<p>These changes have been thinking carefully to improve the overall user experience and maintainability of Perses. We hope\neven if it will make the upgrade process a bit more complex, you will stay with us and enjoy the benefits of these\nimprovements.</p>\n<p>While you can read this blog post to have details about the changes and how to upgrade, we are also providing a\n<a href=\"https://perses.dev/docs/perses/latest/upgrade/v0.53.0/\">migration guide</a> that is more condensed and focused on the steps\nrequired to upgrade from previous versions to v0.53.0.</p>\n<p>On a different topic, we are happy to being able to list <a href=\"https://logz.io/\">Logz.io</a> as a new officially company using\nPerses in production. Welcome to the Perses community!</p>\n<p>If you are a company using Perses or contributing to it and want to be listed as an adopter, please follow\nthe <a href=\"https://perses.dev/adopters/\">guideline</a>. It is always great to see more and more companies trusting Perses for their\nmonitoring needs. And it will help us to grow the community and make Perses even better.</p>\n<p>As usual, this blog post does not cover all the changes and improvements included in this release. We are only talking\nabout the changes that should interest you the most. If you want to have a complete list of all the changes, please\nrefer to the <a href=\"https://github.com/perses/perses/releases/tag/v0.53.0\">changelog</a></p>\n<!-- more -->\n<h2 id=\"introduction-of-plugin-version-and-registry\">Introduction of plugin version and registry</h2>\n<p>To enhance the management of plugins specially when dealing with upgrading a plugin version that may introduce breaking\nchanges, we introduced a new field in the plugin specification called <code>metadata</code>. It includes a <code>version</code> field that\nallows to specify the version of the plugin and the <code>registry</code> field that indicates the source registry of the plugin.</p>\n<p>Now a plugin specification looks like this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">kind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">TimeSeriesChart</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">metadata</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  version</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">v0.1.0</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  registry</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">perses.dev</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">spec</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\"># ... rest of the plugin spec</span></span></code></pre>\n<p>Note that the version is following the semantic versioning format (semver) and this is enforced during the loading of\nthe plugin.</p>\n<p>This change is important as it will allow in the future to manage multiple versions of the same plugin and facilitate\nthe migration from one version to another. We are planning to introduce automatic migration tools in future releases to\nhelp users upgrade their plugins seamlessly. Excepting if a plugin is introducing breaking changes that cannot be\nautomatically handled, the upgrade process will be handled by the Perses backend using cuelang script contained in the\nplugin package.</p>\n<h3 id=\"what-does-it-change\">What does it change?</h3>\n<p>For <strong>end users</strong> using the Perses application, this change is transparent and does not require any action.</p>\n<p>However, for <strong>plugin developers</strong>, you will need to update the CLI to the last version. This is required as the API\nhandling the load of the plugins in development has changed. Therefore, previous versions of the CLI won't be able to\nsend the data to the server to load plugin in development. The error returned by the server will be 405 (Method Not\nAllowed). (see <a href=\"https://github.com/perses/perses/issues/3789\">https://github.com/perses/perses/issues/3789</a>)</p>\n<p>If you want to see the changes and more details regarding how it is implemented, they are available in this\nPR: <a href=\"https://github.com/perses/perses/pull/3711\">https://github.com/perses/perses/pull/3711</a></p>\n<h2 id=\"tls-config-changes\">TLS config changes</h2>\n<p>We are introducing a breaking change in the TLS configuration to have a consistent syntax to define TLS settings across\nall data-sources specifications and across all backend sub configurations.</p>\n<p>The previous version was mixing two syntaxes to set TLS across the various possible configuration that could lead to\nconfusion (camelCase and snake_case).\nThis breaking change is impacting only the SQL database configuration.</p>\n<p>In the SQL configuration, if the tls_config is used, then you should change your config like that:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-txt\"><span class=\"line\"><span>ca_file -> caFile</span></span>\n<span class=\"line\"><span>cert_file -> certFile</span></span>\n<span class=\"line\"><span>key_file -> keyFile</span></span>\n<span class=\"line\"><span>server_name -> serverName</span></span>\n<span class=\"line\"><span>insecure_skip_verify -> insecureSkipVerify</span></span>\n<span class=\"line\"><span>min_version -> minVersion</span></span>\n<span class=\"line\"><span>max_version -> maxVersion</span></span></code></pre>\n<h2 id=\"user-used-in-the-container\">User used in the container</h2>\n<p>In order to simplify the build of the docker image, we have changed the default user used in the container from <code>nobody</code>\nto <code>nonroot</code>. As a based image we are using now <code>gcr.io/distroless/static-debian12:non-root</code> instead of\n<code>ggcr.io/distroless/static-debian12:latest</code>, which gives us a non-root user by default.</p>\n<h3 id=\"what-does-it-change_1\">What does it change?</h3>\n<p>This change can impact users that is using as a database the file system inside the container, specially when running\nthe container with docker (not within Kubernetes). In that case, you should ensure that the <code>nonroot</code> user has the right\npermissions to read and write into the database folder. If this is not the case, when upgrading the image, you will face\npermission errors when Perses is trying to load the data coming from the file system.</p>\n<h2 id=\"authentication-changes\">Authentication changes</h2>\n<p>A new <strong>OIDC logout endpoint</strong> has been added to the API, allowing users to log out both from Perses and from their OIDC\nprovider, respecting\nthe <a href=\"https://openid.net/specs/openid-connect-rpinitiated-1_0.html\">OpenID Connect RP-Initiated Logout 1.0</a>\nspecification.\nThis is mainly used by the frontend to ensure a proper provider-side logout when a user signs out.<br>\nThe feature is currently in <strong>beta</strong> and <strong>disabled by default</strong>. It has been successfully tested with <strong>Azure AD</strong>\nand <strong>Keycloak</strong>, so feel free to try it out.</p>\n<p>We also introduced several improvements to the generic <strong>OIDC/OAuth2</strong> provider system:</p>\n<ul>\n<li>The <code>apiPrefix</code> configuration is now correctly applied during login redirections.</li>\n<li>The OAuth2/OIDC <code>state</code> parameter is now more secure, enabling compatibility with providers such as <strong>Authelia</strong>.</li>\n</ul>\n<h2 id=\"improving-run-query-button-behavior-in-multiqueryeditor\">Improving \"Run Query\" button behavior in MultiQueryEditor</h2>\n<h3 id=\"what-does-it-change_2\">What does it change?</h3>\n<p>If you are developing plugin specially query plugin or embedding MultiQueryEditor in your app, these changes will impact\nyou,\nand you need to follow these guidelines.</p>\n<p><code>MultiQueryEditor</code> component has a new mandatory method: <code>onQueryRun</code>. It will be called when the user click on the\nbutton \"Run Query\". It's useful if you want to execute a query only when this button is clicked and not on every\n<code>onChange</code> (previous Perses behavior). Now the <code>onChange</code> method is always called when something change in the editor.\nOn the Perses app, queries are only executed when the user click on the \"Run Query\" button, however changes are still\nsaved\nif user save the dashboard without clicking on \"Run Query\". But embedded use-cases might want to execute queries on\nevery change,\nso this new behavior allows both use-cases.</p>\n<p>In parallel, the caching of queries has been greatly improved to avoid memory leaks on dashboard refresh. More info can\nbe found in related PR: <a href=\"https://github.com/perses/perses/pull/3518\">#3518</a>\nAnd queries errors are now displayed at the query level (before it was only displayed at the panel level, could be hard\nto know which queries are causing issues).</p>\n<p>About the breaking change, your code should change from this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-tsx\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> FooExplorer</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ReactElement</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">        data</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: {</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">queries</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> []},</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        setData</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    } </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> useExplorerManagerContext</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">FooExplorerQueryParams</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>();</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Stack</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> gap</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">} </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sx</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{{width: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'100%'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}}></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">MultiQueryEditor</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                queryTypes</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{[</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'ProfileQuery'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">]}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                queries</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{queries}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                onChange</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">newQueries</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> setData</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({queries: queryDefinitions})}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">FooPanel</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> queries</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{queries}/></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        &#x3C;/</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Stack</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>to this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-tsx\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">export</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> FooExplorer</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">()</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ReactElement</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">        data</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: {</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">queries</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> []},</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">        setData</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    } </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> useExplorerManagerContext</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">FooExplorerQueryParams</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>();</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">queryDefinitions</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">setQueryDefinitions</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> useState</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">QueryDefinition</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[]>(queries);</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Stack</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> gap</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">2</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">} </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sx</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{{width: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'100%'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}}></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">MultiQueryEditor</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                queryTypes</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{[</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">'ProfileQuery'</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">]}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                queries</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{queryDefinitions}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                onChange</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">newQueries</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> setQueryDefinitions</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(newQueries)}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">                onQueryRun</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{() </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> setData</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({queries: queryDefinitions})}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">            &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">FooPanel</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> queries</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{queries}/></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        &#x3C;/</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Stack</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    );</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<h2 id=\"variable-migration-changes\">Variable migration changes</h2>\n<p>We realized variable migration script could be simplified &#x26; better follow CUE's good practices by replacing condition\nblocks by constraints defined on the variable object. However to enable this we had to introduce a breaking change*:\nwhere previously such schema was describing the remapping of a Grafana variable object named <code>#var</code>, it is now called\n<code>#grafanaVar</code>. Thus, if you had defined a schema looking like this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-cue\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">package</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> migrate</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"strings\"</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">#var: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">_</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> </span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> #var.type </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">==</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"custom\"</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> #var.type </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">==</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"interval\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    kind: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"MyVariable\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    spec: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        values: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">strings</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Split</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(#var.query, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\",\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>..the minimum change you need to do is this renaming:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-cue\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">package</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> migrate</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"strings\"</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">#grafanaVar: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">_</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> </span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> #grafanaVar.type </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">==</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"custom\"</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> ||</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> #grafanaVar.type </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">==</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"interval\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    kind: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"MyVariable\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    spec: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        values: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">strings</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Split</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(#grafanaVar.query, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\",\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>Then it is recommended to refactor to something like this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-cue\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">package</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> migrate</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"strings\"</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">#grafanaVar: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    type: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"custom\"</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> |</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"interval\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    query: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">string</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    ...</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">kind: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"MyVariable\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">spec: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    values: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">strings</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Split</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(#grafanaVar.query, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\",\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>*We believe the trade‑off was worth introducing this breaking change, as we expect very few (if any) people to have\nwritten such variable migration schemas outside of the Perses organization. However, if you are impacted, please reach\nout to us! Learning more about our community helps us make better future decisions by having a clearer understanding of\npotential impacts.</p>\n<h2 id=\"introducing-i18n-support\">Introducing i18n support</h2>\n<p>This new version is introducing internationalization (i18n) support in the frontend, allowing to easily add new\nlanguages and provide a better experience for non-English speaking users. The i18n implementation is based on the widely\nused <code>react-i18next</code> library, which provides a powerful and flexible solution for managing translations in React\napplications.</p>\n<p>For the moment, the il8n is really limited as it only contains a few translations for few languages. The main goal of\nthis change is mainly to get the i18n support in place and have a framework to easily add new translations in the\nfuture.</p>\n<h2 id=\"kubernetes-auth\">Kubernetes Auth</h2>\n<p>This release introduces Kubernetes authentication and authorization providers, enables authorization decisions for users\nbased on Kubernetes RBAC checks against Perses CRDs. This change marks a forward step in Perses Kubernetes integration\nstory, allowing Perses CRDs to not just create resources but be used in conjunction with Kubernetes <code>Roles</code> and\n<code>RoleBindings</code> to provide access checks for users within Perses itself. Due to the variety of authentication providers\nfor Kubernetes, the implementation is designed to be provider agnostic. When enabled, Perses expects requests to contain\nan <code>Authorization</code> header in the form of <code>Authorization: Bearer XXXX</code>. The token is used to authenticate against the\nKubernetes API Server and check if the user has permission to requested namespaces and resources.</p>\n<p>The concept of authorization providers has been added with this change, marking the\n<code>.security.authorization.guest_permissions</code> and <code>.security.authorization.check_latest_update_interval</code> fields as\ndeprecated, moving them to the \"native\" authorization provider. These fields will be removed in a future release.</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">security</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  authorization</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    provider</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      native</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        enable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        check_latest_update_interval</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">5m</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        guest_permissions</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">        # ...</span></span></code></pre>\n<p>The frontend and percli have been updated to support these new providers. An <code>/api/v1/user/whoami</code> endpoint has been\ncreated to return user information for a logged in user. The percli has had <code>--kube</code> and <code>--kubeconfig-file</code> flags added\nwhich use the bearer token present in a kubeconfig file to authenticate with the Perses backend.</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-sh\"><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">percli</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> login</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> --kube</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> --kubeconfig-file=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"./kubeconfig\"</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> http://localhost:8080</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">successfully</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> logged</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> in</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> http://localhost:8080</span></span></code></pre>\n<p>The Kubernetes authentication and authorization providers must be enabled together. When enabled, the Perses backend\nwill use its pod's service account to authenticate and authorize users. The service account should be given\n<code>TokenReview</code> and <code>SubjectAccessReview</code> create and <code>Namespace</code> list permissions. The authenticator and authorizer\nprovider configurations are exposed as configuration options:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">security</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  enable_auth</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  authorization</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    provider</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      kubernetes</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        enable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        qps</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">500</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        burst</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1000</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        authorizer_allow_ttl</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">5m</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        authorizer_deny_ttl</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">30s</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        authenticator_ttl</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">2m</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  authentication</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    providers</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      kubernetes</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">        enable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span></code></pre>\n<h2 id=\"cli-improvements\">CLI improvements</h2>\n<ul>\n<li><code>plugin test-schemas</code> has been improved to test that the actual migrated schemas are valid against the expected\nschemas.</li>\n<li><code>plugin start</code> is now able to discover the port used by rspack to serve the plugin in development mode, so you don't\nneed to provide it anymore.\n<ul>\n<li>There was also an issue when loading a plugin in development with no schema defined, it is now fixed.</li>\n<li>When stoping the command, there was some orphan process left, it is now fixed.</li>\n<li>As mentioned before, the CLI has been updated to be compatible with the new dev plugin API introduced in this\nrelease.</li>\n</ul>\n</li>\n<li><code>lint</code>: when you were using local plugin to validate the dashboards, it was mandatory to have the plugins extracted in\na folder. Now you can also provide the plugins as an archive like it is the case for the Perses server. The command\nwill extract the plugins before starting validating any data.</li>\n</ul>\n<h2 id=\"plugin-improvements\">Plugin improvements</h2>\n<p>// TODO list of improvements, ideally give major changes and improvements for each plugin.</p>\n<h3 id=\"go-sdk-change-in-the-way-to-define-a-query-plugin\">GO-SDK Change in the way to define a query plugin</h3>\n<p>In the previous version of the GO-SDK, a query plugin was defined by using the Query builder. The issue with this\napproach is that it was not possible to provide the high level query type as it was hardcoded in the query builder.</p>\n<p>This was not a problem for the Perses app as we only have one query type until recently. It changed with the\nintroduction of the new query types:  \"ProfileQuery\", \"LogQuery\" and \"TraceQuery\". To support this new use-case, we had\nto introduce a breaking change in the way to define a query plugin.</p>\n<p>Now, instead of using the Query builder, you need to fill a struct <code>query.Option</code> that contains the query plugin and the\nhigh level query type.</p>\n<p>If we take the Prometheus plugin as an example, the implementation will change from this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">package</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> query</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">github.com/perses/perses/go-sdk/query</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">func</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> PromQL</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">expr</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">options</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> ...</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\treturn</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> func</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">builder</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> *</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Builder</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tplugin, err </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> create</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(expr, options</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">...</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\t\tif</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> err </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">!=</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> nil</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\t\t\treturn</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> err</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tbuilder.Spec.Plugin.Kind </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> PluginKind</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tbuilder.Spec.Plugin.Spec </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> plugin</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\t\treturn</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> nil</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span></code></pre>\n<p>to this:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">package</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> query</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">github.com/perses/perses/go-sdk/query</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">github.com/perses/perses/pkg/model/api/v1/common</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\t\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">github.com/perses/perses/pkg/model/api/v1/plugin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">func</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> PromQL</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">expr</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">options</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> ...</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">query</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\tplg, err </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> create</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(expr, options</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">...</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\treturn</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> query</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tKind: plugin.KindTimeSeriesQuery,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tPlugin: </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">common</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Plugin</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\tKind: PluginKind,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\tSpec: plg,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t},</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tError: err,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span></code></pre>\n<h3 id=\"support-of-temperature-units\">Support of temperature units</h3>\n<p>Celsius (°C) and Fahrenheit (°F) temperature units are now available for panel plugins that support unit configuration.</p>\n<h3 id=\"introducing-victorialogs-and-clickhouse-as-new-data-sources\">Introducing VictoriaLogs and ClickHouse as new data-sources</h3>\n<p>On top of that, this release is also introducing two new data-sources: VictoriaLogs and ClickHouse provided directly by\nthe community.</p>\n<p>// TODO: write more about these two data-sources, highlight their features, and who did it.</p>\n<p>Note that since these two data-sources are provided by the community, they are not officially supported by the Perses\nteam.\nAnd as such, soon we will come with a governance model to manage community plugins. In later release, these plugins\nmight be removed in the main images, depending on the governance adopted. You will still be able to use them by\ninstalling the datasources in your Perses instance.</p>",
      "date_published": "2026-01-31T00:00:00Z",
      "tags": [
        "Release notes"
      ]
    },
    {
      "id": "https://perses.dev/blog/2025/09/15/release-v0520/",
      "url": "https://perses.dev/blog/2025/09/15/release-v0520/",
      "title": "Release v0.52.0",
      "summary": "The release of Perses v0.52.0 introduces significant new features and improvements.",
      "content_html": "\n<p>The release of Perses v0.52.0 introduces significant new features and improvements.</p>\n<p>This update expands Perses' observability capabilities by introducing support for logging and continuous profiling,\nalong with new plugins for Pyroscope, Flame Chart, Loki, and log visualization.</p>\n<p>Additional enhancements include a heatmap panel for Prometheus histograms, a quick query viewer, panel group variable repeat,\nusability improvements, and upgraded CLI commands to streamline plugin development and schema testing.</p>\n<!-- more -->\n<h2 id=\"new-profiling-plugins\">New profiling plugins</h2>\n<p>This release provides the support of Continuous Profiling through two plugins:</p>\n<ul>\n<li><strong>Pyroscope</strong>: a datasource plugin for retrieving and handling data from a Pyroscope server.</li>\n<li><strong>Flame Chart</strong>: a visualization plugin which contains 3 panels: Flame Graph, Table View and Series Chart.</li>\n</ul>\n<h3 id=\"what-is-continuous-profiling\">What is Continuous Profiling?</h3>\n<p>Continuous Profiling is a new observability signal, complementing the traditional logs, metrics, and traces. This\ninnovative approach provides a way of continuously measuring applications' resource consumption with code-level\ngranularity and low overhead. This signal generates excitement in the community for its ability to provide in-depth\nvisibility into production performance of applications.</p>\n<h3 id=\"panels\">Panels</h3>\n<h4 id=\"flame-graph\">Flame Graph</h4>\n<p>The flame graph panel offers a simple and intuitive way to represent performance data, providing a hierarchical view\nthat let you zoom in on any stack for a detailed analysis. It helps to understand resource allocations (CPU,\nMemory, ...) and bottlenecks within an application.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/flame-graph-panel.png\" alt=\"Flame Graph Panel\"></p>\n<h4 id=\"table-view\">Table View</h4>\n<p>This panel displays the profile in a table format. It allows you to sort stacks, for example in descending order, to see\nwhich function consume the most resources. A search bar is also present for filtering the table and highlighting stacks\nin the flame graph.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/table-view-panel.png\" alt=\"Table View Panel\"></p>\n<h4 id=\"series-chart\">Series Chart</h4>\n<p>When retrieving profiles from the Pyroscope server, they include timeline data showing how the total amount of resources\nconsumed evolves over time, depending on the selected profile type. This panel allows you to visualize this data in\norder to identify spikes in resource consumption (CPU, memory, etc.) and focus on them by zooming into the corresponding\ntime range.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/series-chart-panel.png\" alt=\"Series Chart Panel\"></p>\n<h2 id=\"new-logs-plugins\">New Logs plugins</h2>\n<p>This release introduces two new plugins enabling log visualization and exploration in Perses:</p>\n<ul>\n<li><strong>Loki</strong>: a datasource plugin for retrieving and handling data from a Loki server.</li>\n<li><strong>Logs Panel</strong>: a visualization plugin for displaying and exploring logs.</li>\n</ul>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/logtable-panel.jpg\" alt=\"LogTable Panel\"></p>\n<p>These new plugins have been developed by the Perses community.\nA big thank you to <a href=\"https://github.com/abelyakin\">@abelyakin</a> !!</p>\n<h2 id=\"heatmap\">Heatmap</h2>\n<p>As spoiled on the previous release note, the heatmap panel has been added on Perses!\nIt is now possible to visualize Prometheus native histograms in a heatmap format. This panel is particularly useful for\nvisualizing latency distributions over time.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/heatmap-dark.png\" alt=\"Heatmap Panel\">\n<img src=\"https://perses.dev/assets/images/blog/v052/heatmap-light.png\" alt=\"Heatmap Panel\"></p>\n<p>This panel still need to be improved, so stay tuned for future updates! Or even better, contribute to it! List of\nimprovements to be done can be found in the <a href=\"https://github.com/perses/perses/issues/2978\">GitHub issue #2978</a></p>\n<h2 id=\"quick-query-viewer\">Quick Query Viewer</h2>\n<p>Panels introduces a new feature called <code>Quick Query Viewer</code> using which users can quickly check the executed queries\nwithout being in edit mode.\nThe feature has added a new, default icon button into the panel header. When clicked a modal is opened in which you can\nsee relevant query specs.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/quick_query_viewer.png\" alt=\"Quick Query Review\"></p>\n<h2 id=\"panel-group-repeat\">Panel group repeat</h2>\n<p>Panel group now support variable repeat. This allows you to create a panel group and have it repeated for each value of\na variable.</p>\n<p>You can define the repeat variable in the panel group settings dialog.\nIt will be also applied to preview in panel group.\nWhen editing a panel inside a panel group with repeat, changes will be applied to all panels group repeated.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/panel-group-job.png\" alt=\"Panel Group Repeat\">\n<img src=\"https://perses.dev/assets/images/blog/v052/markdown-panel-job.png\" alt=\"Panel Group Repeat\"></p>\n<h2 id=\"user-profile\">User profile</h2>\n<p>We are introducing user profiles in Perses!</p>\n<p>For the moment, the user profile page only contains the list of the permissions associated to the account used.\nBut it is the first step towards a more complete user profile page, which will include more functionalities in the\nfuture.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/user-profile.png\" alt=\"User Profile\"></p>\n<h2 id=\"discard-changes-prompt\">Discard changes prompt</h2>\n<p>When editing a dashboard, if you try to leave the page with unsaved changes, a prompt will appear to warn you about\npotential lost changes.\nThere are 2 different prompts depending on how you try to leave the page:</p>\n<ul>\n<li>If you try to navigate to another page in Perses, a modal will appear to confirm you want to leave the page.</li>\n<li>If you try to close the tab or navigate to another website, a browser native prompt will appear.</li>\n</ul>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/discard-changes-prompt.png\" alt=\"Discard Changes Prompt\">\n<img src=\"https://perses.dev/assets/images/blog/v052/discard-browser-prompt.png\" alt=\"Discard Browser Prompt\"></p>\n<h2 id=\"explorer-improvements\">Explorer improvements</h2>\n<p>Explorer can now show more information about your resources, thanks to collapsable tab menu!</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/explorer-not-collapsed.png\" alt=\"Explorer Not Collapsed\">\n<img src=\"https://perses.dev/assets/images/blog/v052/explorer-collapsed.png\" alt=\"Explorer Not Collapsed\"></p>\n<p>Few other improvements have been made to the explorer, such as:</p>\n<ul>\n<li>Tabs are now sorted alphabetically</li>\n<li>The metric finder datasource selector is rendered correctly</li>\n<li>Metric finder filter inputs are now displayed in 3 parts: key, operator, value. Instead of a single input.</li>\n</ul>\n<h2 id=\"plugins-improvements\">Plugins Improvements</h2>\n<h3 id=\"traces\">Traces</h3>\n<h4 id=\"attribute-search\">Attribute Search</h4>\n<p>The Tempo plugin now allows you to search for traces by attributes directly in the query editor, without writing a\nTraceQL query manually.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/tempo-filter-bar.png\" alt=\"Attribute Search\"></p>\n<h4 id=\"span-links\">Span Links</h4>\n<p>You can now view span links in a new <strong>Links</strong> tab when clicking on a span which has links configured. This makes it\neasier to explore related spans and understand trace relationships.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v052/tracingganttchart-span-links.png\" alt=\"Span Links\"></p>\n<h4 id=\"download-traces\">Download Traces</h4>\n<p>The TracingGanttChart panel now includes a download action in the panel header. With one click, you can export the\nentire trace in OTLP/JSON format for offline analysis or sharing.</p>\n<h4 id=\"linking-improvements\">Linking Improvements</h4>\n<p>The TracingGanttChart, TraceTable, and ScatterChart panels now support configuring links in the panel spec. You can\nconfigure the link to a specific trace (e.g. relevant for the trace table) or create dynamic links from resource and\nspan attributes (in the TracingGanttChart panel).</p>\n<h2 id=\"cli-improvements\">CLI Improvements</h2>\n<h3 id=\"new-command-percli-plugin-test-schema\">New command <code>percli plugin test-schema</code></h3>\n<p>This new command provides a way to test the Cuelang schema and the migration schema. Here how it works:</p>\n<p>First, all tests files needs to be placed directly alongside the schema file to test, within a <code>tests</code> folder.\nThen you will have different way to test the schemas:</p>\n<p><strong>Tests validating the model</strong>:</p>\n<ul>\n<li>Validate that a JSON file is accepted by the plugin's CUE schema.</li>\n<li>Place valid tests under \"tests/valid/\". \"tests\" is located next to the entrypoint of the \"model\" CUE package.</li>\n<li>Each test is a JSON file containing a valid configuration expected to pass validation.</li>\n</ul>\n<p><strong>Tests verifying invalid possibility</strong>:</p>\n<ul>\n<li>Validate that a JSON file is rejected by the plugin's CUE schema.</li>\n<li>Place invalid tests in \"tests/invalid/\". \"tests\" is located next to the entrypoint of the \"model\" CUE package.</li>\n<li>Each test is a JSON file containing an invalid configuration expected to fail validation.</li>\n</ul>\n<p><strong>Migration Tests</strong>:</p>\n<ul>\n<li>Validate migration logic defined in the plugin's \"migrate.cue\" file.</li>\n<li>Place migration tests under \"migrate/tests/\". \"tests\" is located next to \"migrate.cue\".</li>\n<li>Each test is a directory containing:\n<ul>\n<li>\"input.json\": The source file (e.g., Grafana format).</li>\n<li>\"expected.json\": The expected result after migration (Perses format).</li>\n</ul>\n</li>\n<li>The migration test unifies the input with the migration schema and compares the result to the expected output.</li>\n</ul>\n<p>Example of file structure for a single plugin:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-tree\"><span class=\"line\"><span>schemas/</span></span>\n<span class=\"line\"><span>├── model.cue</span></span>\n<span class=\"line\"><span>├── tests/</span></span>\n<span class=\"line\"><span>│   ├── valid/</span></span>\n<span class=\"line\"><span>│   │   ├── basic-config.json</span></span>\n<span class=\"line\"><span>│   │   └── advanced-config.json</span></span>\n<span class=\"line\"><span>│   └── invalid/</span></span>\n<span class=\"line\"><span>│       ├── missing-required.json</span></span>\n<span class=\"line\"><span>│       └── invalid-type.json</span></span>\n<span class=\"line\"><span>└── migrate/</span></span>\n<span class=\"line\"><span>├── migrate.cue</span></span>\n<span class=\"line\"><span>└── tests/</span></span>\n<span class=\"line\"><span>├── basic-migration/</span></span>\n<span class=\"line\"><span>│   ├── input.json</span></span>\n<span class=\"line\"><span>│   └── expected.json</span></span>\n<span class=\"line\"><span>└── complex-migration/</span></span>\n<span class=\"line\"><span>├── input.json</span></span>\n<span class=\"line\"><span>└── expected.json</span></span></code></pre>\n<p>More complex example for a package embedding several plugins:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-tree\"><span class=\"line\"><span>schemas/</span></span>\n<span class=\"line\"><span>├── my-datasource/</span></span>\n<span class=\"line\"><span>│   ├── model.cue</span></span>\n<span class=\"line\"><span>│   ├── tests/</span></span>\n<span class=\"line\"><span>│   │   ├── valid/</span></span>\n<span class=\"line\"><span>│   │   │   ├── basic-config.json</span></span>\n<span class=\"line\"><span>│   │   │   └── advanced-config.json</span></span>\n<span class=\"line\"><span>│   │   └── invalid/</span></span>\n<span class=\"line\"><span>│   │       ├── missing-required.json</span></span>\n<span class=\"line\"><span>│   │       └── invalid-type.json</span></span>\n<span class=\"line\"><span>│   └── migrate/</span></span>\n<span class=\"line\"><span>│       ├── migrate.cue</span></span>\n<span class=\"line\"><span>│       └── tests/</span></span>\n<span class=\"line\"><span>│           ├── basic-migration/</span></span>\n<span class=\"line\"><span>│           │   ├── input.json</span></span>\n<span class=\"line\"><span>│           │   └── expected.json</span></span>\n<span class=\"line\"><span>│           └── complex-migration/</span></span>\n<span class=\"line\"><span>│               ├── input.json</span></span>\n<span class=\"line\"><span>│               └── expected.json</span></span>\n<span class=\"line\"><span>└── my-query/</span></span>\n<span class=\"line\"><span>├── model.cue</span></span>\n<span class=\"line\"><span>├── tests/</span></span>\n<span class=\"line\"><span>│   ├── valid/</span></span>\n<span class=\"line\"><span>│   └── invalid/</span></span>\n<span class=\"line\"><span>└── migrate/</span></span>\n<span class=\"line\"><span>├── migrate.cue</span></span>\n<span class=\"line\"><span>└── tests/`,</span></span></code></pre>\n<h3 id=\"improvement-of-the-command-percli-plugin-start\">Improvement of the command <code>percli plugin start</code></h3>\n<p>This command has been improved to provide a better experience when starting a plugin locally.</p>\n<p>Note: all improvement described below will only work with a remote server of version >= 0.52.0 as it also included new\nendpoints to make the features work.</p>\n<ol>\n<li>\n<p>With this new version, the command is now able to detect any changes on the Cuelang schema.\nWhen a change is detected, the command will trigger the remote server to reload the schema internally.\nThis improvement is particularly useful during the development of a plugin, as it allows to see the changes of the\nschema immediately without having to manually restart the server and the plugin watching process.</p>\n</li>\n<li>\n<p>When stopping the command, it will now unregister any plugin it was watching. This is useful to avoid having to\nrestart the remote server to get back the list of registered plugins clean. It also solve an issue about being able\nto override a plugin with the development version of the same plugin.</p>\n</li>\n</ol>",
      "date_published": "2025-09-15T00:00:00Z",
      "tags": [
        "Release notes"
      ]
    },
    {
      "id": "https://perses.dev/blog/2025/06/18/introducing-the-perses-mcp-server/",
      "url": "https://perses.dev/blog/2025/06/18/introducing-the-perses-mcp-server/",
      "title": "Introducing the Perses MCP Server",
      "summary": "We're thrilled to introduce the Perses MCP Server, now available in public beta. This new tool empowers you to interact with your Perses instances using natural language, opening up a world of…",
      "content_html": "\n<p>We're thrilled to introduce the <strong>Perses MCP Server</strong>, now available in public beta. This new tool empowers you to interact with your Perses instances using natural language, opening up a world of possibilities for monitoring and visualization.</p>\n<p>With the Perses MCP Server, users can use AI Agents to understand, query and interact with Perses APIs in a standardized and secure manner.</p>\n<p>Imagine being able to prompt your favorite AI Agent with questions like:</p>\n<ul>\n<li>\"How many dashboards are created in the last 5 days in project 'Test Project'?\"</li>\n<li>\"What is the default datasource for project 'Test Project'?\"\n<ul>\n<li>\"Is this datasource in proxy mode? and what is the URL?\"</li>\n</ul>\n</li>\n<li>\"Analyze this dashboard 'Dashboard A' in project 'Test Project'\"\n<ul>\n<li>Suggest me some improvements to panels and PromQL queries in this dashboard</li>\n</ul>\n</li>\n</ul>\n<p>As you can see, the possibilities are endless. The Perses MCP Server allows you to interact with Perses in ways that were previously not possible.</p>\n<!-- more -->\n<picture>\n  <img alt=\"Fallback image description\" src=\"https://github.com/user-attachments/assets/416409df-9045-41f3-b10b-91df3020af1f\">\n</picture>\n<p>This diagram visually represents how the Perses MCP Server acts as an intermediary between your AI Agent and the Perses Application.</p>\n<h3 id=\"what-is-mcp-the-model-context-protocol-explained\">What is MCP - The Model Context Protocol Explained</h3>\n<p>You might be wondering what makes this all possible. The magic behind the scenes is the Model Context Protocol (MCP), an open standard pioneered by Anthropic that is quickly gaining industry-wide adoption.</p>\n<p>MCP’s purpose is to create a universal language for AI agents to interact with the \"outside world\" that is, any data or system beyond their initial training data. This protocol enables AI to securely access real-time information and perform tasks by connecting to external APIs. In short, MCP provides a paved road for Large Language Models (LLMs) to interact with external systems like databases, APIs, and filesystems.</p>\n<p>Major players like Google, Microsoft, and OpenAI have already committed to supporting MCP.</p>\n<h3 id=\"how-to-use-the-perses-mcp-server\">How to Use the Perses MCP Server</h3>\n<p>Using the Perses MCP Server is simple and straightforward.</p>\n<ol>\n<li>Follow this <a href=\"https://github.com/perses/mcp-server/blob/main/README.md#usage\">User Guide</a> to install and configure the MCP Server;</li>\n<li><strong>Ask a Question</strong>: Pose a natural language question to your favorite AI agent, such as, \"When was 'Dashboard A' in 'Project B' last updated?\";</li>\n<li><strong>Get an Answer</strong>: The MCP Server instantly gets to work, querying the Perses API and delivering the answer back to your AI agent in seconds.</li>\n</ol>\n<p>Check out this short demo to see it in action:</p>\n<video controls>\n  <source src=\"https://perses.dev/assets/images/blog/mcp-server/perses-mcp-server-demo.mp4\" type=\"video/mp4\">\n  Your browser does not support the video tag.\n</video>\n<h3 id=\"getting-started-with-perses-mcp-server\">Getting Started with Perses MCP Server</h3>\n<p>Ready to dive in? Here are the resources you'll need:</p>\n<ul>\n<li><strong>Perses MCP Server GitHub Repository:</strong> Explore the code, read the documentation, and find the installation instructions <a href=\"https://github.com/perses/mcp-server\">here</a>;</li>\n<li><strong>Perses Official Website:</strong> Discover more about the Perses, its features, blog posts and documentation <a href=\"https://perses.dev/\">here</a>.</li>\n</ul>\n<h3 id=\"whats-next\">What's next?</h3>\n<p>This public beta is just the beginning. Currently, the server supports read-only operations, allowing you to query the Perses API. Our roadmap includes adding write capabilities, which will enable you to use AI agents to create and update Perses resources like dashboards, projects, and datasources.</p>\n<p>We are committed to an open development process and we welcome your feedback and contributions as we build these new features.</p>",
      "date_published": "2025-06-18T00:00:00Z",
      "tags": [
        "Community"
      ]
    },
    {
      "id": "https://perses.dev/blog/2025/06/10/composable-dashboards----lessons-from-building-perses-community-dashboards/",
      "url": "https://perses.dev/blog/2025/06/10/composable-dashboards----lessons-from-building-perses-community-dashboards/",
      "title": "Composable Dashboards -  Lessons from building Perses Community Dashboards",
      "summary": "Every CNCF User/Developer/Contributor has, at some point, to endure the frustration of trying to salvage an outdated dashboard, or adapting upstream YAML, only to get to the point of wondering why it…",
      "content_html": "\n<h2 id=\"why-we-keep-rewriting-the-same-dashboards\">Why we keep rewriting the same dashboards</h2>\n<p>Every CNCF User/Developer/Contributor has, at some point, to endure the frustration of trying to salvage an outdated dashboard, or adapting upstream YAML, only to get to the point of wondering why it doesn't work on their setup. This leads to a recurring pattern: everyone ends up rebuilding the same dashboards, over and over again, each slightly different.</p>\n<p>The Mixins Dashboards helped bring about a sense of relief, as users now could use dashboards and alerts packaged together with the code they are deployed with. In theory, this promised consistency and easier integration. In practical terms, as the concept of mixins relies on Jsonnet, and even though it’s a suitable language for configuration management, it leads to a few issues:</p>\n<ul>\n<li>\n<p>Jsonnet has a steep learning curve. It’s not a conventional Turing-complete programming language, and often makes it hard for downstream users of mixins to be able to do any sort of customization on their dashboards;</p>\n</li>\n<li>\n<p>Mixin Jsonnet is completely detached from the actual application code. It was introduced as a way to maintain dashboarding config for code that you are deploying side by side, to ensure it never goes out of sync. However, many mixins are rarely updated, even when the code is - sometimes these are maintained out of the tree. And Jsonnet cannot use Go structs, so there is no automatic validation during code changes. Thus keeping mixins accurate and reliable demands a lot of effort.;</p>\n</li>\n<li>\n<p>Adoption has also been uneven. A good example of this is kube-prometheus stack, built with Jsonnet, where many users bypass it entirely and only fetch the rendered YAML from that repository, then doing any sort of changes with tools like Kustomize instead. This undermines the original goal of reuse and standardization.</p>\n</li>\n</ul>\n<p>The end result is, that despite the promise of reusable dashboards, the reality is there’s still not a widely used solution for automatic dashboards creation.</p>\n<!-- more -->\n<h2 id=\"perses-kubecon-eu-recap-maybe-theres-a-better-way-to-build-dashboards\">Perses KubeCon EU Recap - Maybe there’s a better way to build Dashboards</h2>\n<p>During <strong>KubeCon EU 2025</strong> in London, two of Perses’ core maintainers, Nicolas Takashi and Antoine Thébaud, shared how Perses is changing the way engineers develop and manage dashboards as code. Their talk covered the power of the Open Dashboard Model, how to use strongly typed code with the Perses Go SDK, and why this approach fits naturally into CI/CD pipelines using modern GitOps practices. If you didn’t get a chance to watch it live, you can watch the full session <a href=\"http://youtube.com/watch?v=7h70Olo5Uzk\">here</a>.</p>\n<p>They also mentioned the <strong>Community Dashboards</strong> Project, but didn’t have time to dive into it during the session. With that in mind is our belief that such an important topic deserves more space, and as so we bring this into live here.</p>\n<h2 id=\"moving-away-from-rebuilding-the-same-dashboards-to-composable-dashboards\">Moving away from rebuilding the same dashboards to composable dashboards</h2>\n<p>With the limitations of mixins in mind, the Perses community decided to take a different path. Since Perses is written in Go, with both its configuration and plugins defined using Go structs, it presents an opportunity to design dashboards in a more efficient and structured way. This approach takes full advantage of the Go structs imported from Perses, with its robust SDK that has the methods and constructs to build dashboards. This then ensures consistency with the core project, safe versioning, both for the dashboard data model and each individual panel plugins, and type-safe dashboard construction and customization.</p>\n<p>Introducing the <a href=\"https://github.com/perses/community-dashboards\">community-dashboards</a> repository. Maintained by community contributors, it offers the following dashboards in type-safe modular Go SDK based Dashboards as Code:</p>\n<p><img src=\"https://perses.dev/assets/images/blog/community-dashboards/perses-dashboards-overview.png\" alt=\"Dashboard overview\"></p>\n<p>The goal of the community-dashboards library isn't just to provide ready-to-use YAML dashboards (though you can use them as-is), but to empower users to import the project as a Go module in their downstream configuration, generate tailored subsets of dashboards, and customize or extend them to meet specific needs (similar to what mixins originally intended).</p>\n<p>A core strength of the Perses Community Dashboards is its modular, reusable panel library. These panels—such as Go CPU Usage and Memory Consumption—serve as building blocks that can be composed into new dashboards. Instead of starting from scratch, users can leverage these community-maintained components to quickly build dashboards suited to their applications and workloads.</p>\n<p>This approach also lowers the barrier to achieving consistency across dashboards. By reusing the same patterns to build and display common metrics, dashboards remain aligned across teams and services. This makes it easier to compare environments, onboard new engineers, and scale observability practices—without reinventing the wheel.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/community-dashboards/perses-dashboards-am.png\" alt=\"AM overview\"></p>\n<h2 id=\"how-to-build-composable-dashboards-a-practical-example\">How to build composable dashboards - a practical example</h2>\n<p>Here we have an example of how to define a panel of Time Series type below. More detailed info about the available option for Time Series Panels can be found <a href=\"https://pkg.go.dev/github.com/perses/plugins/timeserieschart\">here</a> and <a href=\"https://pkg.go.dev/github.com/perses/promql-builder\">PromQLBuilder</a>.</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Define your panel</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">func</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> CPUUsage</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">datasourceName</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">labelMatchers</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> ...*</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">labels</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Matcher</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">panelgroup</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\treturn</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> panelgroup.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AddPanel</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"CPU Usage\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tpanel.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Description</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Shows the CPU usage of the component.\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\ttimeSeriesPanel.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Chart</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\ttimeSeriesPanel.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">WithYAxis</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">timeSeriesPanel</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">YAxis</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tFormat: </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">&#x26;</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">commonSdk</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Format</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\tUnit: </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(commonSdk.DecimalUnit),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t},</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t}),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\ttimeSeriesPanel.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">WithLegend</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">timeSeriesPanel</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Legend</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tPosition: timeSeriesPanel.BottomPosition,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tMode:     timeSeriesPanel.TableMode,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tValues:   []</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">commonSdk</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Calculation</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{commonSdk.LastCalculation},</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t}),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\ttimeSeriesPanel.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">WithVisual</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">timeSeriesPanel</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Visual</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tDisplay:      timeSeriesPanel.LineDisplay,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tConnectNulls: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tLineWidth:    </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0.25</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tAreaOpacity:  </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0.5</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tPalette:      </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">timeSeriesPanel</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Palette</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{Mode: timeSeriesPanel.AutoMode},</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t}),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tpanel.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AddQuery</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\tquery.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">PromQL</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tpromql.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">SetLabelMatchersV2</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\tpromqlbuilder.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Rate</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\tmatrix.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">New</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\t\tvector.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">New</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\t\t\tvector.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">WithMetricName</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"process_cpu_seconds_total\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\t\tmatrix.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">WithRangeAsVariable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"$__rate_interval\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\tlabelMatchers,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t).</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Pretty</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tdashboards.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AddQueryDataSource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(datasourceName),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tquery.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">SeriesNameFormat</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"{{pod}}\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>Next after you have your first panel, it’s time to add it to a dashboard - here’s how to add to a dashboard named <code>Workload / Overview</code>:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Use the panel in a dashboard</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">func</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> withResources</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">datasource</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">clusterLabelMatcher</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> *</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">labels</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Matcher</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">dashboard</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Option</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\tlabelMatchersToUse </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> []</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">*</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">labels</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Matcher</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tpromql.JobVarV2,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t}</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\tlabelMatchersToUse </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> append</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(labelMatchersToUse, clusterLabelMatcher)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\treturn</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> dashboard.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AddPanelGroup</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"CPU Usage\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tpanelgroup.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">PanelsPerLine</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tpanelgroup.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">PanelHeight</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">10</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tpanelsGostats.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">CPUUsage</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(datasource, labelMatchersToUse</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">...</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">// Build the dashboard and add the time series panel withResources</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">func</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> BuildWorkloadOverview</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">project</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">datasource</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#E36209;--shiki-dark:#FFAB70\">clusterLabelName</span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">dashboards</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">DashboardResult</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\tclusterLabelMatcher </span><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">:=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> dashboards.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">GetClusterLabelMatcherV2</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(clusterLabelName)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">\treturn</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> dashboards.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">NewDashboardResult</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\tdashboard.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">New</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"workload-overview\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\tdashboard.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">ProjectName</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(project),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\tdashboard.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Workload / Overview\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\tdashboard.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AddVariable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"job\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\tlistvariable.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">List</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\tlabelvalues.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">PrometheusLabelValues</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"job\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\tlabelvalues.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Matchers</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"workload_build_info{}\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t\tdashboards.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">AddVariableDatasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(datasource),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t\tlistvariable.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">DisplayName</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"job\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">\t\t\twithResources</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(datasource, clusterLabelMatcher),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t\t),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">\t).</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Component</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"workload\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>For more on the SDK please check <a href=\"https://pkg.go.dev/github.com/perses/perses/go-sdk\">perses/go-sdk</a>, and <a href=\"https://pkg.go.dev/github.com/perses/community-dashboards\">community-dashboards</a>.</p>\n<h2 id=\"beyond-copy-pasting-cleaner-and-smarter-way-to-building-dashboards\">Beyond Copy-Pasting - Cleaner and Smarter way to building Dashboards</h2>\n<p>Going back to the idea of copy-pasting raw YAML or JSON, although it might seem quicker, it leads to painful maintenance over time. The Go SDK offers a better path:</p>\n<ul>\n<li><strong>Type safety</strong> - You get compile-time feedback if something is wrong. No more mystery errors buried in JSON blobs.</li>\n<li><strong>Reusability</strong> - Define a panel once and reuse it wherever you want. Avoid duplication and drift.</li>\n<li><strong>Maintainability</strong> -  When a panel definition needs an update, you can do it in one place and apply it across all dashboards.</li>\n<li><strong>CI/CD friendly</strong> - Code is easier to version, review, and test. It fits naturally into modern GitOps workflows.</li>\n</ul>\n<p>Combining the use of panel libraries and the SDK, you get a flexible and scalable way to manage dashboards, while saving time, reducing errors, and staying consistent across your observability stack. This allows a community of dashboards users to have their lives made easier with these features.</p>\n<p>Also considering the most commonly used dashboard across platforms and teams, like <strong>Kubernetes</strong>, <strong>Prometheus</strong> and exporters like <strong>Node Exporter</strong>, <strong>Blackbox Exporter</strong>, also projects like <strong>Thanos</strong> dashboards as it tends to be a power duo within the Prometheus ecosystem, we have from the get go some core dashboards that will help you in the long term in your observability journey.</p>\n<h2 id=\"next-steps-for-the-community-dashboards\">Next Steps for the Community Dashboards</h2>\n<p>We’re committed to expanding support for more CNCF and other OSS projects while continuing to enhance the existing panel libraries. By adding more features and improving the quality of reusable panels, we enable users to gain deeper insights from their dashboards because the faster you can pinpoint an issue in your telemetry data, the better.</p>\n<p>Also, we aim to ensure proper documentation for all dashboards. Whether you're importing full dashboards or using panel libraries as building blocks, we want to make the process as seamless as possible. That means clear, well-commented code and guidance, so modularity is not only guaranteed but also easy to work with, without needing to dig through the entire codebase.</p>\n<p>Ultimately, this is a community effort, and we invite everyone to help grow this project. So if you have a dashboard you’ve rewritten more than once, or any mixin dashboard you use, but want to ensure it becomes modular, easily used and want to increase adoption of it. Whether it’s opening an issue or submitting a contribution, all help is moving forward so we can all, very soon, stop rebuilding the same dashboards.</p>\n<p>Let’s stop duplicating efforts and start building shared observability standards!</p>",
      "date_published": "2025-06-10T00:00:00Z",
      "tags": [
        "Community"
      ]
    },
    {
      "id": "https://perses.dev/blog/2025/06/06/release-v0510/",
      "url": "https://perses.dev/blog/2025/06/06/release-v0510/",
      "title": "Release v0.51.0",
      "summary": "We are excited to announce the release of Perses v0.51.0!",
      "content_html": "\n<p>We are excited to announce the release of Perses v0.51.0!</p>\n<p>This release brings several new features, improvements, and bug fixes to enhance your experience with Perses.</p>\n<p>It is a significant step forward in the evolution of Perses, and we are thrilled to share it with you. We have\nbeen working hard to bring you a more powerful and flexible platform for your observability needs.</p>\n<p>This release includes a new plugin architecture, new panel, new variable, a new\nrepository <a href=\"https://github.com/perses/plugins\">perses/plugins</a>\ncontaining all default plugins supported by Perses.</p>\n<p>We have also made significant improvements to the documentation, highlighting features that were implemented some time\nago but not well advertised, such as datasource discovery and ephemeral dashboards.</p>\n<!-- more -->\n<h2 id=\"new-plugins-system\">New Plugins system</h2>\n<p>Big news from us at Perses! We've rolled out a brand-new plugin system, and it's all about making things more flexible\nand expandable.\nOur goal? To provide a more flexible and extensible way to scaffold, develop and distribute plugins in Perses so we can\nexpand the possibilities for sources of data, visualization and interactions within the platform.</p>\n<h3 id=\"whats-under-the-hood\">What's Under the Hood?</h3>\n<p>Leveraging <a href=\"https://rspack.dev/guide/features/module-federation\">module federation</a> plugins can now operate\nindependently of the main Perses code.\nOpening up a world of possibilities for developers to create and share plugins without being tied down to the core\ncodebase.\nPlugins can be grouped into <strong>Plugin Modules</strong>, which are essentially collections of related plugins that can be\ndeveloped and distributed together.\nUnderneath it all, the system has a backend that handles data validation and migrations using Cuelang schemas, and a\nfrontend that brings everything to life with React components.</p>\n<h3 id=\"easier-plugin-development\">Easier Plugin Development</h3>\n<p>To make life easier for developers, we've built some handy <code>plugin</code> commands right into our command-line interface,\n<a href=\"https://perses.dev/docs/perses/latest/cli/\"><code>percli</code></a>.\nThe CLI will do all the heavy lifting from setting up your project, getting your development environment ready, to\nbuilding your plugins.\nThat way, you can kick back and focus on the exciting part: actually creating awesome plugin features!</p>\n<h3 id=\"how-does-it-work\">How Does It Work?</h3>\n<p>The new plugin system is designed to be super user-friendly.\nYou can scaffold a plugin using the <code>percli plugin generate</code> command, which will set up the new plugin files for you.\nThis command can be used several times to create multiple plugins in the same plugin module.\nThen you can start developing your plugin using <code>percli plugin start</code> to run it in development mode and test it out in\nyour local Perses instance. Finally, compile it with <code>percli plugin build</code> to prepare it for distribution.</p>\n<p>You can follow the <a href=\"https://perses.dev/docs/perses/latest/plugins/creation/\">documentation</a> for details and examples to get\nstarted with creating your own plugins.</p>\n<h3 id=\"where-to-find-plugins\">Where to Find Plugins</h3>\n<p>Thanks to this new setup, our main Perses plugins have moved to their own dedicated home\nat <a href=\"https://github.com/perses/plugins\">perses/plugins</a>. And speaking of plugins, the system supports a bunch of\ndifferent types:</p>\n<ul>\n<li>Datasource: Perfect for grabbing data from all sorts of places.</li>\n<li>Query: This one links your datasources to your panels.</li>\n<li>Panel: Your go-to for making data look good through various visualizations.</li>\n<li>Variable: For when you need dynamic values in your queries.</li>\n<li>Explore: A special kind of panel designed for diving deep into your data.</li>\n</ul>\n<p>You just use <code>percli</code> to get started, test your creations, and then build them up to distribute as archive files or npm\npackages.\nAfter that, they're ready to be installed on a Perses server or even embedded directly into other React apps.</p>\n<p>So, what kind of plugin are you dreaming of building first?</p>\n<h3 id=\"which-plugins-are-available-in-perses\">Which plugins are available in Perses</h3>\n<p>All plugins that are available in the repository <a href=\"https://github.com/perses/plugins\">perses/plugins</a> are installed by\ndefault in Perses.</p>\n<p>You can find the list of available plugins at runtime in the UI, in the <strong>Configuration</strong> page, under the <strong>Plugins</strong>\ntab.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v051/plugins-list.png\" alt=\"PluginsList\"></p>\n<p>You can also use the CLI command <code>percli plugin list</code> to get the list of available plugins.</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-bash\"><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">percli</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> plugin</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> list</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">        NAME</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   VERSION</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">     TYPE</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">     │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> LOADED</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> FROM</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> DEV</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">────────────────────┼─────────────┼──────────────┼────────┼──────────</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> DatasourceVariable</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.1.2</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Variable</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">     │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> GaugeChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">         │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Markdown</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">           │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Prometheus</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">         │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 0.51.0-rc.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> PluginModule</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ScatterChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.6.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> StaticListVariable</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.3.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Variable</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">     │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Table</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">              │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.6.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> HistogramChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">     │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.2</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> PieChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">           │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> TimeSeriesChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.8.0</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> TimeSeriesTable</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">    │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> TraceTable</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">         │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.6.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> BarChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">           │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> TracingGanttChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.6.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> StatChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">          │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> StatusHistoryChart</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.7.2</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">       │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> Panel</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">        │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Tempo</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">              │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> 0.51.0-rc.1</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> PluginModule</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> true</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">   │</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> false</span></span></code></pre>\n<h2 id=\"new-plugins\">New Plugins</h2>\n<h3 id=\"datasource-variable\">Datasource variable</h3>\n<p>Thanks to the community contributions, we are introducing a new plugin: the <strong>Datasource Variable</strong>.\nThis plugin allows the possibility to use a datasource as a variable in your dashboard, specially in the queries of your\npanels.</p>\n<p>This is particularly useful when you have multiple datasources of the same type, such as multiple Prometheus instances,\nand you would like to switch between them without having to modify each panel query.\n<img src=\"https://perses.dev/assets/images/blog/v051/datasourceVariable.gif\" alt=\"DatasourceVariable\"></p>\n<p>Of course, this plugin is not limited to Prometheus; it can be used with any datasource.</p>\n<p>Note: If you are familiar with Grafana this feature wont will feel particularly new to you.\nIt's a valuable addition to Perses, helping to bring feature parity and making it a strong alternative for those\nconsidering or exploring a\ntransition.</p>\n<h3 id=\"histogram-chart\">Histogram Chart</h3>\n<p>This release introduces a new plugin: the <strong>Histogram Chart</strong>. This plugin allows you to visualize Prometheus Native\nHistograms, providing a clear and concise way to understand the distribution of your histogram buckets.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v051/histogram-panel.png\" alt=\"Histogram Panel\"></p>\n<p>This panel is supporting thresholds, which allow you to colorize the chart based on specific values, making it easier to\nunderstand your data.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v051/histogram-thresholds.png\" alt=\"Histogram with thresholds\"></p>\n<p>This chart is also used in <strong>TimeSeriesTable</strong> panel to display histogram details, allowing the Explore page to display\nhistograms.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v051/histogram-explore.png\" alt=\"Explore page with histograms\"></p>\n<p>In next releases, we are planning to add exponential mode support, add support for Prometheus classic histograms and\nsummaries and thresholds on bucket counts.\nFeel free to give us ideas on how to improve this plugin, with issues or discussions on\nthe <a href=\"https://github.com/perses/perses\">Perses GitHub repository</a>.\nSpoiler: the heatmap panel is coming next release 🤫</p>\n<h2 id=\"breaking-change-in-dashboard-as-code\">Breaking Change in Dashboard as Code</h2>\n<p>As previously mentioned, we have relocated the default plugins to a new repository. This includes not only the frontend\ncode, which has been transferred there, but also the corresponding Go SDK and CUE SDK for each plugin.</p>\n<p>This move is a breaking change for the Dashboard as Code feature as when upgraded to the last version, you will no\nlonger have the plugin code from perses/perses repository.</p>\n<p>All imports will have to be updated to point to the new repository. We created a module for each plugin so you can\nimport only the ones you need.</p>\n<p>For example, in Go SDK, in case you are using the plugin <code>label-values</code> from the <code>Prometheus</code> module, you will need to\n<code>go get</code> the plugin first:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-bash\"><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">go</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> get</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> github.com/perses/plugins/prometheus</span></span></code></pre>\n<p>Then, in your Go code, you will have to change the import path from:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> labelValuesVar </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">github.com/perses/perses/go-sdk/prometheus/variable/label-values</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span></span></code></pre>\n<p>to:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-go\"><span class=\"line\"><span style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> labelValuesVar </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">github.com/perses/plugins/prometheus/sdk/go/variable/label-values</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"</span></span></code></pre>\n<p>As a complete example, this PR: <a href=\"https://github.com/perses/community-dashboards/pull/69\">https://github.com/perses/community-dashboards/pull/69</a> is demonstrating the required\nchanges you will have to do in your code when upgrading to the v0.51.0 of Perses.</p>\n<p>In the case of CUE SDK, we are also leveraging on the new dependency management introduced by CUE v0.12.0.\nWhere we previously had a custom-made schema retrieval achieved by <code>percli dac setup</code>, Perses is now fully aligned with\nthe new <a href=\"https://cuelang.org/docs/reference/modules/\">CUE modules</a>.</p>\n<p>To continue using the CUE SDK, you will need to update your CUE files to import the new modules, but also to <strong>upgrade</strong>\nthe\n<strong>cue</strong> version you are using to at least <strong>v0.12.0</strong>.</p>\n<h2 id=\"custom-lint-rules\">Custom Lint rules</h2>\n<p>As you may know, to validate your dashboard, we have implemented a set of rules.\nThese rules are executed when you save your dashboard during the unmarshalling step from JSON or YAML or during the\nvalidation of each plugin using Cuelang.</p>\n<p>In this release, we have added the ability to create custom lint rules. This allows you to enforce specific standards or\npractices within your organization.</p>\n<p>These custom rules should be defined in the configuration file of your Perses instance, typically located at\n<code>/etc/perses/config.yaml</code>. The rules are defined under the <code>dashboard.custom_lint_rules</code> section.</p>\n<p>Here is an example of how to define custom lint rules for dashboards:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">dashboard</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  custom_lint_rules</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Dashboard Naming Convention\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      target</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"$.metadata.name\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      assertion</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"value.matches('^[a-z]+(-[a-z]+)*$')\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      message</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Dashboard name must be all lowercase letters with hyphens only.\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    - </span><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"At Least One Panel Exists\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      target</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"$.spec.panels\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      assertion</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"value.size() > 0\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      message</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Dashboard must contain at least one panel.\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">      disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span></span></code></pre>\n<p>We are using the <a href=\"https://goessner.net/articles/JsonPath/\">JSONPath</a> syntax to target specific parts of the dashboard\nJSON structure, and the assertion is a <a href=\"https://github.com/google/cel-spec/blob/master/doc/langdef.md\">CEL</a> expression.</p>\n<p>To know more about the syntax of the rules, please refer to\nthe <a href=\"https://perses.dev/docs/perses/latest/configuration/custom-lint-rules/\">documentation</a></p>\n<h2 id=\"disable-datasource-and-variable\">Disable datasource and variable</h2>\n<p>In Perses, it is possible to create datasource and variables at three different levels: global, project, and dashboard.</p>\n<p>Usually, for security and governance reasons, you may want to prevent people to create datasource and variables at\nvarious levels. For global and project levels, this is already possible using the RBAC system.</p>\n<p>But before this release, it was not possible to disable the creation of datasource and variables at the dashboard level.</p>\n<p>In this release, we are introducing the ability to disable the manipulation of datasources and variables at any level.\nFor that, you need to modify the configuration file of your Perses instance, and add the following section:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">datasource</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  global</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  disable_local</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span></code></pre>\n<p>This configuration is preventing the usage of datasources at any level and disable the associated HTTP route in the\nPerses proxy.</p>\n<p>Of course, this config is silly because without datasources, you cannot use dashboards, but it is a good example of how\nto disable datasources.</p>\n<p>The same example applies for variables:</p>\n<pre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\"><code class=\"language-yaml\"><span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">variable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  global</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  project</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">:</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">    disable</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">  disable_local</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span></span></code></pre>\n<h2 id=\"improvement-of-the-datasource-discovery\">Improvement of the datasource discovery</h2>\n<p>One year ago, we introduced the datasource discovery feature, which allows you to automatically discover remote\ndatasources from the Kubernetes API or from a generic HTTP endpoint.\nAnd so far we never got feedback about it until a couple of months ago when <a href=\"https://www.sap.com/\">SAP</a> started using\nit.</p>\n<h3 id=\"overview\">Overview</h3>\n<p>We didn't have the opportunity to highlight this feature, so here is a quick overview of how it works.</p>\n<p>Datasource discovery is useful when you have a large number of datasources, and you don't want to manually register\nthem in your application. Note that this feature can only be used when registering Global Datasources.</p>\n<p>We are supporting two types of discovery:</p>\n<ul>\n<li><strong>Kubernetes API</strong>: This allows you to discover datasources that are registered in the Kubernetes API, such as\nPrometheus, Loki, and others. You can configure the discovery by specifying the namespace where the datasources are\nlocated, the label selector to filter the datasources and the type of the discovery you would like to use: service,\npod, endpoint.</li>\n<li><strong>HTTP Endpoint</strong>: This allows you to discover datasources from a generic HTTP endpoint. You can configure the\ndiscovery by specifying the URL of the endpoint. The endpoint should return a JSON array of Global Datasource.</li>\n</ul>\n<p>If you want to learn more about this feature, please refer to\nthe <a href=\"https://perses.dev/docs/perses/latest/configuration/datasource-discovery/\">documentation</a>.</p>\n<h3 id=\"improvements\">Improvements</h3>\n<ul>\n<li>We made a mistake about how the label selector was converted from the configuration file to the Kubernetes\nAPI. The label selector was not correctly formatted, which prevented the discovery from working properly.</li>\n<li>When converting a service to a global datasource, there was a corner case where the global datasource was not\ncorrectly created. And then Perses was not able to load the datasource.</li>\n</ul>\n<p>Thanks to these little improvements, the datasource discovery feature is now more reliable and easier to use.</p>\n<h2 id=\"community-dashboards\">Community Dashboards</h2>\n<p>Fresh off our talk at KubeCon EU 2025 in\nLondon - <a href=\"http://youtube.com/watch?v=7h70Olo5Uzk\">Limitless Possibilities, Consistent Design: Crafting Dashboards With Perses DAC</a>,\ngiven by two perses maintainers, Nicolas Takashi and Antoine Thébaud, we are happy to introduce\nthe <a href=\"https://github.com/perses/community-dashboards\">community-dashboards</a> repository.</p>\n<p>Here we provide support for commonly used Mixin Dashboards, like Prometheus, Kubernetes and Thanos, build on top of\n<strong>Dashboard as Code</strong> capabilities provided by Perses. We’ll dive deeper into the community-dashboards in our upcoming\nblog post, but starting today, you can begin using them right away — whether by:</p>\n<ul>\n<li>\n<p>Importing them directly into your Perses instance;</p>\n</li>\n<li>\n<p>Using them as a starting point to build your own dashboards;</p>\n</li>\n<li>\n<p>Or reusing individual panels in your own dashboards-as-code workflows.</p>\n</li>\n</ul>\n<p>We're also welcoming the community to help us support and extent the community-dashboards. So if there are additional\ndashboards you’d like to see supported, feel free to reach out to the team - or even better, help us extend the\nsupported dashboards with feedback or improvements to the dashboards. Your input helps shape what comes next!</p>\n<h2 id=\"support-oauth2-authentication-for-datasource\">Support OAuth2 authentication for Datasource</h2>\n<p>Another cool contribution from the community is the support for OAuth2 authentication for datasources.</p>\n<p>Before this release, the only way to authenticate to a datasource was to use a token, basic authentication and/or TLS\nconfiguration (like client certificate).</p>\n<p>But in real world scenarios, you may want to use OAuth2 authentication to access your datasources and this is now\npossible!</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v051/datasource-oauth2.png\" alt=\"Datasource OAuth2\"></p>\n<h2 id=\"support-yaml-and-yaml-k8s-custom-resource-format-for-dashboard\">Support YAML and YAML K8s Custom Resource format for Dashboard</h2>\n<img alt=\"Dashboard YAML\" src=\"https://perses.dev/assets/images/blog/v051/dashboard-yaml.png\" width=\"350\" align=\"left\">\n<p>Finally, but not least, we are introducing the support for YAML and YAML K8s Custom Resource format when exporting a\ndashboard from the UI.</p>\n<p>The YAML CR format is directly compatible with the <code>perses-operator</code> and can be used in your GitOps workflow.</p>\n<p>In future releases, we will also support the YAML format for all other resources, so you can export a panel or variable\nin a YAML format.</p>",
      "date_published": "2025-06-06T00:00:00Z",
      "tags": [
        "Release notes"
      ]
    },
    {
      "id": "https://perses.dev/blog/2025/01/15/release-v0500/",
      "url": "https://perses.dev/blog/2025/01/15/release-v0500/",
      "title": "Release v0.50.0",
      "summary": "We are excited to announce the release of Perses v0.50.0! This release brings significant improvements to the migration process from Grafana to Perses, including a major fix for a memory leak issue.…",
      "content_html": "\n<p>We are excited to announce the release of Perses v0.50.0! This release brings significant improvements to the migration\nprocess from Grafana to Perses, including a major fix for a memory leak issue. Additionally, it introduces a new Status\nHistory Panel and various enhancements to the Table Panel, UI, and CLI. Read on to learn more about the new features and\nimprovements in this release.</p>\n<p>See the complete release note for more details: <a href=\"https://github.com/perses/perses/releases/tag/v0.50.0\">v0.50.0</a></p>\n<!-- more -->\n<h2 id=\"migration\">Migration</h2>\n<p>One of the greatest contents of this release is the migration that has been drastically improved.</p>\n<p>Since the beginning of the project, we have been willing to provide an easy way to migrate dashboards from Grafana to\nPerses. As a reminder, you can migrate a Grafana dashboard using the HTTP endpoint <code>/api/migrate</code> or the UI or the CLI\nthat consumes this endpoint.</p>\n<p>The big issue with this feature was the memory leak that was hidden and not that easy to trigger.\n(See <a href=\"https://github.com/perses/perses/issues/2039\">issue #2039</a>)</p>\n<p>This was a big blocker for the migration and one of the main reasons why Amadeus was not able to migrate to Perses.\nAmadeus has a huge number of dashboards, and the memory leak was too important to be ignored.\nTo give you an idea, the memory leak was about <strong>40GB</strong> after migrating <strong>3000 dashboards</strong>. (~ 3MB per dashboard)</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v050/migration-memory-leak.png\" alt=\"Memory leak\"></p>\n<p>As you may know, we are using Cuelang for the Perses plugin validation, and at first, we implemented a complete way to\nmigrate using Cuelang only.\nThe idea behind was to append every migration script (one for each panel, variable, queries) to the main one.\nThen the Grafana JSON was converted to a Cuelang value, and we were applying the migration script to this value.</p>\n<p>With the v0.50.0, we are changing deeply and only internally the way it's working. It doesn't change anything for the\nuser, but it's a huge improvement for the maintainability and the performance of the migration.</p>\n<p>We have entirely rewritten the migration process. It is now using a hybrid system partially written in Golang and the\nrest in Cuelang when the plugins are involved. Thanks to this new system, the Cuelang files written to migrate the\npanels, the variables, and the queries can be validated and tested before the migration is applied.</p>\n<p>Thanks to this change, we are happy to announce the memory leak has been fixed and the migration is now working\nperfectly. We performed the same mass migration, and it succeeded without causing OOMKill, as it requires much less\nmemory than before. The graph below shows we didn't exceed <strong>3GB of memory</strong> during the migration.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v050/migration-without-memory-leak.png\" alt=\"no more Memory leak\"></p>\n<p>Finally, we’ve also addressed numerous updates to the migration process itself, incorporating fixes and enhancements to\nbetter cover use cases raised by the community - thank you for your contributions!</p>\n<h2 id=\"status-history-panel\">Status History panel</h2>\n<p>Thanks to <a href=\"https://github.com/abelyakin\">Alexander Belyakin</a> from the community, Perses is supporting a new Panel: the\nStatus History Panel.</p>\n<p>The Status History panel provides a visual representation of the status of various metrics over time.\nIt allows users to track changes in the status of different metrics, making it easier to identify patterns, trends, and\nanomalies.\nThis panel is particularly useful for monitoring the health and performance of systems, as it can display status changes\nin a clear and concise manner.\nThe panel can be customized to show different statuses, such as up, down, warning, or any other user-defined states, and\nit supports various visualization options to enhance the readability of the data.</p>\n<p>And of course, this panel is fully compatible with the migration process.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v050/status-history-panel.png\" alt=\"Status History panel\"></p>\n<h2 id=\"general-improvements\">General Improvements</h2>\n<h3 id=\"ui\">UI</h3>\n<p>We have finally added the redirection to the initial URL after you are authenticated. This was definitely a missing\nfeature annoying for the users.</p>\n<p>This release also introduces various improvements to the <strong>Table Panel</strong>, such as debounced text fields in the editor,\ndefault column sorting, custom column ordering, default column width setting, and cell focus on hover.</p>\n<p><img src=\"https://perses.dev/assets/images/blog/v050/reorder-columns.gif\" alt=\"Table Panel reordering columns\"></p>\n<h3 id=\"cli\">CLI</h3>\n<p>First, we have fixed the login command not working if you were using the CLI to log in to different Perses servers.</p>\n<p>Then, based on the community feedback, we also have improved the DAC (Dashboard as Code) sub-command.\nWe hope the experience with our DAC framework will be better.</p>\n<p>We are also introducing new commands for plugin development.\nThat's something that comes along with the new plugin architecture we are working on since last year.\nThese commands cannot be used currently as we are still working on the plugin architecture.</p>\n<p>But stay tuned as we are really close to finishing this intense work! <strong>V0.51.0</strong> is going to be incredible with a lot\nof changes!</p>",
      "date_published": "2025-01-15T00:00:00Z",
      "tags": [
        "Release notes"
      ]
    }
  ]
}
