Permissions are embedded in the JWT access token. If you change a role’s permissions — either by editing GetPermissionsForRole() in code or by updating a custom role via the API — affected users continue using the old permissions until their current access token expires (up to 15 minutes) and they get a new one via refresh.There is no built-in mechanism to immediately revoke access tokens for a specific role change. For permission removals that must take effect immediately, the only option is to force re-authentication for the affected users.
You cannot use built-in role names (Owner, Admin, Member) for custom roles.
A role must have at least one permission.
Permission strings must exactly match constants in Permissions.cs. Invalid strings are rejected with a validation error.
The Owner role cannot be deleted or modified. It always has all permissions.
Each tenant can have at most one Owner.
{"docsConfig":{"$schema":"https://mintlify.com/docs.json","theme":"mint","name":"AspFox","colors":{"primary":"#1A56DB","light":"#4F83E8","dark":"#1340A8"},"favicon":"https://mintlify.s3.us-west-1.amazonaws.com/aspfox/favicon.ico","logo":{"light":"https://mintcdn.com/aspfox/0JBeTLnQv3MRGYjF/logo/light.svg?fit=max\u0026auto=format\u0026n=0JBeTLnQv3MRGYjF\u0026q=85\u0026s=05c6eccc1c040b89a1507fd933a51757","dark":"https://mintcdn.com/aspfox/0JBeTLnQv3MRGYjF/logo/dark.svg?fit=max\u0026auto=format\u0026n=0JBeTLnQv3MRGYjF\u0026q=85\u0026s=99c2f0cf963878d1ae169a988a20d9b5"},"navbar":{"links":[{"label":"GitHub","href":"https://github.com/aspfox/aspfox"}],"primary":{"type":"button","label":"Get AspFox — $179","href":"https://aspfox.com"}},"footer":{"socials":{"github":"https://github.com/aspfox"}},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"GitHub","href":"https://github.com/aspfox/aspfox","icon":"github"},{"anchor":"Changelog","href":"https://github.com/aspfox/aspfox-private/blob/main/CHANGELOG.md","icon":"list"},{"anchor":"Support","href":"https://github.com/aspfox/aspfox/issues","icon":"circle-question"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"aspfox","hasAudioNarration":false,"actualSubdomain":"aspfox","customDomains":["docs.aspfox.com"],"gitSource":{"type":"github","owner":"aspfox","repo":"mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6ae9560ff034dd2525b06d6e:success","clientVersion":"0.0.4102","searchFilterCounts":[{"language":"default","tag":"Documentation","count":34},{"language":"default","tag":"Core Concepts","count":8},{"language":"default","tag":"Guides","count":7},{"language":"default","tag":"Configuration","count":5},{"language":"default","tag":"Deployment","count":5},{"language":"default","tag":"Reference","count":5},{"language":"default","tag":"Getting Started","count":4}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"guides/customizing-roles","slug":"/guides/customizing-roles","pageMetadata":{"title":"Customizing Roles and Permissions","description":"Add permissions, create custom roles, and understand when permission changes take effect.","href":"/guides/customizing-roles"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Add permissions, create custom roles, and understand when permission changes take effect.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Heading,{level:`2`,id:`adding-a-new-permission`,children:`Adding a new permission`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Step 1:`}),` Add the permission constant to `,_jsx(_components.code,{children:`Permissions.cs`}),` in Domain:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// src/Acme.Domain/Constants/Permissions.cs`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` static`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Permissions`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // existing permissions...`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` string`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` TenantProjectsRead`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.projects.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` const`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` string`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` TenantProjectsManage`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.projects.manage\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Step 2:`}),` Add the new permissions to the appropriate built-in roles in `,_jsx(_components.code,{children:`GetPermissionsForRole()`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`26`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`26`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// src/Acme.Domain/Services/RolePermissionService.cs`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` static`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` IReadOnlyList`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`GetPermissionsForRole`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`string`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` roleName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` roleName`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` switch`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` RoleNames`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Owner`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // all existing permissions...`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsRead`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsManage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` RoleNames`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Admin`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // existing admin permissions...`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsRead`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsManage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` RoleNames`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`Member`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // existing member permissions...`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsRead`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // Members cannot manage projects by default`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` _`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Array`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`Empty`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`>()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Step 3:`}),` Apply the `,_jsx(_components.code,{children:`[HasPermission]`}),` attribute to controller actions that require the new permission:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`13`,language:`csharp`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`csharp`,children:_jsxs(_components.code,{language:`csharp`,numberOfLines:`13`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`HttpPost`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`HasPermission`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsManage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Task`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`IActionResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`CreateProject`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`([`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`FromBody`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`CreateProjectRequest`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` request`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // ...`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`HttpGet`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`HasPermission`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsRead`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`public`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` async`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Task`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:`IActionResult`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> `}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`GetProjects`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // ...`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Step 4:`}),` Update the frontend `,_jsx(_components.code,{children:`usePermissions()`}),` hook usage and command palette to show/hide items based on the new permission:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`tsx`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`tsx`,children:_jsxs(_components.code,{language:`tsx`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#4EC9B0`},children:`PermissionGate`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` permission`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Permissions`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TenantProjectsManage`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#4EC9B0`},children:`CreateProjectButton`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` />`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#4EC9B0`},children:`PermissionGate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`creating-custom-roles-via-the-api`,children:`Creating custom roles via the API`}),`\n`,_jsxs(_components.p,{children:[`Any tenant member with the `,_jsx(_components.code,{children:`tenant.roles.manage`}),` permission can create custom roles:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`http`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`http`,children:_jsxs(_components.code,{language:`http`,numberOfLines:`12`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`POST`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /api/v1/tenants/current/roles`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Authorization`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` Bearer \u003ctoken>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Developer\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"permissions\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.settings.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.members.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.projects.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.projects.manage\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Updating a custom role:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`13`,language:`http`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`http`,children:_jsxs(_components.code,{language:`http`,numberOfLines:`13`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`PUT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /api/v1/tenants/current/roles/{roleId}`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Authorization`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` Bearer \u003ctoken>`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Senior Developer\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"permissions\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.settings.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.members.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.members.invite\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.projects.read\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"tenant.projects.manage\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Deleting a custom role:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`http`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`http`,children:_jsxs(_components.code,{language:`http`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`DELETE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` /api/v1/tenants/current/roles/{roleId}`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`Authorization`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` Bearer \u003ctoken>`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Deleting a role that has members assigned to it fails with a `,_jsx(_components.code,{children:`CONFLICT`}),` error. Reassign all members to a different role before deleting.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`permission-change-propagation`,children:`Permission change propagation`}),`\n`,_jsxs(Warning,{children:[_jsxs(_components.p,{children:[`Permissions are embedded in the JWT access token. If you change a role’s permissions — either by editing `,_jsx(_components.code,{children:`GetPermissionsForRole()`}),` in code or by updating a custom role via the API — affected users continue using the old permissions until their current access token expires (up to 15 minutes) and they get a new one via refresh.`]}),_jsx(_components.p,{children:`There is no built-in mechanism to immediately revoke access tokens for a specific role change. For permission removals that must take effect immediately, the only option is to force re-authentication for the affected users.`})]}),`\n`,_jsx(Heading,{level:`2`,id:`limitations`,children:`Limitations`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`You cannot use built-in role names (`,_jsx(_components.code,{children:`Owner`}),`, `,_jsx(_components.code,{children:`Admin`}),`, `,_jsx(_components.code,{children:`Member`}),`) for custom roles.`]}),`\n`,_jsx(_components.li,{children:`A role must have at least one permission.`}),`\n`,_jsxs(_components.li,{children:[`Permission strings must exactly match constants in `,_jsx(_components.code,{children:`Permissions.cs`}),`. Invalid strings are rejected with a validation error.`]}),`\n`,_jsxs(_components.li,{children:[`The `,_jsx(_components.code,{children:`Owner`}),` role cannot be deleted or modified. It always has all permissions.`]}),`\n`,_jsx(_components.li,{children:`Each tenant can have at most one Owner.`}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Customizing Roles and Permissions","description":"Add permissions, create custom roles, and understand when permission changes take effect.","href":"/guides/customizing-roles"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Adding a new permission","slug":"adding-a-new-permission","depth":2,"children":[]},{"title":"Creating custom roles via the API","slug":"creating-custom-roles-via-the-api","depth":2,"children":[]},{"title":"Permission change propagation","slug":"permission-change-propagation","depth":2,"children":[]},{"title":"Limitations","slug":"limitations","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"aspfox","siteName":"AspFox","title":"Customizing Roles and Permissions - AspFox","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-05-07T23:16:05.662Z","originalFileLocation":"guides/customizing-roles.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Add permissions, create custom roles, and understand when permission changes take effect.\">\u003cmeta data-mint-head name=\"application-name\" content=\"AspFox\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/x-icon\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/aspfox/favicon.ico\">\u003clink data-mint-head rel=\"icon\" type=\"image/x-icon\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/aspfox/favicon.ico\">\u003clink data-mint-head rel=\"icon\" type=\"image/x-icon\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/aspfox/favicon.ico\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/aspfox/favicon.ico\">\u003cmeta data-mint-head property=\"og:title\" content=\"Customizing Roles and Permissions - AspFox\">\u003cmeta data-mint-head property=\"og:description\" content=\"Add permissions, create custom roles, and understand when permission changes take effect.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"AspFox\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.aspfox.com/guides/customizing-roles\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://aspfox.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Customizing+Roles+and+Permissions\u0026amp;description=Add+permissions%2C+create+custom+roles%2C+and+understand+when+permission+changes+take+effect.\u0026amp;theme=26d6791a97eff5901b6d13ed\u0026amp;signature=a57a5fc046eb418afbdefe51a5a907b2c232d33ee64c47f538c5c31dc40c8cb4\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Customizing Roles and Permissions - AspFox\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Add permissions, create custom roles, and understand when permission changes take effect.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://aspfox.mintlify.site/_mintlify/api/og/v2?division=Guides\u0026amp;title=Customizing+Roles+and+Permissions\u0026amp;description=Add+permissions%2C+create+custom+roles%2C+and+understand+when+permission+changes+take+effect.\u0026amp;theme=26d6791a97eff5901b6d13ed\u0026amp;signature=a57a5fc046eb418afbdefe51a5a907b2c232d33ee64c47f538c5c31dc40c8cb4\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/aspfox/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"AspFox\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#1A56DB\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.aspfox.com/guides/customizing-roles\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/customizing-roles.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.aspfox.com/#organization\",\"name\":\"AspFox\",\"url\":\"https://docs.aspfox.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/aspfox/0JBeTLnQv3MRGYjF/logo/light.svg?fit=max\u0026auto=format\u0026n=0JBeTLnQv3MRGYjF\u0026q=85\u0026s=05c6eccc1c040b89a1507fd933a51757\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.aspfox.com#website\",\"name\":\"AspFox\",\"url\":\"https://docs.aspfox.com\",\"publisher\":{\"@id\":\"https://docs.aspfox.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.aspfox.com/guides/customizing-roles#webpage\",\"url\":\"https://docs.aspfox.com/guides/customizing-roles\",\"name\":\"Customizing Roles and Permissions\",\"description\":\"Add permissions, create custom roles, and understand when permission changes take effect.\",\"dateModified\":\"2026-05-07T23:16:05.662Z\",\"isPartOf\":{\"@id\":\"https://docs.aspfox.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.aspfox.com/guides/customizing-roles#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.aspfox.com/guides/customizing-roles#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Guides\",\"item\":\"https://docs.aspfox.com/guides/local-development\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Customizing Roles and Permissions\",\"item\":\"https://docs.aspfox.com/guides/customizing-roles\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.aspfox.com/guides/customizing-roles#article\",\"headline\":\"Customizing Roles and Permissions\",\"name\":\"Customizing Roles and Permissions\",\"description\":\"Add permissions, create custom roles, and understand when permission changes take effect.\",\"url\":\"https://docs.aspfox.com/guides/customizing-roles\",\"mainEntityOfPage\":{\"@id\":\"https://docs.aspfox.com/guides/customizing-roles#webpage\"},\"dateModified\":\"2026-05-07T23:16:05.662Z\",\"publisher\":{\"@id\":\"https://docs.aspfox.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.aspfox.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"AspFox\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"AspFox\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/guides/customizing-roles.md","siteName":"AspFox","nav":{"global":{"anchors":[{"anchor":"GitHub","href":"https://github.com/aspfox/aspfox","icon":"github"},{"anchor":"Changelog","href":"https://github.com/aspfox/aspfox-private/blob/main/CHANGELOG.md","icon":"list"},{"anchor":"Support","href":"https://github.com/aspfox/aspfox/issues","icon":"circle-question"}]},"anchors":[{"anchor":"Documentation","icon":"book-open","groups":[{"group":"Getting Started","pages":[{"title":"What is AspFox","href":"/getting-started/introduction"},{"title":"Quickstart","href":"/getting-started/quickstart"},{"title":"Prerequisites","href":"/getting-started/prerequisites"},{"title":"Project Structure","href":"/getting-started/project-structure"}]},{"group":"Core Concepts","pages":[{"title":"Architecture","href":"/core-concepts/architecture"},{"title":"Multi-Tenancy","href":"/core-concepts/multi-tenancy"},{"title":"Authentication","href":"/core-concepts/authentication"},{"title":"Roles and Permissions","href":"/core-concepts/rbac-permissions"},{"title":"Stripe Billing","href":"/core-concepts/stripe-billing"},{"title":"Background Jobs","href":"/core-concepts/background-jobs"},{"title":"Notification System","href":"/core-concepts/notifications"},{"title":"Dark Mode and Theming","href":"/core-concepts/dark-mode-theming"}]},{"group":"Configuration","pages":[{"title":"Environment Variables","href":"/configuration/environment-variables"},{"title":"JWT Key Generation","href":"/configuration/jwt-keys"},{"title":"Stripe Setup","href":"/configuration/stripe-setup"},{"title":"Email Setup via Resend","href":"/configuration/email-setup"},{"title":"OAuth Configuration","href":"/configuration/oauth-setup"}]},{"group":"Guides","pages":[{"title":"Local Development","href":"/guides/local-development"},{"title":"Adding a Feature End to End","href":"/guides/adding-a-feature"},{"title":"Adding a Database Entity","href":"/guides/adding-an-entity"},{"title":"Customizing Email Templates","description":"Change copy, update brand colors, add a logo, and create new email templates.","href":"/guides/customizing-email-templates"},{"title":"Customizing Roles and Permissions","href":"/guides/customizing-roles"},{"title":"Working with Stripe","description":"Change prices, add a plan, test billing locally, and recover from missed webhooks.","href":"/guides/working-with-stripe"},{"title":"Command Palette","href":"/guides/command-palette"}]},{"group":"Deployment","pages":[{"title":"Deployment Overview","href":"/deployment/deployment-overview"},{"title":"Deploy to Railway","href":"/deployment/railway"},{"title":"Deploy to Render","href":"/deployment/render"},{"title":"Deploy to VPS with Docker","href":"/deployment/vps-docker"},{"title":"Production Checklist","href":"/deployment/production-checklist"}]},{"group":"Reference","pages":[{"title":"API Reference","href":"/reference/api-endpoints"},{"title":"Notification Types","href":"/reference/notification-types"},{"title":"Stripe Webhook Events","href":"/reference/webhook-events"},{"title":"Background Job Schedules","href":"/reference/job-schedules"},{"title":"Error Codes","href":"/reference/error-codes"}]}]}]},"basePath":"","title":"Customizing Roles and Permissions - AspFox","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":[],"chunks":[]}