From 104d6828fcae3c22048e3c6b1509d9268bb7fd22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?=
Date: Tue, 20 Oct 2026 13:35:04 +0200
Subject: [PATCH] :boom: Enable admin console by default
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: David Barragán Merino
---
CHANGES.md | 6 ++++++
backend/test/backend_tests/helpers.clj | 3 ++-
backend/test/backend_tests/rpc_auth_test.clj | 12 ++++++------
common/src/app/common/flags.cljc | 5 +++--
docker/images/docker-compose.yaml | 2 +-
docker/images/files/nginx-entrypoint.sh | 2 +-
docs/technical-guide/getting-started/docker.md | 14 ++++++++++----
frontend/playwright/ui/pages/BasePage.js | 6 +++++-
plugins/apps/composable-test-suite/ci/run-ci.ts | 2 +-
plugins/apps/plugin-api-test-suite/ci/run-ci.ts | 2 +-
10 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 6da1e66c2d..04c4738824 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -2,6 +2,12 @@
## 2.19.0 (Unreleased)
+### :boom: Breaking changes & Deprecations
+
+- The Admin Console is now enabled by default and the `enable-admin-console` flag is no
+ longer needed. Self-hosted instances must deploy the `penpot-admin-console` service and
+ set `PENPOT_ADMIN_CONSOLE_URI` in frontend and backend (check the [upgrade guide](https://help.penpot.app/technical-guide/getting-started/docker/#upgrade-to-2.19)).
+
### :rocket: Epics and highlights
- Add configurable keyboard shortcuts [#9924](https://github.com/penpot/penpot/issues/9924) (PR: [#10237](https://github.com/penpot/penpot/pull/10237))
diff --git a/backend/test/backend_tests/helpers.clj b/backend/test/backend_tests/helpers.clj
index 8aa3b684fc..168070d7f0 100644
--- a/backend/test/backend_tests/helpers.clj
+++ b/backend/test/backend_tests/helpers.clj
@@ -86,7 +86,8 @@
:enable-quotes
:enable-rpc-climit
:enable-auto-file-snapshot
- :disable-file-validation])
+ :disable-file-validation
+ :disable-admin-console])
(defn init-config
([next]
diff --git a/backend/test/backend_tests/rpc_auth_test.clj b/backend/test/backend_tests/rpc_auth_test.clj
index 802c70ac08..dcc8ffdcbf 100644
--- a/backend/test/backend_tests/rpc_auth_test.clj
+++ b/backend/test/backend_tests/rpc_auth_test.clj
@@ -122,7 +122,7 @@
(.close ^AutoCloseable conn)))))
(t/deftest login-with-password-locks-after-max-attempts
- (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout])]
+ (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout :disable-admin-console])]
(let [profile (th/create-profile* 200 {:is-active true})]
(cleanup-redis (:id profile))
;; 4 failed attempts — not yet locked
@@ -141,7 +141,7 @@
(t/is (th/ex-of-code? (:error out) :account-locked))))))
(t/deftest login-with-password-returns-rate-limit-when-locked
- (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout])]
+ (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout :disable-admin-console])]
(let [profile (th/create-profile* 201 {:is-active true})]
(cleanup-redis (:id profile))
;; Trigger lockout
@@ -161,7 +161,7 @@
(t/is (pos? ttl) "ttl should be a positive number"))))))
(t/deftest successful-login-clears-failed-attempts
- (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout])]
+ (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout :disable-admin-console])]
(let [profile (th/create-profile* 202 {:is-active true})]
(cleanup-redis (:id profile))
;; 3 failed attempts
@@ -184,7 +184,7 @@
(t/is (th/ex-of-code? (:error out) :wrong-credentials)))))))
(t/deftest lockout-does-not-apply-when-flag-disabled
- (with-redefs [app.config/flags (flags/parse flags/default [])]
+ (with-redefs [app.config/flags (flags/parse flags/default [:disable-admin-console])]
(let [profile (th/create-profile* 203 {:is-active true})]
(cleanup-redis (:id profile))
;; 10 failed attempts — no lockout without the flag
@@ -199,7 +199,7 @@
"Verify that login-with-ldap short-circuits when account is locked,
without attempting LDAP authentication. Calls the actual command
function with a mock provider to test the full flow."
- (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout :login-with-ldap])
+ (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout :login-with-ldap :disable-admin-console])
ldap/authenticate (constantly nil)]
(let [profile (th/create-profile* 204 {:is-active true})
cfg (assoc th/*system* ::ldap/provider {})]
@@ -217,7 +217,7 @@
(t/deftest recover-profile-clears-lockout
"Verify that clearing attempts (e.g. after password reset) unlocks the account."
- (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout])]
+ (with-redefs [app.config/flags (flags/parse flags/default [:enable-account-lockout :disable-admin-console])]
(let [profile (th/create-profile* 205 {:is-active true})
cfg th/*system*]
(cleanup-redis (:id profile))
diff --git a/common/src/app/common/flags.cljc b/common/src/app/common/flags.cljc
index a3f3cf44be..aeec7274d0 100644
--- a/common/src/app/common/flags.cljc
+++ b/common/src/app/common/flags.cljc
@@ -174,7 +174,7 @@
;; redis for caching data
:redis-cache
- ;; Activates the admin-console module
+ ;; enabled by default. Activates the admin-console module
:admin-console
;; disabled by default. When enabled, allows the admin-console
@@ -236,7 +236,8 @@
:enable-token-combobox
:enable-custom-shortcuts
:enable-token-lib-sync
- :enable-link-unfurl])
+ :enable-link-unfurl
+ :enable-admin-console])
(defn parse
[& flags]
diff --git a/docker/images/docker-compose.yaml b/docker/images/docker-compose.yaml
index e667bc3049..932fda6279 100644
--- a/docker/images/docker-compose.yaml
+++ b/docker/images/docker-compose.yaml
@@ -24,7 +24,7 @@
# WARNING: if you're exposing Penpot to the internet, you should remove the flags
# 'disable-secure-session-cookies' and 'disable-email-verification'
x-flags: &penpot-flags
- PENPOT_FLAGS: disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies enable-mcp enable-admin-console
+ PENPOT_FLAGS: disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies enable-mcp
x-uri: &penpot-public-uri
PENPOT_PUBLIC_URI: http://localhost:9001
diff --git a/docker/images/files/nginx-entrypoint.sh b/docker/images/files/nginx-entrypoint.sh
index 3ec97403a8..e76e581f1c 100644
--- a/docker/images/files/nginx-entrypoint.sh
+++ b/docker/images/files/nginx-entrypoint.sh
@@ -61,7 +61,7 @@ fi
envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI,\$PENPOT_HTTP_SERVER_MAX_BODY_SIZE,\$PENPOT_IPV6_LISTEN_DIRECTIVE" \
< /tmp/nginx.conf.template > /etc/nginx/nginx.conf
-if [[ $PENPOT_FLAGS == *"enable-admin-console"* ]]; then
+if [[ " $PENPOT_FLAGS " != *" disable-admin-console "* ]]; then
export PENPOT_ADMIN_CONSOLE_URI=${PENPOT_ADMIN_CONSOLE_URI:-http://penpot-admin-console:3000}
envsubst "\$PENPOT_ADMIN_CONSOLE_URI" \
< /tmp/nginx-admin-console-locations.conf.template > /etc/nginx/overrides/server.d/admin-console-locations.conf
diff --git a/docs/technical-guide/getting-started/docker.md b/docs/technical-guide/getting-started/docker.md
index 4d192aee11..3d204f6a60 100644
--- a/docs/technical-guide/getting-started/docker.md
+++ b/docs/technical-guide/getting-started/docker.md
@@ -122,6 +122,13 @@ This will fetch the latest images. When you do docke
It is strongly recommended to update the Penpot version in small increments, rather than updating between two distant versions.
+#### Upgrade to 2.19
+
+The Admin Console is now enabled by default, so the `enable-admin-console` flag is no longer
+needed and can be removed from `PENPOT_FLAGS`. The `penpot-admin-console` service and the
+`PENPOT_ADMIN_CONSOLE_URI` variable are now required: if you haven't set them up yet, follow
+steps 2–4 of the [2.18 upgrade](#upgrade-to-2.18).
+
#### Upgrade to 2.18
This version deploys a new service, **`penpot-admin-console`**, in the official `docker-compose.yaml`
@@ -132,10 +139,9 @@ example. If you maintain your own compose file, you need to replicate the follow
**NOTE:** Enabling the Admin Console is not required in this version, but it will be in a future release.
We recommend setting it up now to avoid a more complex upgrade later.
-This step (the `enable-admin-console` flag) only applies to this version 2.18. In a future release, the
-Admin Console will be enabled by default and this flag will be removed. If you're upgrading directly to a
-version where the flag has already been removed, skip step 1 and go straight to steps 2–4, which remain
-required.
+This step (the `enable-admin-console` flag) only applies to this version 2.18. Since 2.19 the Admin
+Console is enabled by default: if you're upgrading directly to 2.19 or later, skip step 1 and go straight
+to steps 2–4, which remain required.
Wherever you set `PENPOT_FLAGS` (frontend and backend):
diff --git a/frontend/playwright/ui/pages/BasePage.js b/frontend/playwright/ui/pages/BasePage.js
index 670e8a2766..f8f246058d 100644
--- a/frontend/playwright/ui/pages/BasePage.js
+++ b/frontend/playwright/ui/pages/BasePage.js
@@ -101,7 +101,11 @@ export class BasePage {
static async mockConfigFlags(page, flags, extras = {}) {
const url = "**/js/config.js*";
- const config = { penpotFlags: flags.join(" "), ...extras };
+ // The e2e suite mocks the backend and has no admin console behind it.
+ const config = {
+ penpotFlags: ["disable-admin-console", ...flags].join(" "),
+ ...extras,
+ };
const body = Object.entries(config)
.map(([key, value]) => `var ${key} = ${JSON.stringify(value)};`)
.join("\n");
diff --git a/plugins/apps/composable-test-suite/ci/run-ci.ts b/plugins/apps/composable-test-suite/ci/run-ci.ts
index d9403c6793..69186e9436 100644
--- a/plugins/apps/composable-test-suite/ci/run-ci.ts
+++ b/plugins/apps/composable-test-suite/ci/run-ci.ts
@@ -146,7 +146,7 @@ async function setupMockedRoutes(page: Page): Promise {
route.fulfill({
status: 200,
contentType: "application/javascript",
- body: 'var penpotFlags = "";\n',
+ body: 'var penpotFlags = "disable-admin-console";\n',
})
);
diff --git a/plugins/apps/plugin-api-test-suite/ci/run-ci.ts b/plugins/apps/plugin-api-test-suite/ci/run-ci.ts
index 559e6f0aea..8b97cf088a 100644
--- a/plugins/apps/plugin-api-test-suite/ci/run-ci.ts
+++ b/plugins/apps/plugin-api-test-suite/ci/run-ci.ts
@@ -242,7 +242,7 @@ async function setupMockedRoutes(page: Page): Promise {
route.fulfill({
status: 200,
contentType: 'application/javascript',
- body: 'var penpotFlags = "";\n',
+ body: 'var penpotFlags = "disable-admin-console";\n',
}),
);