From eddfcc491aee33e62bbe4060ab2d7f0797009bd6 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 10 Feb 2026 12:27:13 -0800 Subject: [PATCH 1/4] Regenerate permissions documentation from backend source - Add scripts/generate_permissions_docs.py to generate permissions tables from backend source files (data.json and org_initials.json) - Replace hardcoded permissions tables with auto-generated content - Add 18 previously missing resources (Attestation, Analytics, etc.) - Add missing permissions (workflow execution, delete comments, etc.) - Document model-level permissions with correct roles: - Model Owner, Model Developer, Model Validator, Basic User - Apply UI terminology mapping (Finding -> Artifact) - Add role descriptions for both org-level and model-level roles - Restructure page to explain two-level permission system --- scripts/generate_permissions_docs.py | 348 ++++++++++++++++++ .../configuration/_permissions-generated.qmd | 337 +++++++++++++++++ .../configuration/manage-permissions.qmd | 193 +--------- 3 files changed, 696 insertions(+), 182 deletions(-) create mode 100644 scripts/generate_permissions_docs.py create mode 100644 site/guide/configuration/_permissions-generated.qmd diff --git a/scripts/generate_permissions_docs.py b/scripts/generate_permissions_docs.py new file mode 100644 index 0000000000..9e9484fdaa --- /dev/null +++ b/scripts/generate_permissions_docs.py @@ -0,0 +1,348 @@ +#!/usr/bin/env python3 +""" +Generate permissions documentation from backend source files. + +This script reads the permission definitions from the backend repository +and generates Quarto markdown tables for the documentation. + +Source files: +- backend/src/backend/templates/platform_resources/data.json +- backend/src/backend/templates/platform_resources/org_initials.json + +Usage: + python scripts/generate_permissions_docs.py + +Output: + site/guide/configuration/_permissions-generated.qmd +""" + +import json +import os +import re +from pathlib import Path +from typing import Any + +# Paths relative to documentation repo root +SCRIPT_DIR = Path(__file__).parent +REPO_ROOT = SCRIPT_DIR.parent +BACKEND_ROOT = REPO_ROOT.parent / "backend" + +DATA_JSON = BACKEND_ROOT / "src/backend/templates/platform_resources/data.json" +ROLES_JSON = BACKEND_ROOT / "src/backend/templates/platform_resources/org_initials.json" +OUTPUT_FILE = REPO_ROOT / "site/guide/configuration/_permissions-generated.qmd" + +# UI terminology mapping (Finding -> Artifact) +TERMINOLOGY_MAP = { + "Finding": "Artifact", + "finding": "artifact", +} + + +def format_action_name(action_id: str, action_name: str | None = None) -> str: + """Format action ID into human-readable name.""" + # Use provided name if available + if action_name: + name = action_name + else: + name = action_id + + # Remove common prefixes + for prefix in ["read_", "create_", "update_", "delete_", "add_", "manage_"]: + if name.startswith(prefix): + name = name[len(prefix):] + break + + # Replace underscores with spaces + name = name.replace("_", " ") + + # Capitalize first letter of each word + name = " ".join(word.capitalize() for word in name.split()) + + # Apply terminology mapping + for old, new in TERMINOLOGY_MAP.items(): + name = name.replace(old, new) + + return name + + +def format_resource_name(name: str) -> str: + """Format resource name for display.""" + # Apply terminology mapping + for old, new in TERMINOLOGY_MAP.items(): + name = name.replace(old, new) + return name + + +def get_action_display_name(action: dict) -> str: + """Get display name for an action.""" + action_id = action.get("id", "") + action_name = action.get("name", "") + description = action.get("description", "") + + # Build display name from action name or ID + if action_name and action_name not in ["read", "create", "update", "delete", "add"]: + display = action_name.replace("_", " ").title() + else: + # Use action_id but format it nicely + display = action_id.replace("_", " ").title() + + # Apply terminology mapping + for old, new in TERMINOLOGY_MAP.items(): + display = display.replace(old, new) + + return display + + +def checkbox(checked: bool) -> str: + """Return HTML checkbox markup.""" + if checked: + return '' + return '' + + +def load_json(path: Path) -> Any: + """Load JSON file.""" + with open(path, "r") as f: + return json.load(f) + + +def get_role_permissions(roles_data: dict) -> dict: + """Extract permissions for each role.""" + defaults = roles_data.get("defaults", {}) + all_roles_perms = set(defaults.get("all_roles", [])) + model_scope_perms = set(defaults.get("model_scope_roles", [])) + + role_perms = {} + for role_name, role_data in roles_data.get("roles", {}).items(): + if role_name in ["Staff"]: # Skip internal roles + continue + perms = set(role_data.get("permissions", [])) + scope = role_data.get("scope", "Organization") + is_basic = role_data.get("is_basic_role", False) + + # Add default permissions + if scope == "Organization": + perms = perms.union(all_roles_perms) + elif scope == "Model": + perms = perms.union(model_scope_perms).union(all_roles_perms) + + role_perms[role_name] = { + "permissions": perms, + "scope": scope, + "is_basic": is_basic, + } + + return role_perms + + +def has_permission(role_perms: dict, role_name: str, action_id: str) -> bool: + """Check if a role has a specific permission.""" + if role_name not in role_perms: + return False + + perms = role_perms[role_name]["permissions"] + + # Direct match + if action_id in perms: + return True + + # Wildcard match (e.g., read_cf_* matches read_cf_anything) + for perm in perms: + if perm.endswith("*"): + prefix = perm[:-1] + if action_id.startswith(prefix): + return True + + # Customer Admin has all permissions + if role_name == "Customer Admin": + return True + + return False + + +def generate_org_permissions_table( + resources: list, role_perms: dict, org_roles: list +) -> str: + """Generate markdown table for organization-level permissions.""" + lines = [] + + for resource in resources: + resource_id = resource.get("id", "") + resource_name = format_resource_name(resource.get("name", resource_id)) + parent_id = resource.get("parent_id") + actions = resource.get("actions", []) + + # Skip if no actions or if model-scoped + if not actions or parent_id == "Model": + continue + + # Skip internal resources + if resource_id.startswith("dt_") or resource_id in ["WorkflowStatus"]: + continue + + lines.append(f"\n#### {resource_name}\n") + + # Build header + header = "| Permission |" + sep = "|---|" + for role in org_roles: + header += f" {role} |" + sep += ":---:|" + lines.append(header) + lines.append(sep) + + # Build rows + for action in actions: + action_id = action.get("id", "") + is_visible = action.get("is_visible", True) + if not is_visible: + continue + + display_name = get_action_display_name(action) + row = f"| {display_name} |" + + for role in org_roles: + checked = has_permission(role_perms, role, action_id) + row += f" {checkbox(checked)} |" + + lines.append(row) + + lines.append(f': **{resource_name}** permissions {{.hover tbl-colwidths="[40,20,20,20]"}}') + + return "\n".join(lines) + + +def generate_model_permissions_table( + resources: list, role_perms: dict, model_roles: list +) -> str: + """Generate markdown table for model-level permissions.""" + lines = [] + + for resource in resources: + resource_id = resource.get("id", "") + resource_name = format_resource_name(resource.get("name", resource_id)) + parent_id = resource.get("parent_id") + actions = resource.get("actions", []) + + # Only include model-scoped resources + if parent_id != "Model" or not actions: + continue + + # Skip dt_ resources (document types) - internal + if resource_id.startswith("dt_"): + continue + + lines.append(f"\n#### {resource_name}\n") + + # Build header + header = "| Permission |" + sep = "|---|" + for role in model_roles: + header += f" {role} |" + sep += ":---:|" + lines.append(header) + lines.append(sep) + + # Build rows + for action in actions: + action_id = action.get("id", "") + is_visible = action.get("is_visible", True) + if not is_visible: + continue + + display_name = get_action_display_name(action) + row = f"| {display_name} |" + + for role in model_roles: + checked = has_permission(role_perms, role, action_id) + row += f" {checkbox(checked)} |" + + lines.append(row) + + lines.append(f': **{resource_name}** permissions {{.hover tbl-colwidths="[28,18,18,18,18]"}}') + + return "\n".join(lines) + + +def main(): + """Generate permissions documentation.""" + print(f"Loading {DATA_JSON}") + resources = load_json(DATA_JSON) + + print(f"Loading {ROLES_JSON}") + roles_data = load_json(ROLES_JSON) + role_perms = get_role_permissions(roles_data) + + # Define role groups + org_roles = ["Customer Admin", "Developer", "Validator"] + model_roles = ["Model Owner", "Model Developer", "Model Validator", "Basic User"] + + # Generate output + output = [] + + output.append(""" + +## Organization-level permissions + +Organization-level permissions apply to all users in your organization based on their assigned role. These permissions control access to platform-wide settings and configurations. + +::: {.callout-note} +The [{{< fa hand >}} Customer Admin]{.bubble} role has full access to all organization-level permissions and cannot be modified. +::: +""") + + output.append(generate_org_permissions_table(resources, role_perms, org_roles)) + + output.append(""" + +## Model-level permissions + +Model-level permissions control what users can do within the context of a specific model. Users are assigned model-level roles when they are added as stakeholders to a model. + +::: {.callout-tip} +Model-level permissions are additive to organization-level permissions. A user with the Validator role at the organization level who is also assigned as Model Validator on a specific model will have both sets of permissions for that model. +::: +""") + + output.append(generate_model_permissions_table(resources, role_perms, model_roles)) + + output.append(""" + +## Role descriptions + +### Organization-level roles + +| Role | Description | +|------|-------------| +| Customer Admin | Full administrative access to the organization. Can manage users, roles, and all settings. | +| Validator | Can create and manage models, templates, guidelines, and perform validation activities. | +| Developer | Can create models and view organization settings. Limited administrative access. | +| Basic User | Minimal permissions. Can only access models they are explicitly added to as stakeholders. | + +### Model-level roles + +| Role | Description | +|------|-------------| +| Model Owner | Full control over a specific model including deletion and stakeholder management. | +| Model Developer | Can edit model documentation and monitoring. | +| Model Validator | Can perform validation activities, add findings, and edit validation reports. | +: Role descriptions {.hover} +""") + + # Write output + OUTPUT_FILE.parent.mkdir(parents=True, exist_ok=True) + with open(OUTPUT_FILE, "w") as f: + f.write("\n".join(output)) + + print(f"Generated {OUTPUT_FILE}") + + +if __name__ == "__main__": + main() diff --git a/site/guide/configuration/_permissions-generated.qmd b/site/guide/configuration/_permissions-generated.qmd new file mode 100644 index 0000000000..f635280b56 --- /dev/null +++ b/site/guide/configuration/_permissions-generated.qmd @@ -0,0 +1,337 @@ + + +## Organization-level permissions + +Organization-level permissions apply to all users in your organization based on their assigned role. These permissions control access to platform-wide settings and configurations. + +::: {.callout-note} +The [{{< fa hand >}} Customer Admin]{.bubble} role has full access to all organization-level permissions and cannot be modified. +::: + + +#### Model + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Log Tracking | | | | +| Update Model | | | | +| Create Model | | | | +| Delete Model | | | | +| Download Vr | | | | +| Read Model | | | | +| Download Doc | | | | +: **Model** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Role + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Delete Role | | | | +| Create Role | | | | +| Read Role | | | | +| Update Role | | | | +: **Role** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Group + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Create Group | | | | +| Read Group | | | | +| Update Group | | | | +| Delete Group | | | | +: **Group** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### User + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Create User | | | | +| Update User | | | | +| Read User | | | | +| Delete User | | | | +: **User** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Organization + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Invite User | | | | +| Create Organization | | | | +| Read Organization | | | | +| Update Organization | | | | +| Delete Organization | | | | +: **Organization** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Template + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Update Template | | | | +| Duplicate | | | | +| Read Template | | | | +| Create Template | | | | +| Delete Template | | | | +: **Template** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Workflow + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Create Workflow | | | | +| Read Workflow | | | | +| Update Workflow | | | | +| Delete Workflow | | | | +| Execution-Read | | | | +| Execution-Manage | | | | +: **Workflow** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Document Type + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Create Document Type | | | | +| Read Document Type | | | | +| Update Document Type | | | | +| Delete Document Type | | | | +: **Document Type** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Artifact Types + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Manage Artifact Types | | | | +: **Artifact Types** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Artifact Severity + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Artifact Severity | | | | +| Manage | | | | +: **Artifact Severity** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Attestation + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Add Attestation | | | | +| Read Attestation | | | | +| Update Attestation | | | | +| Delete Attestation | | | | +: **Attestation** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Analytics + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Analytics | | | | +| Update Analytics | | | | +: **Analytics** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Inventory Model Schema + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Inventory Schema | | | | +| Update Inventory Schema | | | | +: **Inventory Model Schema** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Artifact Schema + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Artifact Schema | | | | +| Update Artifact Schema | | | | +: **Artifact Schema** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Use Case + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Use Case | | | | +| Add Use Case | | | | +| Update Use Case | | | | +| Delete Use Case | | | | +: **Use Case** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Risk Area + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Risk Area | | | | +| Update Risk Area | | | | +| Delete Risk Area | | | | +| Add Risk Area | | | | +: **Risk Area** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Business Unit + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Add Business Unit | | | | +| Read Business Unit | | | | +| Update Business Unit | | | | +| Delete Business Unit | | | | +: **Business Unit** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Guideline Assessment Option + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Add Assessment Option | | | | +| Read Assessment Option | | | | +| Update Assessment Option | | | | +| Delete Assessment Option | | | | +: **Guideline Assessment Option** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Guidelines + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Add Guideline | | | | +| Read Guideline | | | | +| Update Guideline | | | | +| Delete Guideline | | | | +: **Guidelines** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Status + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Add Status | | | | +| Read Status | | | | +| Update Status | | | | +| Delete Status | | | | +: **Status** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### BlockLibrary + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Manage Shared Block Library | | | | +: **BlockLibrary** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### ValidChecker Question + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Validchecker Question | | | | +| Manage | | | | +: **ValidChecker Question** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### ValidChecker Assessment Version + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Validchecker Assessment Version | | | | +| Manage | | | | +: **ValidChecker Assessment Version** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Regulation + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Regulation | | | | +| Manage | | | | +: **Regulation** permissions {.hover tbl-colwidths="[40,20,20,20]"} + +#### Primary Record Type + +| Permission | Customer Admin | Developer | Validator | +|---|:---:|:---:|:---:| +| Read Primary Record Type | | | | +| Manage | | | | +: **Primary Record Type** permissions {.hover tbl-colwidths="[40,20,20,20]"} + + +## Model-level permissions + +Model-level permissions control what users can do within the context of a specific model. Users are assigned model-level roles when they are added as stakeholders to a model. + +::: {.callout-tip} +Model-level permissions are additive to organization-level permissions. A user with the Validator role at the organization level who is also assigned as Model Validator on a specific model will have both sets of permissions for that model. +::: + + +#### Model Artifact Remediation Plan + +| Permission | Model Owner | Model Developer | Model Validator | Basic User | +|---|:---:|:---:|:---:|:---:| +| Update Artifact Remediation Plan | | | | | +: **Model Artifact Remediation Plan** permissions {.hover tbl-colwidths="[28,18,18,18,18]"} + +#### Inventory Model User + +| Permission | Model Owner | Model Developer | Model Validator | Basic User | +|---|:---:|:---:|:---:|:---:| +| Add Model User | | | | | +| Delete Model User | | | | | +: **Inventory Model User** permissions {.hover tbl-colwidths="[28,18,18,18,18]"} + +#### Model Validation Report + +| Permission | Model Owner | Model Developer | Model Validator | Basic User | +|---|:---:|:---:|:---:|:---:| +| Delete Comment | | | | | +| Read Vr | | | | | +| Assess Guideline | | | | | +| Add Block | | | | | +| Remove Block | | | | | +| Update Vr | | | | | +| Add Comment | | | | | +| Swap Template | | | | | +: **Model Validation Report** permissions {.hover tbl-colwidths="[28,18,18,18,18]"} + +#### Model Documentation + +| Permission | Model Owner | Model Developer | Model Validator | Basic User | +|---|:---:|:---:|:---:|:---:| +| Delete Comment | | | | | +| Read Doc | | | | | +| Add Block | | | | | +| Remove Block | | | | | +| Update Doc | | | | | +| Add Comment | | | | | +| Swap Template | | | | | +: **Model Documentation** permissions {.hover tbl-colwidths="[28,18,18,18,18]"} + +#### Model Artifacts + +| Permission | Model Owner | Model Developer | Model Validator | Basic User | +|---|:---:|:---:|:---:|:---:| +| Manage Attachments | | | | | +| Add Artifact | | | | | +| Update Artifact | | | | | +| Delete Artifact | | | | | +| Add Comment | | | | | +| Read Artifact | | | | | +: **Model Artifacts** permissions {.hover tbl-colwidths="[28,18,18,18,18]"} + + +## Role descriptions + +### Organization-level roles + +| Role | Description | +|------|-------------| +| Customer Admin | Full administrative access to the organization. Can manage users, roles, and all settings. | +| Validator | Can create and manage models, templates, guidelines, and perform validation activities. | +| Developer | Can create models and view organization settings. Limited administrative access. | +| Basic User | Minimal permissions. Can only access models they are explicitly added to as stakeholders. | + +### Model-level roles + +| Role | Description | +|------|-------------| +| Model Owner | Full control over a specific model including deletion and stakeholder management. | +| Model Developer | Can edit model documentation and monitoring. | +| Model Validator | Can perform validation activities, add findings, and edit validation reports. | +: Role descriptions {.hover} diff --git a/site/guide/configuration/manage-permissions.qmd b/site/guide/configuration/manage-permissions.qmd index 9b8ba585fb..489ff1f9d9 100644 --- a/site/guide/configuration/manage-permissions.qmd +++ b/site/guide/configuration/manage-permissions.qmd @@ -11,6 +11,11 @@ aliases: Permissions dictate user access controls within the {{< var validmind.platform >}}, and are associated with specific roles. Assign granular permissions to roles according to your organization's custom requirements. +{{< var vm.product >}} uses a two-level permission system: + +- **Organization-level permissions** control access to platform-wide settings and are assigned through organization roles (Customer Admin, Developer, Validator, Basic User). +- **Model-level permissions** control what users can do within specific models and are assigned when users are added as stakeholders to a model (Model Owner, Model Developer, Model Validator). + ::: {.attn} ## Prerequisites @@ -29,191 +34,15 @@ Please note that the [{{< fa hand >}} Customer Admin]{.bubble} role has the high {{< include _manage-permissions.qmd >}} -### Default permissions - -The following tables outline the default roles and stock permissions provided by {{< var vm.product >}}: - -#### Workflow - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Create Workflow | | | | -| Read Workflow | | | | -| Delete Workflow | | | | -| Update Workflow | | | | -: **Workflow** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Role - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Create Role | | | | -| Update Role | | | | -| Delete Role | | | | -| Read Role | | | | -: **Role** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Model - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Log Tracking | | | | -| Update Model | | | | -| Download VR | | | | -| Delete Model | | | | -| Download Doc | | | | -| Read Model | | | | -| Create Model | | | | -: **Model** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Severity - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Severity | | | | -: **Severity** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Assessment Option - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Assessment Option | | | | -| Add Assessment Option | | | | -| Delete Assessment Option | | | | -| Update Assessment Option | | | | -: **Assessment Option** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Guideline - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Guideline | | | | -| Add Guideline | | | | -| Delete Guideline | | | | -| Update Guideline | | | | -: **Guideline** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Business Unit - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Business Unit | | | | -| Add Business Unit | | | | -| Update Business Unit | | | | -| Delete Business Unit | | | | -: **Business Unit** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Status - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Status | | | | -| Add Status | | | | -| Update Status | | | | -| Delete Status | | | | -: **Status** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Group - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Create Group | | | | -| Read Group | | | | -| Update Group | | | | -| Delete Group | | | | -: **Group** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Use Case - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Use Case | | | | -| Add Use Case | | | | -| Update Use Case | | | | -| Delete Use Case | | | | -: **Use Case** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Risk Area - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Risk Area | | | | -| Update Risk Area | | | | -| Delete Risk Area | | | | -| Add Risk Area | | | | -: **Risk Area** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Template - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Duplicate Template | | | | -| Update Template | | | | -| Read Template | | | | -| Create Template | | | | -| Delete Template | | | | -: **Template** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### User - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Create User | | | | -| Update User | | | | -| Delete User | | | | -| Read User | | | | -: **User** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Organization - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Read Organization | | | | -| Update Organization | | | | -| Invite User Organization | | | | -| Create Organization | | | | -| Delete Organization | | | | -: **Organization** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Validation Report - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Add Block VR | | | | -| Remove Block VR | | | | -| Update VR | | | | -| Add Comment VR | | | | -| Swap Template VR | | | | -| Read VR | | | | -| Assess Guideline | | | | -: **Validation Report** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Documentation - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Add Block Doc | | | | -| Remove Block Doc | | | | -| Update Doc | | | | -| Add Comment Doc | | | | -| Swap Template Doc | | | | -| Read Doc | | | | -: **Documentation** permissions {.hover tbl-colwidths="[40,20,20,20]"} - -#### Artifact - -| Permission | Customer Admin | Developer | Validator | -|---|:---:|:---:|:---:| -| Delete Artifact | | | | -| Add Artifact | | | | -| Add Artifact Comment | | | | -| Update Artifact | | | | -| Read Artifact | | | | -: **Artifact** permissions {.hover tbl-colwidths="[40,20,20,20]"} +## Default permissions + +The following tables outline the default roles and permissions provided by {{< var vm.product >}}. + +{{< include _permissions-generated.qmd >}} [^1]: [Manage roles](manage-roles.qmd) -[^2]: [Default permissions](#default-permissions) \ No newline at end of file +[^2]: [Default permissions](#default-permissions) From a931aab2f5c40923838e97eb568657f3acfed12a Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 10 Feb 2026 12:30:42 -0800 Subject: [PATCH 2/4] Add documentation for generate_permissions_docs.py script --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index f87db708af..427c8a3e46 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,26 @@ After you pull in the changes, commit them to this repo as part of the release n > [!TIP] > **Want to author new code samples?** Refer to our [Jupyter Notebook template Quickstart](https://github.com/validmind/validmind-library/tree/main/notebooks/templates)! +### Permissions documentation + +The permissions tables in `site/guide/configuration/manage-permissions.qmd` are auto-generated from the backend source files. To regenerate: + +```bash +python scripts/generate_permissions_docs.py +``` + +**Requirements:** +- The `backend` repo must be cloned at `../backend/` relative to this repo +- Python 3.9+ + +The script reads from: +- `backend/src/backend/templates/platform_resources/data.json` — resource and action definitions +- `backend/src/backend/templates/platform_resources/org_initials.json` — role permission assignments + +Output: `site/guide/configuration/_permissions-generated.qmd` + +Run this script when backend permission definitions change to keep documentation in sync. + ## Local development with Kind From c3b52b8937cd6b83ca8e2eee7f9c9d2c97ee7631 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 10 Feb 2026 12:31:59 -0800 Subject: [PATCH 3/4] Add comment pointing to script and README for permissions generation --- site/guide/configuration/manage-permissions.qmd | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/site/guide/configuration/manage-permissions.qmd b/site/guide/configuration/manage-permissions.qmd index 489ff1f9d9..3bfa4b054e 100644 --- a/site/guide/configuration/manage-permissions.qmd +++ b/site/guide/configuration/manage-permissions.qmd @@ -38,6 +38,11 @@ Please note that the [{{< fa hand >}} Customer Admin]{.bubble} role has the high The following tables outline the default roles and permissions provided by {{< var vm.product >}}. + {{< include _permissions-generated.qmd >}} From 580c96933b35726f84e906e0fd5c147df239be4a Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 10 Feb 2026 12:41:59 -0800 Subject: [PATCH 4/4] Add copyright header to generated permissions file --- scripts/generate_permissions_docs.py | 6 +++++- site/guide/configuration/_permissions-generated.qmd | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/generate_permissions_docs.py b/scripts/generate_permissions_docs.py index 9e9484fdaa..9e9fd2f029 100644 --- a/scripts/generate_permissions_docs.py +++ b/scripts/generate_permissions_docs.py @@ -280,7 +280,11 @@ def main(): # Generate output output = [] - output.append(""" + + +