diff --git a/.github/workflows/update-custom-role-permissions.yml b/.github/workflows/update-custom-role-permissions.yml new file mode 100644 index 0000000000..29fad41099 --- /dev/null +++ b/.github/workflows/update-custom-role-permissions.yml @@ -0,0 +1,67 @@ +name: 'Update Custom Role Permissions' + +on: + schedule: + - cron: '0 9 * * 1' + workflow_dispatch: + +jobs: + update: + name: 'Check for permission changes and open PR if needed' + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Generate token + id: generate_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.TEMPORAL_CICD_APP_ID }} + private-key: ${{ secrets.TEMPORAL_CICD_PRIVATE_KEY }} + + - name: Checkout docs repo + uses: actions/checkout@v4 + with: + persist-credentials: true + token: ${{ steps.generate_token.outputs.token }} + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Fetch permissions and generate table + env: + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} + run: node bin/generate-custom-role-permissions-table.js --write + + - name: Check for changes + id: diff + run: | + if git diff --quiet docs/cloud/manage-access/_custom_role_permissions_table.mdx; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create PR + if: steps.diff.outputs.changed == 'true' + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git config user.name "temporal-cicd[bot]" + git config user.email "temporal-cicd[bot]@users.noreply.github.com" + + branch_name="update-custom-role-permissions-$(date +%Y%m%d)" + git checkout -b "$branch_name" + git add docs/cloud/manage-access/_custom_role_permissions_table.mdx + git commit -m "Update custom role permissions reference" + git push origin "$branch_name" + + gh pr create \ + --title "Update custom role permissions reference" \ + --body "Automated update from \`temporalio/saas-proto\` \`custom_role_permissions.json\`." \ + --head "$branch_name" \ + --base "main" diff --git a/bin/generate-custom-role-permissions-table.js b/bin/generate-custom-role-permissions-table.js new file mode 100644 index 0000000000..f45aba2baa --- /dev/null +++ b/bin/generate-custom-role-permissions-table.js @@ -0,0 +1,212 @@ +#!/usr/bin/env node + +const https = require("https"); +const fs = require("fs"); +const path = require("path"); + +const GITHUB_API_URL = + "https://api.github.com/repos/temporalio/saas-proto/contents/protogen/custom_role_permissions.json"; + +const CLOUD_OPS_SERVICE = + "temporal.api.cloud.cloudservice.v1.CloudService"; + +const RESOURCE_TYPE_LABELS = { + RESOURCE_TYPE_ACCOUNT: "Account", + RESOURCE_TYPE_NAMESPACE: "Namespace", + RESOURCE_TYPE_NEXUS_ENDPOINT: "Nexus Endpoint", + RESOURCE_TYPE_CONNECTIVITY_RULE: "Connectivity Rule", + RESOURCE_TYPE_PROJECT: "Project", + RESOURCE_TYPE_CUSTOM_ROLE: "Custom Role", +}; + +const CLOUD_OPS_API_LINKS = { + GetAccount: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/account", + UpdateAccount: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/account", + GetUsage: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/usage", + GetAuditLogs: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/audit-logs", + ValidateAccountAuditLogSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/audit-log-sink-validate", + CreateAccountAuditLogSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/audit-log-sinks", + GetAccountAuditLogSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/audit-log-sinks/%7Bname%7D", + GetAccountAuditLogSinks: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/audit-log-sinks", + UpdateAccountAuditLogSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/audit-log-sinks/%7Bspec.name%7D", + DeleteAccountAuditLogSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/DELETE/cloud/audit-log-sinks/%7Bname%7D", + GetAsyncOperation: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/operations/GET/cloud/operations/%7BasyncOperationId%7D", + CreateUser: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/users", + GetUser: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/GET/cloud/users/%7BuserId%7D", + GetUsers: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/GET/cloud/users", + UpdateUser: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/users/%7BuserId%7D", + DeleteUser: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/DELETE/cloud/users/%7BuserId%7D", + ResendUserInvite: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/users", + SetUserNamespaceAccess: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/namespaces/%7Bnamespace%7D/users/%7BuserId%7D/access", + CreateNamespace: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces", + GetNamespaces: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces", + GetNamespaceIDs: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces", + GetNamespace: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces/%7Bnamespace%7D", + UpdateNamespace: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces/%7Bnamespace%7D", + DeleteNamespace: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/DELETE/cloud/namespaces/%7Bnamespace%7D", + RenameCustomSearchAttribute: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces/%7Bnamespace%7D/rename-custom-search-attribute", + UpdateNamespaceTags: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces/%7Bnamespace%7D/update-tags", + GetNamespaceCapacityInfo: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces/%7Bnamespace%7D/capacity-info", + FailoverNamespaceRegion: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/high-availability/POST/cloud/namespaces/%7Bnamespace%7D/failover-region", + AddNamespaceRegion: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/high-availability/POST/cloud/namespaces/%7Bnamespace%7D/add-region", + DeleteNamespaceRegion: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/high-availability/DELETE/cloud/namespaces/%7Bnamespace%7D/regions/%7Bregion%7D", + CreateNamespaceExportSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/POST/cloud/namespaces/%7Bnamespace%7D/export-sinks", + GetNamespaceExportSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/GET/cloud/namespaces/%7Bnamespace%7D/export-sinks/%7Bname%7D", + GetNamespaceExportSinks: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/GET/cloud/namespaces/%7Bnamespace%7D/export-sinks", + UpdateNamespaceExportSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/POST/cloud/namespaces/%7Bnamespace%7D/export-sinks/%7Bspec.name%7D", + DeleteNamespaceExportSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/DELETE/cloud/namespaces/%7Bnamespace%7D/export-sinks/%7Bname%7D", + ValidateNamespaceExportSink: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/POST/cloud/namespaces/%7Bnamespace%7D/export-sink-validate", + SetServiceAccountNamespaceAccess: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/service-accounts/POST/cloud/namespaces/%7Bnamespace%7D/service-accounts/%7BserviceAccountId%7D/access", + SetUserGroupNamespaceAccess: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/namespaces/%7Bnamespace%7D/user-groups/%7BgroupId%7D/access", + GetRegions: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/regions/GET/cloud/regions", + GetRegion: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/regions/GET/cloud/regions/%7Bregion%7D", + GetNexusEndpoints: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/GET/cloud/nexus/endpoints", + GetNexusEndpoint: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/GET/cloud/nexus/endpoints/%7BendpointId%7D", + CreateNexusEndpoint: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/POST/cloud/nexus/endpoints", + UpdateNexusEndpoint: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/POST/cloud/nexus/endpoints/%7BendpointId%7D", + DeleteNexusEndpoint: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/DELETE/cloud/nexus/endpoints/%7BendpointId%7D", + GetUserGroups: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/GET/cloud/user-groups", + GetUserGroup: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/GET/cloud/user-groups/%7BgroupId%7D", + CreateUserGroup: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups", + UpdateUserGroup: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups/%7BgroupId%7D", + DeleteUserGroup: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/DELETE/cloud/user-groups/%7BgroupId%7D", + AddUserGroupMember: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups/%7BgroupId%7D/members", + RemoveUserGroupMember: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups/%7BgroupId%7D/remove-member", + GetUserGroupMembers: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/GET/cloud/user-groups/%7BgroupId%7D/members", + GetConnectivityRules: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/GET/cloud/connectivity-rules", + GetConnectivityRule: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/GET/cloud/connectivity-rules/%7BconnectivityRuleId%7D", + CreateConnectivityRule: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/POST/cloud/connectivity-rules", + DeleteConnectivityRule: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/DELETE/cloud/connectivity-rules/%7BconnectivityRuleId%7D", + CreateBillingReport: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/billing-reports", + GetBillingReport: "https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/billing-reports/%7BbillingReportId%7D", +}; + +function fetchJSON(url) { + return new Promise((resolve, reject) => { + const options = { + headers: { + "User-Agent": "temporal-docs-generator", + Accept: "application/vnd.github.v3+json", + }, + }; + + if (process.env.GITHUB_TOKEN) { + options.headers.Authorization = `token ${process.env.GITHUB_TOKEN}`; + } + + https.get(url, options, (res) => { + let data = ""; + res.on("data", (chunk) => (data += chunk)); + res.on("end", () => { + if (res.statusCode !== 200) { + reject(new Error(`HTTP ${res.statusCode}: ${data.substring(0, 200)}`)); + return; + } + try { + const json = JSON.parse(data); + const content = Buffer.from(json.content, "base64").toString("utf-8"); + resolve(JSON.parse(content)); + } catch (e) { + reject(e); + } + }); + res.on("error", reject); + }); + }); +} + +function buildTable(permissions) { + const cloudOpsPerms = permissions.filter( + (p) => p.service === CLOUD_OPS_SERVICE && !p.is_internal_permission + ); + + const byResource = {}; + for (const perm of cloudOpsPerms) { + for (const rt of perm.resource_types) { + const label = RESOURCE_TYPE_LABELS[rt] || rt; + if (!byResource[label]) byResource[label] = []; + byResource[label].push(perm); + } + } + + // Deduplicate within each resource group (same permission string) + for (const label of Object.keys(byResource)) { + const seen = new Set(); + byResource[label] = byResource[label].filter((p) => { + const key = p.permission; + if (seen.has(key)) return false; + seen.add(key); + return true; + }); + byResource[label].sort((a, b) => a.permission.localeCompare(b.permission)); + } + + const resourceOrder = [ + "Account", + "Namespace", + "Project", + "Nexus Endpoint", + "Connectivity Rule", + "Custom Role", + ]; + + let md = "{/* Auto-generated by bin/generate-custom-role-permissions-table.js — do not edit manually */}\n\n"; + + for (const resourceLabel of resourceOrder) { + const perms = byResource[resourceLabel]; + if (!perms || perms.length === 0) continue; + + md += `### ${resourceLabel} permissions\n\n`; + md += `| Permission | Cloud Ops API | Resource type |\n`; + md += `| ---------- | ------------- | ------------- |\n`; + + for (const perm of perms) { + const apiLink = CLOUD_OPS_API_LINKS[perm.method]; + const apiCol = apiLink + ? `[${perm.method}](${apiLink})` + : perm.method; + const resourceTypes = perm.resource_types + .map((rt) => RESOURCE_TYPE_LABELS[rt] || rt) + .join(", "); + md += `| \`${perm.permission}\` | ${apiCol} | ${resourceTypes} |\n`; + } + md += "\n"; + } + + return md; +} + +async function main() { + let permissionsData; + + const localPath = process.argv[2]; + if (localPath) { + const raw = fs.readFileSync(localPath, "utf-8"); + permissionsData = JSON.parse(raw); + } else { + console.error("Fetching permissions from GitHub..."); + permissionsData = await fetchJSON(GITHUB_API_URL); + } + + const table = buildTable(permissionsData.permissions); + + if (process.argv.includes("--write")) { + const outPath = path.join( + __dirname, + "..", + "docs", + "cloud", + "manage-access", + "_custom_role_permissions_table.mdx" + ); + fs.writeFileSync(outPath, table); + console.error(`Wrote ${outPath}`); + } else { + process.stdout.write(table); + } +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/docs/cloud/manage-access/_custom_role_permissions_table.mdx b/docs/cloud/manage-access/_custom_role_permissions_table.mdx new file mode 100644 index 0000000000..3cc0db0afa --- /dev/null +++ b/docs/cloud/manage-access/_custom_role_permissions_table.mdx @@ -0,0 +1,106 @@ +{/* Auto-generated by bin/generate-custom-role-permissions-table.js — do not edit manually */} + +### Account permissions + +| Permission | Cloud Ops API | Resource type | +| ---------- | ------------- | ------------- | +| `cloud.account.get` | [GetAccount](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/account) | Account | +| `cloud.account.update` | [UpdateAccount](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/account) | Account | +| `cloud.asyncoperation.get` | [GetAsyncOperation](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/operations/GET/cloud/operations/%7BasyncOperationId%7D) | Account | +| `cloud.auditlog.createSink` | [CreateAccountAuditLogSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/audit-log-sinks) | Account | +| `cloud.auditlog.deleteSink` | [DeleteAccountAuditLogSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/DELETE/cloud/audit-log-sinks/%7Bname%7D) | Account | +| `cloud.auditlog.getSink` | [GetAccountAuditLogSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/audit-log-sinks/%7Bname%7D) | Account | +| `cloud.auditlog.list` | [GetAuditLogs](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/audit-logs) | Account | +| `cloud.auditlog.listSinks` | [GetAccountAuditLogSinks](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/audit-log-sinks) | Account | +| `cloud.auditlog.updateSink` | [UpdateAccountAuditLogSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/audit-log-sinks/%7Bspec.name%7D) | Account | +| `cloud.auditlog.validateSink` | [ValidateAccountAuditLogSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/audit-log-sink-validate) | Account | +| `cloud.billingreport.create` | [CreateBillingReport](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/POST/cloud/billing-reports) | Account | +| `cloud.billingreport.get` | [GetBillingReport](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/billing-reports/%7BbillingReportId%7D) | Account | +| `cloud.connectivityrule.list` | [GetConnectivityRules](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/GET/cloud/connectivity-rules) | Account, Project | +| `cloud.migration.abort` | AbortMigration | Account | +| `cloud.migration.confirm` | ConfirmMigration | Account | +| `cloud.migration.get` | GetMigration | Account | +| `cloud.migration.handover` | HandoverNamespace | Account | +| `cloud.migration.list` | GetMigrations | Account | +| `cloud.migration.start` | StartMigration | Account | +| `cloud.namespace.list` | [GetNamespaces](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces) | Account, Project | +| `cloud.nexusendpoint.list` | [GetNexusEndpoints](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/GET/cloud/nexus/endpoints) | Account, Project | +| `cloud.project.create` | CreateProject | Account | +| `cloud.project.list` | GetProjects | Account | +| `cloud.region.get` | [GetRegion](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/regions/GET/cloud/regions/%7Bregion%7D) | Account | +| `cloud.region.list` | [GetRegions](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/regions/GET/cloud/regions) | Account | +| `cloud.usage.get` | [GetUsage](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/account/GET/cloud/usage) | Account | +| `cloud.user.create` | [CreateUser](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/users) | Account | +| `cloud.user.delete` | [DeleteUser](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/DELETE/cloud/users/%7BuserId%7D) | Account | +| `cloud.user.get` | [GetUser](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/GET/cloud/users/%7BuserId%7D) | Account | +| `cloud.user.list` | [GetUsers](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/GET/cloud/users) | Account | +| `cloud.user.update` | [UpdateUser](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/users/%7BuserId%7D) | Account | +| `cloud.usergroup.addMember` | [AddUserGroupMember](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups/%7BgroupId%7D/members) | Account | +| `cloud.usergroup.create` | [CreateUserGroup](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups) | Account | +| `cloud.usergroup.delete` | [DeleteUserGroup](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/DELETE/cloud/user-groups/%7BgroupId%7D) | Account | +| `cloud.usergroup.get` | [GetUserGroup](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/GET/cloud/user-groups/%7BgroupId%7D) | Account | +| `cloud.usergroup.getMembers` | [GetUserGroupMembers](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/GET/cloud/user-groups/%7BgroupId%7D/members) | Account | +| `cloud.usergroup.list` | [GetUserGroups](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/GET/cloud/user-groups) | Account | +| `cloud.usergroup.removeMember` | [RemoveUserGroupMember](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups/%7BgroupId%7D/remove-member) | Account | +| `cloud.usergroup.update` | [UpdateUserGroup](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/user-groups/%7BgroupId%7D) | Account | + +### Namespace permissions + +| Permission | Cloud Ops API | Resource type | +| ---------- | ------------- | ------------- | +| `cloud.namespace.addRegion` | [AddNamespaceRegion](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/high-availability/POST/cloud/namespaces/%7Bnamespace%7D/add-region) | Namespace | +| `cloud.namespace.capacityinfo.get` | [GetNamespaceCapacityInfo](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces/%7Bnamespace%7D/capacity-info) | Namespace | +| `cloud.namespace.delete` | [DeleteNamespace](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/DELETE/cloud/namespaces/%7Bnamespace%7D) | Namespace | +| `cloud.namespace.deleteRegion` | [DeleteNamespaceRegion](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/high-availability/DELETE/cloud/namespaces/%7Bnamespace%7D/regions/%7Bregion%7D) | Namespace | +| `cloud.namespace.exportsink.create` | [CreateNamespaceExportSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/POST/cloud/namespaces/%7Bnamespace%7D/export-sinks) | Namespace | +| `cloud.namespace.exportsink.delete` | [DeleteNamespaceExportSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/DELETE/cloud/namespaces/%7Bnamespace%7D/export-sinks/%7Bname%7D) | Namespace | +| `cloud.namespace.exportsink.get` | [GetNamespaceExportSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/GET/cloud/namespaces/%7Bnamespace%7D/export-sinks/%7Bname%7D) | Namespace | +| `cloud.namespace.exportsink.list` | [GetNamespaceExportSinks](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/GET/cloud/namespaces/%7Bnamespace%7D/export-sinks) | Namespace | +| `cloud.namespace.exportsink.update` | [UpdateNamespaceExportSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/POST/cloud/namespaces/%7Bnamespace%7D/export-sinks/%7Bspec.name%7D) | Namespace | +| `cloud.namespace.exportsink.validate` | [ValidateNamespaceExportSink](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/export/POST/cloud/namespaces/%7Bnamespace%7D/export-sink-validate) | Namespace | +| `cloud.namespace.failoverRegion` | [FailoverNamespaceRegion](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/high-availability/POST/cloud/namespaces/%7Bnamespace%7D/failover-region) | Namespace | +| `cloud.namespace.get` | [GetNamespace](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces/%7Bnamespace%7D) | Namespace | +| `cloud.namespace.getServiceAccountNamespaceAssignments` | GetServiceAccountNamespaceAssignments | Namespace | +| `cloud.namespace.getUserGroupNamespaceAssignments` | GetUserGroupNamespaceAssignments | Namespace | +| `cloud.namespace.getUserNamespaceAssignments` | GetUserNamespaceAssignments | Namespace | +| `cloud.namespace.renameCustomSearchAttribute` | [RenameCustomSearchAttribute](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces/%7Bnamespace%7D/rename-custom-search-attribute) | Namespace | +| `cloud.namespace.setUserAccess` | [SetUserNamespaceAccess](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/users/POST/cloud/namespaces/%7Bnamespace%7D/users/%7BuserId%7D/access) | Namespace | +| `cloud.namespace.setUserGroupAccess` | [SetUserGroupNamespaceAccess](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/groups/POST/cloud/namespaces/%7Bnamespace%7D/user-groups/%7BgroupId%7D/access) | Namespace | +| `cloud.namespace.update` | [UpdateNamespace](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces/%7Bnamespace%7D) | Namespace | +| `cloud.namespace.updateTags` | [UpdateNamespaceTags](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces/%7Bnamespace%7D/update-tags) | Namespace | + +### Project permissions + +| Permission | Cloud Ops API | Resource type | +| ---------- | ------------- | ------------- | +| `cloud.connectivityrule.create` | [CreateConnectivityRule](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/POST/cloud/connectivity-rules) | Project | +| `cloud.connectivityrule.list` | [GetConnectivityRules](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/GET/cloud/connectivity-rules) | Account, Project | +| `cloud.namespace.create` | [CreateNamespace](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/POST/cloud/namespaces) | Project | +| `cloud.namespace.list` | [GetNamespaces](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/namespaces/GET/cloud/namespaces) | Account, Project | +| `cloud.nexusendpoint.create` | [CreateNexusEndpoint](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/POST/cloud/nexus/endpoints) | Project | +| `cloud.nexusendpoint.list` | [GetNexusEndpoints](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/GET/cloud/nexus/endpoints) | Account, Project | +| `cloud.project.delete` | DeleteProject | Project | +| `cloud.project.get` | GetProject | Project | +| `cloud.project.getServiceAccountProjectAssignments` | GetServiceAccountProjectAssignments | Project | +| `cloud.project.getUserGroupProjectAssignments` | GetUserGroupProjectAssignments | Project | +| `cloud.project.getUserProjectAssignments` | GetUserProjectAssignments | Project | +| `cloud.project.setServiceAccountAccess` | SetServiceAccountProjectAccess | Project | +| `cloud.project.setUserAccess` | SetUserProjectAccess | Project | +| `cloud.project.setUserGroupAccess` | SetUserGroupProjectAccess | Project | +| `cloud.project.update` | UpdateProject | Project | + +### Nexus Endpoint permissions + +| Permission | Cloud Ops API | Resource type | +| ---------- | ------------- | ------------- | +| `cloud.nexusendpoint.delete` | [DeleteNexusEndpoint](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/DELETE/cloud/nexus/endpoints/%7BendpointId%7D) | Nexus Endpoint | +| `cloud.nexusendpoint.get` | [GetNexusEndpoint](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/GET/cloud/nexus/endpoints/%7BendpointId%7D) | Nexus Endpoint | +| `cloud.nexusendpoint.update` | [UpdateNexusEndpoint](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/nexus/POST/cloud/nexus/endpoints/%7BendpointId%7D) | Nexus Endpoint | + +### Connectivity Rule permissions + +| Permission | Cloud Ops API | Resource type | +| ---------- | ------------- | ------------- | +| `cloud.connectivityrule.delete` | [DeleteConnectivityRule](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/DELETE/cloud/connectivity-rules/%7BconnectivityRuleId%7D) | Connectivity Rule | +| `cloud.connectivityrule.get` | [GetConnectivityRule](https://saas-api.tmprl.cloud/docs/httpapi.html#tag/connectivity-rules/GET/cloud/connectivity-rules/%7BconnectivityRuleId%7D) | Connectivity Rule | + diff --git a/docs/cloud/manage-access/permissions-reference.mdx b/docs/cloud/manage-access/permissions-reference.mdx index f3b8bda235..64add2ffe4 100644 --- a/docs/cloud/manage-access/permissions-reference.mdx +++ b/docs/cloud/manage-access/permissions-reference.mdx @@ -268,6 +268,17 @@ permissions. These permissions are configured per Namespace per user. | Initiate Namespace failover | | | ✔ | | Convert single-region Namespace to multi-region | | | ✔ | */} +## Custom Role permissions reference {#custom-role-permissions} + +The following tables list the permission action strings available when defining [Custom Roles](/cloud/manage-access/custom-roles). +Use these strings in the `actions` field of a Custom Role permission grant. + +Not all Cloud Ops API operations can be assigned to a Custom Role. For details on which operations are excluded and why, see [Available permissions](/cloud/manage-access/custom-roles#available-permissions). + +import CustomRolePermissionsTable from './_custom_role_permissions_table.mdx'; + + + ## Additional authorization behaviors Some APIs are granted to all account-level roles but enforce additional authorization rules at runtime. The action group