diff --git a/.agents/README.md b/.agents/README.md index 6bf3a80a1a..165a4a7745 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -34,7 +34,7 @@ JSON, REPL access, and so on. |---|---|---| | [`make-a-plan`](skills/make-a-plan/SKILL.md) | Researches the task, writes an implementation plan, asks you the open questions in plain language, and saves the plan to `.agents/plans/`. | "make a plan for the token refresh bug" | | [`review-plan`](skills/review-plan/SKILL.md) | Evaluates a plan before anyone writes code: completeness, ordering, risks. Approves it or asks for changes. | "review this plan before we start" | -| [`implement-plan`](skills/implement-plan/SKILL.md) | Shows you the full flow first — the issue and branch it will create (or the branch it continues on), the execution style, and the task checklist — and, after your go-ahead, executes a ready plan. Default: every task, one commit. On request ("step by step"): one task, one commit, your confirmation between tasks. | "implement the plan" · "step by step, one commit per task" | +| [`implement-plan`](skills/implement-plan/SKILL.md) | Shows you the full flow first — the issue and branch it will create (or the branch it continues on), the execution style, and the task checklist — and, after your go-ahead, executes a ready plan. Default: every task, one commit. On request ("step by step"): one task, one commit, your confirmation between tasks. On request ("direct"): no issue and no branch, commits on the current branch. | "implement the plan" · "step by step, one commit per task" · "direct, no branch" | | [`review-code`](skills/review-code/SKILL.md) | Reviews a diff, branch, or PR and returns findings ranked by impact. | "review my changes before I push" | | [`create-pr`](skills/create-pr/SKILL.md) | Opens a pull request for the current branch — with checks on base branch, commits, issue, and push state — or updates an existing PR's title and description. | "open a PR for this branch" | | [`resolve-git-conflicts`](skills/resolve-git-conflicts/SKILL.md) | Untangles merge or rebase conflicts: explains both sides, proposes a resolution, applies it after you approve. Never runs `git rebase --continue`. | "resolve these conflicts" | @@ -65,6 +65,7 @@ JSON, REPL access, and so on. | [`nrepl-eval`](skills/nrepl-eval/SKILL.md) | Run Clojure or ClojureScript code in the live REPL sessions (backend and frontend). | | [`taiga`](skills/taiga/SKILL.md) | Look up Penpot issues, user stories, and tasks in Taiga. | | [`testing`](skills/testing/SKILL.md) | The repo's testing rules and TDD workflow, loaded before writing tests. | +| [`local-ci`](skills/local-ci/SKILL.md) | Run CI-style lint, test, and format checks for the modules you touched with `scripts/ci`, and read the logs when they fail. | | [`security-and-hardening`](skills/security-and-hardening/SKILL.md) | Security checks for code that handles user input, auth, or external services. | | [`ste`](skills/ste/SKILL.md) | Rewrites prose in Simplified Technical English. Loads only when you name it. | | [`refine-prompt`](skills/refine-prompt/SKILL.md) | Rewrites a rough prompt into a clearer one. Never runs the prompt. | diff --git a/.agents/skills/implement-plan/SKILL.md b/.agents/skills/implement-plan/SKILL.md index 6b7f30fb76..807b60064c 100644 --- a/.agents/skills/implement-plan/SKILL.md +++ b/.agents/skills/implement-plan/SKILL.md @@ -1,6 +1,6 @@ --- name: implement-plan -description: Implementation flow — execute a ready plan from the session context: read the plan, detect the flow, then present the full picture (issue and branch to create or the branch to continue on, execution style, task checklist) and wait for confirmation. Default is every task with one final commit; on request ("step by step"), one task and one commit at a time with a pause after each. Use it when the user asks to implement or execute a plan, in any phrasing. +description: Implementation flow — execute a ready plan from the session context: read the plan, detect the flow, then present the full picture (issue and branch to create or the branch to continue on, execution style, task checklist) and wait for confirmation. Default is every task with one final commit; on request ("step by step"), one task and one commit at a time with a pause after each; on request ("direct"), no issue and no branch — the commit lands on the current branch. Use it when the user asks to implement or execute a plan, in any phrasing. --- # Implement Plan @@ -45,9 +45,14 @@ read-only: nothing is created until the user confirms (step 3). No issue or branch is created. The branch name provides the issue reference when it follows the `issue-NNNN` pattern. -Arguments override detection: `standalone`, `continue`, -`no issue` / `without issue`, or an explicit base such as -`from origin/develop`. +Arguments override detection: `standalone`, `continue`, `direct` +(`no branch` / `direct commit`), `no issue` / `without issue`, or an +explicit base such as `from origin/develop`. + +**Direct mode** (`direct`, `no branch`, `direct commit`): no issue and +no branch — the implementation and the commit land on the current branch +as it is, even when it is a base branch. Best for small or tooling-only +changes the user wants committed in place. **Standalone while already on a feature branch:** stop and explain that this would stack branches. Ask the user to re-run with an explicit base, for @@ -59,8 +64,10 @@ Before touching the repository, show the user the full picture: - **The flow**: whether the GitHub issue and the branch will be created (standalone mode — give the planned branch name, `issue-NNNN` or - `plan-`), or whether you continue on the current branch - (continue mode — name it). + `plan-`), whether you continue on the current branch + (continue mode — name it), or whether everything lands on the current + branch as it is (direct mode — name it, and say so when it is a base + branch). - **The execution style**: batch or step-by-step (see *Execution modes*). - A checklist (todolist) of the plan's tasks, in order. @@ -84,6 +91,11 @@ If the arguments say `no issue` / `without issue`, skip the issue and create a branch named `plan-` instead, where `` is the plan title, lowercase and hyphen-separated. +If the arguments say `direct` / `no branch` / `direct commit`, skip the +issue and the branch: implement and commit on the current branch as it +is. If it is a base branch, the checklist presentation already said so — +no further confirmation is needed. + ### Batch mode (default) Implement every task in one go. Work methodically, keeping changes @@ -126,7 +138,7 @@ instruction from me overrides them): Extra context in the user's invocation (the message that triggered this skill) plays the role command arguments play elsewhere: `standalone`, -`continue`, `no issue` / `without issue`, an explicit base such as -`from origin/develop`, or `step by step` / `one commit per task` for the -step-by-step execution mode. Modes combine freely, for example -"standalone step by step". +`continue`, `direct` (`no branch` / `direct commit`), `no issue` / +`without issue`, an explicit base such as `from origin/develop`, or +`step by step` / `one commit per task` for the step-by-step execution +mode. Modes combine freely, for example "standalone step by step". diff --git a/.agents/skills/local-ci/SKILL.md b/.agents/skills/local-ci/SKILL.md new file mode 100644 index 0000000000..5cda6acf89 --- /dev/null +++ b/.agents/skills/local-ci/SKILL.md @@ -0,0 +1,95 @@ +--- +name: local-ci +description: Run local CI-style checks with ./scripts/ci (lint, tests, format) per monorepo module. Use when verifying changes before declaring work done, running lint or tests locally, fixing formatting, or repairing Clojure delimiter errors. +--- + +# Local CI + +Run the same checks CI runs, locally, for the modules you touched, with +`scripts/ci`. Each task writes a log file; the final summary says what +passed and what failed. + +Full details: `mem:scripts/ci` (file: `.serena/memories/scripts/ci.md`) + +## When to use + +- After implementing or fixing code — verify every module you touched + before declaring the work done. +- When the user asks to run CI, lint, tests, or format checks locally. +- When you changed `common/` — validate its consumers too. + +**Skip:** while exploring, planning, or reading code. + +## Command reference + +Run from the repo root: + +```bash +./scripts/ci [OPTIONS] [MODULES...] +``` + +Modules: `frontend` `backend` `common` `render-wasm` `exporter` `mcp` +`plugins` `library`, or `--all` for every module. + +With no task flags it runs three tasks per module, in order: **lint**, +**test**, **fmt** (format check; `--fix` formats files instead). + +| Flag | Effect | +|------|--------| +| `--all` | Run every module | +| `--exclude MOD` | Skip one module (repeatable) | +| `--lint` / `--no-lint` | Run only lint / drop lint | +| `--test` / `--no-test` | Run only tests / drop tests | +| `--fmt` / `--no-fmt` | Run only format check / drop it | +| `--fix` | Format files instead of checking (other tasks unaffected) | +| `--paren-repair` | Fix delimiter errors in Clojure/CLJS files | +| `--fail-fast` | Stop at the first failure | +| `--quiet` | Suppress failure output | +| `--dry-run` | Show what would run, execute nothing | +| `--clean` | Delete the `.ci-logs/` directory | + +## Reading failures + +Every task writes its full output to `.ci-logs/-.log`. On +failure the script prints only the last 30 lines. To diagnose a failure, +**read the log file** — never re-run the command piped through filters +(repo rule: redirect to a file first, then read it). The exit code is 1 +when any task failed; the summary lists each failed `module:task` and its +log path. + +## Typical workflows + +```bash +# Verify a module you changed: lint + tests + format check +./scripts/ci frontend + +# Fast pass while iterating: lint only +./scripts/ci --lint frontend + +# Lint + format check, skip the long test suite +./scripts/ci --no-test frontend + +# Format the module without running the test suite +./scripts/ci --fix --no-test frontend + +# Broke delimiters in Clojure/CLJS files: repair first, then lint +./scripts/ci --paren-repair frontend +./scripts/ci --lint frontend + +# Changed common/ — validate its consumers too +./scripts/ci frontend backend exporter + +# Preview what would run, without running it +./scripts/ci --dry-run --all +``` + +## Gotchas + +- Run from the repo root. +- Test tasks are long-running (backend runs `clojure -M:dev:test`); give + the bash call a generous timeout (10–20 minutes) instead of letting it + time out mid-run. +- `mcp` has no lint task — it shows as skipped, not failed. +- `--paren-repair` only fixes delimiters; run lint afterwards to catch + what remains. See `mem:scripts/paren-repair`. +- What to run and how to read test results: `mem:testing`. diff --git a/.opencode/commands/implement-plan.md b/.opencode/commands/implement-plan.md index 69b1bbbf5f..eaf9d29fc3 100644 --- a/.opencode/commands/implement-plan.md +++ b/.opencode/commands/implement-plan.md @@ -1,5 +1,5 @@ --- -description: Execute a ready plan — task checklist, your confirmation, then all tasks with one commit (default) or step by step with a commit and a pause per task; creates issue + branch when on a base branch — loads and follows the implement-plan skill +description: Execute a ready plan — task checklist, your confirmation, then all tasks with one commit (default) or step by step with a commit and a pause per task; creates issue + branch when on a base branch, or commits on the current branch with "direct" — loads and follows the implement-plan skill agent: build --- diff --git a/.serena/memories/critical-info.md b/.serena/memories/critical-info.md index 0854fe28ee..26fcfe2971 100644 --- a/.serena/memories/critical-info.md +++ b/.serena/memories/critical-info.md @@ -78,6 +78,10 @@ module. You can read it from `mem:/core` workspaces (root, modules, member packages). Keeps the shared pnpm store at `/.pnpm-store` unless `--store`; ignores `external/` and `.opencode/`. Usage and reinstall steps: `mem:workflow/updating-pnpm`. +- `scripts/ci` — CI orchestration script: runs lint, tests, and format + checks per module (`frontend backend common render-wasm exporter mcp + plugins library`). Logs go to `.ci-logs/`; read the log file on failure. + See `mem:scripts/ci`. # Dependency graph diff --git a/.serena/memories/scripts/ci.md b/.serena/memories/scripts/ci.md new file mode 100644 index 0000000000..69d3fa6968 --- /dev/null +++ b/.serena/memories/scripts/ci.md @@ -0,0 +1,61 @@ +# CI (scripts/ci) + +`scripts/ci` runs CI-style checks — lint, tests, format — for one or more +monorepo modules and prints a per-task summary. It is the local equivalent +of CI; use it to verify changes before declaring work done. + +## When to use + +- After implementing or fixing code in a module: run its checks before + finishing (AGENTS.md: run the applicable lint and format checks). +- When `common/` changed: validate its consumers too (frontend, backend, + exporter; see the dependency graph in `mem:critical-info`). +- To fix formatting across a module (`--fix`) or repair delimiters + (`--paren-repair`) before linting. + +## How to use (CLI) + +Run from the repo root: + +```bash +./scripts/ci MODULE... # lint + test + fmt per module +./scripts/ci --all --no-test # lint + fmt on all modules +./scripts/ci --lint frontend # lint only +./scripts/ci --fix --no-test frontend # format files, skip tests +./scripts/ci --paren-repair --all # fix delimiters in all Clojure modules +./scripts/ci --dry-run --all # preview what would run +``` + +Modules: `frontend backend common render-wasm exporter mcp plugins library`. + +Flags: + +- Default tasks: `lint`, `test`, `fmt` (format check; `--fix` formats + instead). +- `--lint` / `--test` / `--fmt` run one task only; `--no-lint` / + `--no-test` / `--no-fmt` drop one task from the default set. +- `--paren-repair` runs only the delimiter repair — it wraps + `scripts/paren-repair` over each module's Clojure/CLJS sources; see + `mem:scripts/paren-repair`. +- `--all` selects every module; `--exclude MOD` drops one (repeatable). +- `--fail-fast` stops at the first failure; `--quiet` suppresses failure + output; `--dry-run` prints commands without running; `--clean` removes + the log directory. + +## Logs and exit codes + +- Full output of every task: `.ci-logs/-.log`. +- On failure the script prints the last 30 lines; the final summary lists + every failed `module:task` with its log path. +- Exit code 0 when all selected tasks passed, 1 otherwise. +- Diagnose failures by reading the log file — never pipe test output + through filters (AGENTS.md hard rule). + +## Notes + +- `mcp` has no lint task (shows as skipped). `render-wasm` uses `./lint`, + `./test`, and `cargo fmt`. +- Test tasks are long-running (backend: `clojure -M:dev:test`); use a + generous timeout when calling it from an agent shell. +- Skill entry point: `.agents/skills/local-ci/SKILL.md`. +- Testing principles and output discipline: `mem:testing`. diff --git a/AGENTS.md b/AGENTS.md index a02706f460..bc2b4c9865 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -145,6 +145,6 @@ precision while maintaining a strong focus on maintainability and performance. - `scripts/nrepl-eval.mjs` — Evaluate Clojure code via nREPL (backend + frontend). - `scripts/check-commit` — Validate commit messages against Penpot's commit guidelines. - `scripts/check-fmt-clj` — Check Clojure formatting without modifying files. -- `scripts/ci` — CI orchestration script for running lint, tests, and format checks across modules. See `scripts/ci --help`. +- `scripts/ci` — CI orchestration script for running lint, tests, and format checks across modules. See `mem:scripts/ci`. - `scripts/gh.py` — Multi-purpose GitHub CLI helper. Subcommands: `issues` (list issues in a milestone), `prs` (fetch PR details), `advisories` (list/inspect security advisories). See `python3 scripts/gh.py --help`. diff --git a/docs/img/enterprise/enterprise-access-admin-console.webp b/docs/img/enterprise/enterprise-access-admin-console.webp new file mode 100644 index 0000000000..2c0d98e28b Binary files /dev/null and b/docs/img/enterprise/enterprise-access-admin-console.webp differ diff --git a/docs/img/enterprise/enterprise-admin-console.webp b/docs/img/enterprise/enterprise-admin-console.webp new file mode 100644 index 0000000000..91fc8cc728 Binary files /dev/null and b/docs/img/enterprise/enterprise-admin-console.webp differ diff --git a/docs/img/enterprise/enterprise-membership-w.webp b/docs/img/enterprise/enterprise-membership-w.webp new file mode 100644 index 0000000000..8ebad02478 Binary files /dev/null and b/docs/img/enterprise/enterprise-membership-w.webp differ diff --git a/docs/img/enterprise/enterprise-module-sso.webp b/docs/img/enterprise/enterprise-module-sso.webp new file mode 100644 index 0000000000..48d12cd322 Binary files /dev/null and b/docs/img/enterprise/enterprise-module-sso.webp differ diff --git a/docs/img/enterprise/enterprise-organization-hierarchy-w.webp b/docs/img/enterprise/enterprise-organization-hierarchy-w.webp new file mode 100644 index 0000000000..921358f22a Binary files /dev/null and b/docs/img/enterprise/enterprise-organization-hierarchy-w.webp differ diff --git a/docs/user-guide/account-teams/comments.njk b/docs/user-guide/account-teams/comments.njk index 4d5a2a769b..1cf4752094 100644 --- a/docs/user-guide/account-teams/comments.njk +++ b/docs/user-guide/account-teams/comments.njk @@ -1,6 +1,6 @@ --- title: Comments -order: 4 +order: 6 desc: Learn how to import and export files in Penpot, the free, open-source design tool. Discover file formats, backups, sharing, and library management. --- diff --git a/docs/user-guide/account-teams/enterprise-plan.njk b/docs/user-guide/account-teams/enterprise-plan.njk new file mode 100644 index 0000000000..c9a82c81c4 --- /dev/null +++ b/docs/user-guide/account-teams/enterprise-plan.njk @@ -0,0 +1,35 @@ +--- +title: Enterprise plan +order: 2 +desc: Learn how the Enterprise plan works in Penpot. Discover its features and how to use it within your organization. +--- + +

Enterprise plan

+

Penpot Enterprise gives organizations the tools to govern how design work happens across their teams: from creating a structured org and managing members, to applying fine-grained permissions and configuration through the Admin Console.

+ +

What is Penpot Enterprise? +

+

Penpot Enterprise is the plan that unlocks organizational governance features. While Penpot remains free and unlimited as an open-source platform, Enterprise adds a layer of control on top: the ability to create Organizations, manage teams under it, and apply configuration settings that define what members can and cannot do.

+

The organization owner is the user who creates the organization. They have exclusive access to the Admin Console and are responsible for configuring Modules.

+

The key concepts you'll work with:

+
    +
  • Organization: the top-level structure that groups one or more Teams under a shared governance layer.
  • +
  • Admin Console: the back-office interface where the org owner manages settings, teams and members.
  • +
  • Modules: the paid, configurable capabilities applied to an organization. Each Module consists of individual Controls (specific settings or restrictions).
  • +
+ +

Subscribing to Enterprise + # +

+

To create an organization, you first need to upgrade to the Enterprise plan. Click "Create Organization" to begin. Once the subscription process is complete, you'll be redirected to the Admin Console to finish creating your organization.

+ +

Frequently asked questions + # +

+ +

Can I have multiple organizations?

+

Yes. You can create more than one organization under a single Enterprise subscription and manage them from the Admin Console.

+ +

What happens if I cancel my Enterprise subscription?

+

Your organizations are deleted but not their teams. Governance settings no longer apply to any of them.

+ diff --git a/docs/user-guide/account-teams/index.njk b/docs/user-guide/account-teams/index.njk index e03ed12133..d1d228d3ad 100644 --- a/docs/user-guide/account-teams/index.njk +++ b/docs/user-guide/account-teams/index.njk @@ -13,7 +13,19 @@ desc: Begin with the Penpot user guide! Get quickstarts, shortcuts, and tutorial

Access your account settings and manage personal access tokens

-
  • +
  • + +

    Enterprise plan →

    +

    Learn how the Enterprise plan works and what it includes

    +
    +
  • +
  • + +

    Organizations →

    +

    Create and manage organizations, the Admin Console, and SSO

    +
    +
  • +
  • Teams →

    Create and manage your teams

    diff --git a/docs/user-guide/account-teams/organizations.njk b/docs/user-guide/account-teams/organizations.njk new file mode 100644 index 0000000000..4c9d8ef777 --- /dev/null +++ b/docs/user-guide/account-teams/organizations.njk @@ -0,0 +1,227 @@ +--- +title: Organizations +order: 3 +desc: Learn how Organizations work in Penpot Enterprise, creating one, the Admin Console, membership, Modules and Controls, and Single Sign-On (SSO). +--- + +

    Organizations

    +

    An organization is the governance layer Penpot Enterprise adds on top of your teams. This section covers how to create and manage one: the Admin Console, membership, and the Modules and Controls used to configure it, including Single Sign-On (SSO).

    + +

    Creating an organization + # +

    +

    Creating an organization is as easy as giving it a name.

    +

    Once the organization is created, you'll be taken to the Admin Console. At this point, the organization has one member: you, the owner.

    + +

    The Admin Console + # +

    +

    The Admin Console is the admin interface for your organization. Only the organization owner can access it.

    +

    You can reach the Admin Console directly at /admin-console, or from any team dashboard in Penpot by opening the organization navigation menu and clicking the Admin Console link. If you own more than one organization, you can switch between them from within the Admin Console.

    + +
    + + Accessing the Admin Console + +
    + +

    The Admin Console includes:

    + +
      +
    1. Switch organization menu: To navigate between the organizations you own.
    2. +
    3. Organization settings: To change basic settings, such as renaming it or deleting it.
    4. +
    5. A "Go to files" button that returns you to a team dashboard.
    6. +
    7. Your user avatar, that expands into a full user menu.
    8. +
    9. Module: The control itself to configure.
    10. +
    + +
    + + Admin Console + +
    + +

    Organizations and teams + # +

    +

    An organization groups one or more Teams under a shared governance structure. Teams continue to work just as they do in standard Penpot, with the added layer that the org owner can apply configuration that affects all members across the organization's teams.

    +

    How teams relate to organizations

    + +

    Teams inside an organization inherit the governance settings applied at the org level via the Admin Console. The structure is:

    + +
    + organization-hierarchy +
    + +

    Team members work within projects and files as usual. What changes under Enterprise is the org owner's ability to restrict or govern that work from the Admin Console.

    +

    Within each team, the standard Penpot roles apply.

    + +

    Managing organization membership + # +

    +

    At launch, an organization has a single member: the owner. Additional members are brought in by being part of a team added to the organization, being invited to teams within the organization, or being directly invited to the organization by the owner.

    +

    The Admin Console provides a unified view of all members across teams within the organization.

    + +
    + + Admin-Console Members page + +
    + +

    Modules and Controls + # +

    + +

    Modules are the configurable governance capabilities available to Enterprise organizations. Each Module is made up of one or more Controls: the individual settings that define who can do what, and where.

    +

    Modules are configured from the Admin Console and apply organization-wide.

    + + + + + + + + + + + + + + + + + + +
    ModulesWhat it does
    Single Sign-On (SSO)Requires all org members to authenticate through your corporate identity provider before accessing the organization's teams and files.
    Advanced permissionsDefines who can create, view, edit, administer, or share teams, projects, and files. Also controls who can invite new members to teams.
    + +

    Module: Advanced permissions + # +

    + +

    Advanced Permissions gives the organization owner fine-grained control over what members can do across all teams in the organization. Rather than relying on the default Penpot team roles alone, this module lets you restrict or open up specific actions at the organization level.

    + +

    What it controls

    + +

    The Advanced Permissions module is made up of individual Controls. Each Control governs a specific action, and each has a set of options to choose from. The selected option becomes the rule for the entire organization.

    + +

    How to configure it

    + +

    Advanced Permissions is configured from the Admin Console. Changes apply to all teams within the organization immediately.

    +
      +
    1. Open the Admin Console.
    2. +
    3. Select Advanced Permissions from the left sidebar.
    4. +
    5. For each Control, select the option that fits your governance policy.
    6. +
    7. Changes take effect right away. There is no publish or save step.
    8. +
    + +

    How it relates to team roles

    + +

    Advanced Permissions works on top of the standard Penpot team roles (Viewer, Editor, Admin, Owner). It does not replace them. Think of it as a ceiling: even if a member's team role would normally allow an action, an Advanced Permissions Control can prevent it organization-wide.

    +

    For example, if “New team members” is set to "Organization members only," a team owner who would normally be able to invite anyone will find that option restricted to people who are already part of the organization.

    + +

    Default behavior

    + +

    When an organization is first created, all controls are configured with the most permissive setting; the same setting is used by all teams that are not part of any organization. No behavior changes until you actively configure a Control.

    + +

    Module: Single Sign-On (SSO) + # +

    + +

    Single Sign-On lets you require all members of your organization to authenticate through your corporate identity provider (IdP) before accessing any of the organization's teams and files.

    +

    SSO applies to teams and files only. The Admin Console is always accessible without SSO, so you can always reach your configuration to adjust or deactivate it, even if your own directory entry changes.

    + +

    Configuring your identity provider

    +

    Before setting up SSO in Penpot, you need to register Penpot as an application in your identity provider. The steps vary by provider, but you will always need to set the following callback URL in your IdP configuration:

    +

    https://<your-penpot-domain>/api/auth/oidc/callback

    +

    Your IdP will then give you a Client ID and Client Secret to use in Penpot. Once you have those:

    +
      +
    1. Open the Admin Console.
    2. +
    3. Select SSO Config.
    4. +
    5. Choose your provider and fill in the fields.
    6. +
    + +
    + + SSO configuration + +
    + +
    Generic authentication (OpenID Connect)
    +

    Use this option for any identity provider that supports the OIDC protocol, such as Okta, Keycloak, or Auth0.

    +
      +
    • Issuer / Authority URL: base URL of your OIDC provider, used to autodiscover endpoints
    • +
    • Client ID: client identifier assigned by your provider
    • +
    • Client Secret: client secret assigned by your provider
    • +
    + +
    Azure Active Directory (OpenID Connect)
    +
      +
    • Issuer / Authority URL: https://login.microsoftonline.com/<your-tenant-id>/v2.0/
    • +
    • Client ID: Application (client) ID from your Azure app registration
    • +
    • Client Secret: client secret value from your Azure app registration
    • +
    + +
    Google (OAuth)
    +
      +
    • Client ID: client identifier from your Google Cloud OAuth 2.0 credentials
    • +
    • Client Secret: client secret from your Google Cloud OAuth 2.0 credentials
    • +
    + +

    When all fields are filled, click Activate SSO. Penpot will run a test connection against your IdP. If the connection fails, your draft is kept and no changes are applied.

    +

    If the test passes, a confirmation dialog will appear. It will warn you that members not in your directory will lose access to the organization's teams once SSO is active. Review your member list if needed, then confirm. SSO becomes active immediately.

    + +

    What happens to existing sessions

    +

    When SSO is activated, any member who is currently inside one of the organization's teams is cut off immediately and sent through the SSO login. This does not log them out of Penpot entirely. They can still reach teams that do not belong to your organization without re-authenticating.

    +

    SSO sessions last 4 hours. When a session expires, members are routed through the SSO login again. If they are still in the directory, they are signed back in immediately.

    + +

    Editing an active configuration

    +

    While SSO is active, you can edit any field. As soon as you make a change, Apply changes and Discard changes buttons appear. Discarding restores every field to the current live configuration. Applying runs the same test connection as the initial setup, without a confirmation dialog. If the connection fails, your live configuration is not touched. Changes may take up to 5 minutes to apply for members who are currently working in a file.

    + +

    Deactivating SSO

    +

    Click Deactivate SSO and confirm. The configuration is preserved as a draft so you can reactivate it later without re-entering your credentials. Members are notified by email the first time SSO is activated. If you deactivate and reactivate within 24 hours, the notification is not re-sent.

    + +

    For your members

    +

    Members do not need to do anything to prepare. When they next try to access the organization's teams, they will be asked to authenticate through your IdP. If they are already signed in through that provider, the step is skipped automatically.

    +

    Org membership still requires an invitation from you. Being in the directory alone does not grant access to Penpot or to your organization.

    +

    If a member is not in your directory, they remain an org member but cannot enter the organization's teams until they are added. A single email is sent to all current members and pending invitees when SSO is first activated, explaining what changed and who to contact if they cannot get in.

    + +

    Frequently asked questions + # +

    + +

    Can a team belong to more than one organization?

    +

    No. A team belongs to a single organization.

    + +

    Can non-owners access the Admin Console?

    +

    No. Access to the Admin Console is currently exclusive to the organization owner.

    + +

    What is the organization name used for?

    +

    It's the human-readable name used to identify your organization in the UI, in emails, and in URLs. It is not your official billing name. You can change it at any time without affecting navigation or functionality.

    + +

    Do Advanced Permissions replace the standard Penpot team roles?

    +

    No. Advanced Permissions work on top of the existing roles (Viewer, Editor, Admin, Owner). They add an organization-wide ceiling on what any role can do, but they do not change how roles work within a team.

    + +

    What is the default behavior when I first create an organization?

    +

    All Controls are set to their most permissive option. Nothing changes until you actively configure a Control.

    + +

    What happens to existing team admins if I change a Control that restricts their permissions?

    +

    The restriction applies immediately. An admin who could previously perform an action will no longer be able to do so as soon as the Control is changed, with no grace period.

    + +

    Is this the same as the authentication providers in Penpot's self-hosting configuration?

    +

    No. Penpot's self-hosted configuration lets server administrators enable login methods (Google, GitHub, GitLab, OIDC) at the instance level, so users can sign in to Penpot itself with those providers. That is a server-level setting managed by whoever runs the infrastructure.

    +

    The SSO module in Enterprise is different in scope and purpose. It is configured by you, the organization owner, from the Admin Console, and it governs access to your organization's teams and files specifically. It does not change how users log in to Penpot as a platform, only whether they need to pass through your corporate identity provider to reach your organization's content.

    + +

    Does SSO affect the Admin Console?

    +

    No. The Admin Console is always accessible without SSO, regardless of your configuration. This ensures you can always reach your settings to adjust or deactivate SSO, even if something changes on the directory side.

    + +

    What happens if my identity provider goes down while SSO is active?

    +

    Current sessions continue until they expire. The next time a member tries to authenticate through your IdP and the provider is unreachable, the login will fail. There is no automatic bypass. Since the Admin Console is outside SSO, you can still reach your configuration to deactivate SSO if needed.

    + +

    Can I use the same identity provider for more than one organization?

    +

    Yes. Two different organizations, and the Penpot instance itself, can share the same IdP. A successful SSO login never grants org membership on its own, so there is no risk of cross-organization access. Membership always requires an explicit invitation.

    + +

    What if a member is not in my directory?

    +

    They remain an org member and keep their Penpot account, but they cannot enter the organization's teams until they are added to the directory. We send them an email when SSO is first activated explaining the situation and telling them to contact you.

    + +

    Does accepting an invitation automatically give someone access to my org's teams?

    +

    Only if they are also in your directory. An invitee can register and accept the invitation, but if they are not in the directory, they become an org member without being able to enter the teams. Acceptance is never blocked on that basis.

    diff --git a/docs/user-guide/account-teams/projects-files.njk b/docs/user-guide/account-teams/projects-files.njk index fa3029e7c9..b4befb2ad8 100644 --- a/docs/user-guide/account-teams/projects-files.njk +++ b/docs/user-guide/account-teams/projects-files.njk @@ -1,6 +1,6 @@ --- title: Projects and Files -order: 3 +order: 5 desc: Learn how to organize your work in Penpot. Create, manage and organize projects and files, work with drafts, and handle deleted items. --- diff --git a/docs/user-guide/account-teams/teams.njk b/docs/user-guide/account-teams/teams.njk index 550cf81390..64c39376d3 100644 --- a/docs/user-guide/account-teams/teams.njk +++ b/docs/user-guide/account-teams/teams.njk @@ -1,6 +1,6 @@ --- title: Teams -order: 2 +order: 4 desc: Manage teams and roles with Penpot's collaboration features! Learn how to manage teams, roles (Viewer, Editor, Admin, Owner), send invites and use webhooks. ---