From 2edb6e588ab7ac3763edc29e61580e93b7cc959a Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 10:54:01 +0000 Subject: [PATCH 1/4] docs: document download-only content-as-code scope for editors --- references/workspace/custom-roles.mdx | 18 ++++++++++++++++++ references/workspace/roles.mdx | 6 ++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/references/workspace/custom-roles.mdx b/references/workspace/custom-roles.mdx index 6941f46c..84d7737e 100644 --- a/references/workspace/custom-roles.mdx +++ b/references/workspace/custom-roles.mdx @@ -103,6 +103,24 @@ Custom roles are assigned at the project level to provide granular access contro ## Scope reference +### Content-as-code scopes + +Two scopes control access to [content as code](/guides/developer/dashboards-as-code), the CLI workflow for managing charts and dashboards as YAML files. + +**Download content as code** (`view:ContentAsCode`) lets a user pull existing charts and dashboards as YAML via `lightdash download`. It does not allow pushing changes back. + +**Download and upload content as code** (`manage:ContentAsCode`) grants both download and upload. Users with this scope can run `lightdash upload` to overwrite charts and dashboards in the project. + +Use **download-only** to let a user pull production YAML for local development, diffing, or inspection without giving them the ability to overwrite production content. Combine with a controlled promotion path (e.g., CI/CD running with a service account that holds the manage scope) so writes only land via the pipeline. + +For example, to protect a production project from accidental `lightdash upload` overwrites: + +1. Downgrade the user's org role to **Member** or **Viewer** so they don't inherit `manage:ContentAsCode` from their org role. +2. Create a custom project role with only **Download content as code** enabled (plus whatever else they need). +3. Assign the custom role to the user on the production project. + +The user can now run `lightdash download` against production but will get a `403` on `lightdash upload`. + ### SQL-related scopes Three scopes control different SQL-authoring features. They are independent — granting one does not grant the others. diff --git a/references/workspace/roles.mdx b/references/workspace/roles.mdx index 0f1f2985..f5119486 100644 --- a/references/workspace/roles.mdx +++ b/references/workspace/roles.mdx @@ -35,7 +35,8 @@ Project Admins can invite users to their project and assign users or [groups](/r | Manage project access and permissions | | | | | | | Delete project | | | | | | | Create a preview project | | | | | | -| Use dashboards as code (CLI) | | | | | | +| Download content as code (CLI) | | | | | | +| Upload content as code (CLI) | | | | | | | Rename models, dimensions, and metrics (CLI and UI) | | | | | | @@ -54,7 +55,8 @@ Organization Admins can assign roles to organization members, which gives access | Admin for **all** projects | | | | | | | | Invite users to organization | | | | | | | | Manage organization access and permissions | | | | | | | -| Use dashboards as code (CLI) | | | | | | +| Download content as code (CLI) | | | | | | +| Upload content as code (CLI) | | | | | | | Rename models, dimensions, and metrics (CLI and UI) | | | | | | From 3033b958ac9a9f2f1621b7db11d142337e7b5214 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 11:42:54 +0000 Subject: [PATCH 2/4] docs: document manage:ContentAsCode@self scope for own-preview uploads --- references/workspace/custom-roles.mdx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/references/workspace/custom-roles.mdx b/references/workspace/custom-roles.mdx index 84d7737e..6e84a122 100644 --- a/references/workspace/custom-roles.mdx +++ b/references/workspace/custom-roles.mdx @@ -105,21 +105,27 @@ Custom roles are assigned at the project level to provide granular access contro ### Content-as-code scopes -Two scopes control access to [content as code](/guides/developer/dashboards-as-code), the CLI workflow for managing charts and dashboards as YAML files. +Three scopes control access to [content as code](/guides/developer/dashboards-as-code), the CLI workflow for managing charts and dashboards as YAML files. They form a read → write → narrow-write ladder. -**Download content as code** (`view:ContentAsCode`) lets a user pull existing charts and dashboards as YAML via `lightdash download`. It does not allow pushing changes back. +**Download content as code** (`view:ContentAsCode`) lets a user pull existing charts and dashboards as YAML via `lightdash download`. It does not allow pushing changes back. This is the common "let people pull templates" grant. -**Download and upload content as code** (`manage:ContentAsCode`) grants both download and upload. Users with this scope can run `lightdash upload` to overwrite charts and dashboards in the project. +**Upload content as code to own previews** (`manage:ContentAsCode@self`) is a narrow upload right: users can run `lightdash upload` only against preview projects they created themselves. This is the intended day-to-day scope for non-Developer users in CI/CD-style workflows where they need to validate their own preview but shouldn't push to shared projects. Pair it with `view:ContentAsCode` so they can still pull from shared projects. + +**Download and upload content as code** (`manage:ContentAsCode`) grants both download and upload across any project the role applies to. Users with this scope can run `lightdash upload` to overwrite charts and dashboards in the project. This implies `view:ContentAsCode` and the `@self` upload right. Use **download-only** to let a user pull production YAML for local development, diffing, or inspection without giving them the ability to overwrite production content. Combine with a controlled promotion path (e.g., CI/CD running with a service account that holds the manage scope) so writes only land via the pipeline. -For example, to protect a production project from accidental `lightdash upload` overwrites: +For example, to protect a production project from accidental `lightdash upload` overwrites while still letting users iterate on previews: 1. Downgrade the user's org role to **Member** or **Viewer** so they don't inherit `manage:ContentAsCode` from their org role. -2. Create a custom project role with only **Download content as code** enabled (plus whatever else they need). +2. Create a custom project role with **Download content as code** and **Upload content as code to own previews** enabled (plus whatever else they need). 3. Assign the custom role to the user on the production project. -The user can now run `lightdash download` against production but will get a `403` on `lightdash upload`. +The user can now run `lightdash download` against production and `lightdash upload` against their own preview projects, but will get a `403` on `lightdash upload` to production. + + + A custom role cloned from **Developer** can drop the full **Upload content as code** scope while keeping **Upload content as code to own previews** — this mirrors built-in Developer behavior for the own-preview case while removing write access to shared projects. + ### SQL-related scopes From 8e10c2e43eb1be4514ba4ddf0cc4c880ac728636 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:01:13 +0000 Subject: [PATCH 3/4] docs: expand agentic development workflow for content-as-code scopes --- references/workspace/custom-roles.mdx | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/references/workspace/custom-roles.mdx b/references/workspace/custom-roles.mdx index 6e84a122..cd659174 100644 --- a/references/workspace/custom-roles.mdx +++ b/references/workspace/custom-roles.mdx @@ -115,17 +115,26 @@ Three scopes control access to [content as code](/guides/developer/dashboards-as Use **download-only** to let a user pull production YAML for local development, diffing, or inspection without giving them the ability to overwrite production content. Combine with a controlled promotion path (e.g., CI/CD running with a service account that holds the manage scope) so writes only land via the pipeline. -For example, to protect a production project from accidental `lightdash upload` overwrites while still letting users iterate on previews: +#### Restrict developers to preview uploads (agentic development workflow) -1. Downgrade the user's org role to **Member** or **Viewer** so they don't inherit `manage:ContentAsCode` from their org role. -2. Create a custom project role with **Download content as code** and **Upload content as code to own previews** enabled (plus whatever else they need). -3. Assign the custom role to the user on the production project. +A common pattern for agentic development of dashboards and content as code is to let developers iterate freely on their own preview projects while preventing direct `lightdash upload` to production. Promotion to production then happens through a reviewed CI/CD pipeline instead of an individual's CLI. -The user can now run `lightdash download` against production and `lightdash upload` against their own preview projects, but will get a `403` on `lightdash upload` to production. +To set this up: - - A custom role cloned from **Developer** can drop the full **Upload content as code** scope while keeping **Upload content as code to own previews** — this mirrors built-in Developer behavior for the own-preview case while removing write access to shared projects. - +1. **Clone the built-in Developer role** to create a custom role (for example, `Developer (no prod upload)`). +2. **Remove** the **Download and upload content as code** (`manage:ContentAsCode`) scope from the cloned role. +3. **Add** the **Download content as code** (`view:ContentAsCode`) and **Upload content as code to own previews** (`manage:ContentAsCode@self`) scopes. +4. **Assign the custom role to the user at the project level** on the production project. + + + Custom project roles can only narrow scopes the user would otherwise inherit. If the user is an **Organization Admin** or **Organization Developer**, they will inherit `manage:ContentAsCode` from their org role and the project-level custom role will not block them. For this pattern to work, the user's organization role must be **Viewer**, **Interactive Viewer**, or **Member**. + + +With this setup, the user can: + +- Run `lightdash download` against the production project to pull YAML for local editing. +- Run `lightdash preview` and `lightdash upload` against their own preview projects to validate changes. +- Receive a `403` when attempting `lightdash upload` against the production project — production writes must go through the promotion pipeline. ### SQL-related scopes From 28c38b797be82b763e2035f556b7e3fbb86f8f6b Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 12:04:25 +0000 Subject: [PATCH 4/4] docs: mention UI promote-content as alternative prod promotion path --- references/workspace/custom-roles.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/references/workspace/custom-roles.mdx b/references/workspace/custom-roles.mdx index cd659174..1d8eaf8c 100644 --- a/references/workspace/custom-roles.mdx +++ b/references/workspace/custom-roles.mdx @@ -117,7 +117,7 @@ Use **download-only** to let a user pull production YAML for local development, #### Restrict developers to preview uploads (agentic development workflow) -A common pattern for agentic development of dashboards and content as code is to let developers iterate freely on their own preview projects while preventing direct `lightdash upload` to production. Promotion to production then happens through a reviewed CI/CD pipeline instead of an individual's CLI. +A common pattern for agentic development of dashboards and content as code is to let developers iterate freely on their own preview projects while preventing direct `lightdash upload` to production. Promotion to production then happens through a reviewed CI/CD pipeline instead of an individual's CLI, or through [promoting content](/guides/how-to-promote-content) in the UI. To set this up: