Self-hosted platform for standing up and running software factories on AWS: complete DevSecOps environments with secure delivery pipelines, supply-chain controls, compliance evidence and multi-tenant governance — in minutes, not months.
This file is maintained BY HAND. There is no regenerate flag, and that is the point.
permissions.sysadmin becoming a permission, all(...) becoming any(...), a dropped aal2 / step-up(...) / system-org, a widened internal(...) list, or an added +svc.frontend/test/route-permissions.test.tsx, and relaxing a gate here can leave the UI as the only thing still enforcing the old one.Every route’s authorization is also recorded in frontend/src/generated/route-table/<service>.json, which is generated from the routes themselves. That makes permission weakening invisible: relax a gate and the generated table changes to match, so the diff looks like whatever the change intended. Nothing in review says “this route got easier to reach”.
This file is the human-stated counterpart, and it exists for reviewers as much as for authors. If you are looking for what a permission means rather than which route demands it, see Permissions.
UPDATE_ROUTE_TABLES=1.frontend/test/permission-contract.test.ts renders each generated route into one canonical authorization string, using the tokens in Notation below.A further assertion checks that every notation token appearing in a row is explained above the table — a row whose rendering uses an unexplained token is unreviewable.
UPDATE_ROUTE_TABLES=1 on its route-coverage test).routeRequires string from the failure — it is already in canonical form.KNOWN_UI_GATE_MISMATCHES in frontend/test/route-permissions.test.tsx; if the control still checks the old gate, the dashboard is now stricter than the API.A diff that touches this file is a permission change. Review it as a security change: for each altered row, ask what a caller can now reach that they could not before.
sysadmin→ a permission,all(...)→any(...), a droppedaal2/step-up(...)/system-org, a widenedinternal(...)caller list, or an added+svcare all weakenings, whatever the commit message says.
Removing a row means the route is gone. Adding one means a newly gated route — check it is gated at the right level, not merely gated.
The UI side of the same question is pinned separately, in frontend/test/route-permissions.test.tsx: every write route here is either mapped to a dashboard control whose gate that suite proves by rendering it with and without the permission, or categorized there with the caller that drives it. Its KNOWN_UI_GATE_MISMATCHES list names the routes whose control checks a different gate from the row below — read it alongside this file when a row changes, because relaxing a gate here can leave the UI as the only thing still enforcing the old one.
These explain why particular families of rows look the way they do.
Every /plugins/ecosystem/* row carries system-org + ... + aal2: only the system org decides anything in the plugin ecosystem, and only from an MFA-grade session (see Plugin Publishing). A row losing system-org or aal2, or gaining a tenant permission, is a governance weakening.
The request-decision rows (/requests/:id/approve, /second-approve, /reject) show no step-up(...) because the step-up is demanded per request KIND inside the chain — yank, transfer, claim, profile change, Verified application, moderation actions. Two-person approval and separation of duties are enforced by the service and pinned by api/plugin/test/ecosystem-moderation.test.ts.
The tenant /plugins/publisher* and /plugins/publish-requests* rows only submit requests or narrow the caller’s own reach, which api/plugin/test/ecosystem-governance.test.ts enforces.
The install rows (/plugins/catalog, /plugins/listings/*/install-state, /plugins/installs*, /plugins/install-policy, /plugins/shadowing) act only on the caller’s own org.
plugins:install may install, upgrade and uninstall — but an install of an approval-required tier made without plugin_installs:manage only becomes a pending request, and moving such an install across a major or breaking version needs plugin_installs:manage too. Both are decided inside the service, so they don’t show in the rows.
Loosening PUT /plugins/install-policy below plugin_installs:manage + step-up(any) lets any member widen what the org’s pipelines may run, which is a weakening.
The rows under /plugins/security-notifications* decide where the org’s blocked-build (N30) and rescan (N31) notices go — including an outbound webhook and an external address. Loosening the PUT or the test send below org:settings would let any member redirect security notices or aim the webhook, which is a weakening.
The anonymous POST /public/plugin-security-notifications/confirm carries no caller identity — its single-use emailed token is the authority — so it has no row here. Its waiver is pinned in api/plugin/test/route-coverage.test.ts.
The review writes (/plugins/listings/*/reviews, /plugins/reviews/*) are gated on plugins:read on purpose: every member who can browse the catalog may rate and review (see Permissions). The aal1 is what makes them a PERSON’s action — requireAssurance({ minAssurance: 1 }) refuses service accounts and exchanged access keys with HUMAN_SESSION_REQUIRED. Dropping the aal1 lets automation write, vote on and report reviews, which is a weakening.
Who may act on WHICH review is decided in the service and pinned by api/plugin/test/ecosystem-reviews.test.ts: the author edits and deletes; nobody from the publisher’s own org reviews or votes; only the listing publisher’s own managers reply.
The /plugins/ecosystem/reviews* moderation rows follow the governance rule above. Like the reserved names, they carry no step-up — hiding or restoring user content needs none.
One write is gated on a read permission on purpose: message POST /messages/support.
Contacting support is self-service — every member who can open the Messages page (messages:read) must be able to file a request, including a read-only one who holds no messages:write. The route is safe at that floor because it takes no recipient: the server forces every message to the support desk on the reserved support channel and discards any recipient the body carries. POST /messages stays on messages:write.
| Token | Meaning |
|---|---|
any(a\|b) |
Caller holds at least one of these permissions |
all(a\|b) |
Caller holds every one of these permissions |
+svc |
A service principal also passes, without holding the permission |
sysadmin |
Platform administrator only (isSuperAdmin) |
system-org |
The caller’s active org must be the system org (requireSystemOrg, the plugin-ecosystem governance boundary). Dropping it from a route gated on plugins:moderate / publishers:verify is a weakening — and fails api-core’s findSystemOrgGuardViolations too |
service-principal |
Any signed service token |
internal(a,b) |
Peer services only, and only these callers — refuses every user token |
feature(f) |
Paid entitlement f required |
scope(s) |
Machine-credential scope s required |
aalN |
Authenticator assurance level ≥ N |
aalN(except c) |
…of every caller except the named carve-out c. Today the only one is bootstrap-setup: a fresh install’s single administrator, who has no second factor to be MFA-grade with yet, on the setup calls init-platform.sh makes. Step-up still applies, the reach stays limited to the bootstrap allowlist, and a live re-read bounds it to BOOTSTRAP_SETUP_WINDOW_MS (default 24 h) after the install and to an exception that has not yet closed |
step-up(m,…) |
Recent re-authentication with one of these methods |
org-admin-assurance |
The org’s “administrative actions require MFA” policy applies |
authenticated |
Signed in, nothing more |
| Service | Method | Path | Required authorization |
|---|---|---|---|
| ask | POST | /ask |
any(pipelines:read|plugins:read|templates:read) + feature(ai_generation) |
| ask | POST | /ask/agent/stream |
any(pipelines:read|plugins:read|templates:read) + feature(ai_generation) |
| ask | GET | /ask/availability |
any(pipelines:read|plugins:read|templates:read) + feature(ai_generation) |
| ask | POST | /ask/feedback |
any(pipelines:read|plugins:read|templates:read) |
| ask | GET | /ask/providers |
any(pipelines:read|plugins:read|templates:read) + feature(ai_generation) |
| ask | POST | /ask/stream |
any(pipelines:read|plugins:read|templates:read) + feature(ai_generation) |
| billing | GET | /billing/admin/discounts |
sysadmin |
| billing | POST | /billing/admin/discounts |
sysadmin |
| billing | DELETE | /billing/admin/discounts/:id |
sysadmin |
| billing | GET | /billing/admin/discounts/:id |
sysadmin |
| billing | PUT | /billing/admin/discounts/:id |
sysadmin |
| billing | POST | /billing/admin/discounts/:id/apply |
sysadmin |
| billing | POST | /billing/admin/discounts/:id/preview |
sysadmin |
| billing | POST | /billing/admin/discounts/:id/token |
sysadmin |
| billing | GET | /billing/admin/events |
sysadmin |
| billing | GET | /billing/admin/promotions |
sysadmin |
| billing | POST | /billing/admin/promotions |
sysadmin |
| billing | DELETE | /billing/admin/promotions/:id |
sysadmin |
| billing | GET | /billing/admin/promotions/:id |
sysadmin |
| billing | PUT | /billing/admin/promotions/:id |
sysadmin |
| billing | POST | /billing/admin/promotions/:id/activate |
sysadmin |
| billing | POST | /billing/admin/promotions/:id/grant |
sysadmin |
| billing | POST | /billing/admin/promotions/:id/preview |
sysadmin |
| billing | GET | /billing/admin/promotions/:id/spend |
sysadmin |
| billing | GET | /billing/admin/subscriptions |
sysadmin |
| billing | PUT | /billing/admin/subscriptions/:id |
sysadmin + step-up(any) |
| billing | GET | /billing/admin/summary |
sysadmin |
| billing | GET | /billing/bundles |
any(billing:read) |
| billing | GET | /billing/events |
any(billing:read) |
| billing | GET | /billing/invoices |
any(billing:read) |
| billing | POST | /billing/marketplace/claim |
any(billing:manage) + org-admin-assurance |
| billing | GET | /billing/marketplace/entitlements |
any(billing:read) |
| billing | POST | /billing/portal |
any(billing:manage) + org-admin-assurance |
| billing | GET | /billing/subscriptions |
any(billing:read) |
| billing | POST | /billing/subscriptions |
any(billing:manage) + org-admin-assurance |
| billing | PUT | /billing/subscriptions/:id |
any(billing:manage) + org-admin-assurance |
| billing | POST | /billing/subscriptions/:id/addons |
any(billing:manage) + org-admin-assurance |
| billing | DELETE | /billing/subscriptions/:id/addons/:bundleId |
any(billing:manage) + org-admin-assurance |
| billing | POST | /billing/subscriptions/:id/addons/preview |
any(billing:read) |
| billing | POST | /billing/subscriptions/:id/cancel |
any(billing:manage) + step-up(any) + org-admin-assurance |
| billing | POST | /billing/subscriptions/:id/discounts |
any(billing:manage) + org-admin-assurance |
| billing | DELETE | /billing/subscriptions/:id/discounts/:discountId |
any(billing:manage) + org-admin-assurance |
| billing | POST | /billing/subscriptions/:id/discounts/preview |
any(billing:read) |
| billing | POST | /billing/subscriptions/:id/reactivate |
any(billing:manage) + org-admin-assurance |
| billing | DELETE | /billing/subscriptions/by-org/:orgId |
sysadmin |
| billing | GET | /billing/subscriptions/by-org/:orgId/billable |
sysadmin |
| billing | POST | /billing/subscriptions/checkout |
any(billing:manage) + org-admin-assurance |
| billing | GET | /billing/summary |
any(billing:read) |
| billing | GET | /billing/summary/allocation |
any(billing:read) |
| billing | GET | /billing/summary/usage-by-team |
any(billing:read) + feature(team_usage_analytics) |
| billing | GET | /billing/usage |
any(billing:read) |
| compliance | GET | /compliance/audit |
any(compliance:read) |
| compliance | GET | /compliance/entitlements/:orgId |
service-principal + internal(billing) |
| compliance | PUT | /compliance/entitlements/:orgId |
service-principal + internal(billing) |
| compliance | POST | /compliance/events/entity |
service-principal + internal(pipeline,plugin) |
| compliance | GET | /compliance/exemptions |
any(compliance:read) |
| compliance | POST | /compliance/exemptions |
any(compliance:read) |
| compliance | DELETE | /compliance/exemptions/:id |
any(compliance:write) |
| compliance | PUT | /compliance/exemptions/:id/review |
any(compliance:write) |
| compliance | POST | /compliance/exemptions/bulk |
any(compliance:read) |
| compliance | GET | /compliance/notification-preferences |
any(compliance:read) |
| compliance | PUT | /compliance/notification-preferences |
any(compliance:write) |
| compliance | GET | /compliance/posture |
service-principal + internal(reporting) |
| compliance | GET | /compliance/policies |
any(compliance:read) |
| compliance | POST | /compliance/policies |
any(compliance:write) |
| compliance | DELETE | /compliance/policies/:id |
any(compliance:write) |
| compliance | GET | /compliance/policies/:id |
any(compliance:read) |
| compliance | PUT | /compliance/policies/:id |
any(compliance:write) |
| compliance | POST | /compliance/policies/:id/purge |
any(compliance:write) + step-up(any) |
| compliance | POST | /compliance/policies/:id/restore |
any(compliance:write) + step-up(any) |
| compliance | GET | /compliance/policies/deleted |
any(compliance:read) |
| compliance | GET | /compliance/published-rules |
any(compliance:read) |
| compliance | GET | /compliance/rules |
any(compliance:read) |
| compliance | POST | /compliance/rules |
any(compliance:write) |
| compliance | DELETE | /compliance/rules/:id |
any(compliance:write) |
| compliance | GET | /compliance/rules/:id |
any(compliance:read) |
| compliance | PUT | /compliance/rules/:id |
any(compliance:write) |
| compliance | GET | /compliance/rules/:id/history |
any(compliance:read) |
| compliance | POST | /compliance/rules/:id/purge |
any(compliance:write) + step-up(any) |
| compliance | POST | /compliance/rules/:id/restore |
any(compliance:write) + step-up(any) |
| compliance | GET | /compliance/rules/deleted |
any(compliance:read) |
| compliance | GET | /compliance/scan-schedules |
any(compliance:read) |
| compliance | POST | /compliance/scan-schedules |
any(compliance:write) |
| compliance | DELETE | /compliance/scan-schedules/:id |
any(compliance:write) |
| compliance | PUT | /compliance/scan-schedules/:id |
any(compliance:write) |
| compliance | PATCH | /compliance/scan-schedules/:id/active |
any(compliance:write) |
| compliance | GET | /compliance/scans |
any(compliance:read) |
| compliance | POST | /compliance/scans |
any(compliance:write) |
| compliance | GET | /compliance/scans/:id |
any(compliance:read) |
| compliance | POST | /compliance/scans/:id/cancel |
any(compliance:write) |
| compliance | GET | /compliance/subscriptions |
any(compliance:read) |
| compliance | POST | /compliance/subscriptions |
any(compliance:read) |
| compliance | DELETE | /compliance/subscriptions/:ruleId |
any(compliance:write) |
| compliance | PATCH | /compliance/subscriptions/:ruleId |
any(compliance:read) |
| compliance | DELETE | /compliance/subscriptions/:ruleId/pin |
any(compliance:write) |
| compliance | POST | /compliance/subscriptions/:ruleId/pin |
any(compliance:write) |
| compliance | POST | /compliance/subscriptions/auto-subscribe |
service-principal + internal(platform) |
| compliance | POST | /compliance/subscriptions/bulk |
any(compliance:read) |
| compliance | POST | /compliance/subscriptions/clone |
any(compliance:write) |
| compliance | GET | /compliance/subscriptions/enforced |
any(compliance:read) |
| compliance | POST | /compliance/subscriptions/preview |
any(compliance:read) |
| compliance | POST | /compliance/subscriptions/preview/impact |
any(compliance:read) |
| compliance | GET | /compliance/templates |
any(compliance:read) |
| compliance | POST | /compliance/templates/apply |
any(compliance:write) |
| compliance | POST | /compliance/validate/pipeline |
any(compliance:read)+svc |
| compliance | POST | /compliance/validate/pipeline/dry-run |
any(compliance:read)+svc |
| compliance | POST | /compliance/validate/plugin |
any(compliance:read)+svc |
| compliance | POST | /compliance/validate/plugin/dry-run |
any(compliance:read)+svc |
| image-registry | POST | /api/admin/gc |
any(registry:write) |
| image-registry | GET | /api/admin/storage/:prefix |
any(registry:read) |
| image-registry | GET | /api/images |
any(registry:read) |
| image-registry | DELETE | /api/images/:name |
any(registry:write) |
| image-registry | GET | /api/images/:name/blobs/:digest |
any(registry:read) |
| image-registry | DELETE | /api/images/:name/manifests/:reference |
any(registry:write) |
| image-registry | GET | /api/images/:name/manifests/:reference |
any(registry:read) |
| image-registry | GET | /api/images/:name/tags |
any(registry:read) |
| image-registry | POST | /api/images/copy |
all(registry:read|registry:write) |
| image-registry | POST | /internal/plugin-signatures |
service-principal + internal(plugin) |
| image-registry | POST | /internal/plugin-publications |
service-principal + internal(plugin) |
| image-registry | POST | /internal/plugin-publications/resign |
service-principal + internal(plugin) |
| image-registry | DELETE | /internal/quarantine/:submissionId |
service-principal + internal(plugin) |
| image-registry | POST | /internal/quarantine/:submissionId/credential |
service-principal + internal(plugin) |
| image-registry | POST | /internal/plugin-publications/yank |
service-principal + internal(plugin) |
| image-registry | POST | /internal/plugin-publications/retag |
service-principal + internal(plugin) |
| image-registry | POST | /internal/plugin-publications/gc |
service-principal + internal(plugin) |
| image-registry | GET | /internal/plugin-publications/verify |
service-principal + internal(plugin) |
| image-registry | POST | /internal/plugin-publications/verify-cache/invalidate |
service-principal + internal(plugin) |
| message | GET | /messages |
any(messages:read) |
| message | POST | /messages |
any(messages:write) |
| message | DELETE | /messages/:id |
any(messages:write) |
| message | GET | /messages/:id |
any(messages:read) |
| message | PATCH | /messages/:id |
any(messages:write) |
| message | GET | /messages/:id/attachments |
any(messages:read) |
| message | POST | /messages/:id/purge |
any(messages:write) + step-up(any) |
| message | PUT | /messages/:id/read |
any(messages:read) |
| message | POST | /messages/:id/reply |
any(messages:write) |
| message | POST | /messages/:id/restore |
any(messages:write) + step-up(any) |
| message | GET | /messages/:id/thread |
any(messages:read) |
| message | PUT | /messages/:id/thread/read |
any(messages:read) |
| message | GET | /messages/announcements |
any(messages:read) |
| message | POST | /messages/attachments |
any(messages:write) |
| message | GET | /messages/attachments/:id |
any(messages:read) |
| message | GET | /messages/conversations |
any(messages:read) |
| message | GET | /messages/deleted |
any(messages:read) |
| message | POST | /messages/internal/notify |
service-principal + internal(billing,compliance,platform) |
| message | DELETE | /messages/internal/org/:orgId/attachments |
service-principal + internal(platform) |
| message | POST | /messages/notifications/ticket |
any(messages:read) |
| message | GET | /messages/recipients/orgs |
any(messages:write) |
| message | POST | /messages/support |
any(messages:read) |
| message | GET | /messages/unread/count |
any(messages:read) |
| pipeline | GET | /pipeline-templates |
any(templates:read) |
| pipeline | POST | /pipeline-templates |
any(templates:write) |
| pipeline | DELETE | /pipeline-templates/:id |
any(templates:write) |
| pipeline | GET | /pipeline-templates/:id |
any(templates:read) |
| pipeline | PUT | /pipeline-templates/:id |
any(templates:write) |
| pipeline | POST | /pipeline-templates/:id/instantiate |
any(templates:read) |
| pipeline | POST | /pipeline-templates/:id/purge |
any(templates:write) + step-up(any) |
| pipeline | POST | /pipeline-templates/:id/restore |
any(templates:write) + step-up(any) |
| pipeline | GET | /pipeline-templates/deleted |
any(templates:read) |
| pipeline | GET | /pipelines |
any(pipelines:read) |
| pipeline | POST | /pipelines |
any(pipelines:write) |
| pipeline | DELETE | /pipelines/:id |
any(pipelines:write) |
| pipeline | GET | /pipelines/:id |
any(pipelines:read) |
| pipeline | PUT | /pipelines/:id |
any(pipelines:write) |
| pipeline | POST | /pipelines/:id/purge |
any(pipelines:write) + step-up(any) |
| pipeline | POST | /pipelines/:id/restore |
any(pipelines:write) + step-up(any) |
| pipeline | GET | /pipelines/:id/scorecard |
any(pipelines:read) + feature(advanced_reporting) |
| pipeline | POST | /pipelines/:pipelineId/executions |
any(pipelines:write) |
| pipeline | POST | /pipelines/:pipelineId/executions/:executionId/stop |
any(pipelines:write) |
| pipeline | POST | /pipelines/bulk/create |
any(pipelines:write) + feature(bulk_operations) |
| pipeline | POST | /pipelines/bulk/delete |
any(pipelines:write) + feature(bulk_operations) |
| pipeline | PUT | /pipelines/bulk/update |
any(pipelines:write) + feature(bulk_operations) |
| pipeline | GET | /pipelines/deleted |
any(pipelines:read) |
| pipeline | GET | /pipelines/find |
any(pipelines:read) |
| pipeline | POST | /pipelines/generate |
any(pipelines:write) + feature(ai_generation) |
| pipeline | POST | /pipelines/generate/from-url |
any(pipelines:write) + feature(ai_generation) |
| pipeline | POST | /pipelines/generate/from-url/stream |
any(pipelines:write) + feature(ai_generation) |
| pipeline | POST | /pipelines/generate/stream |
any(pipelines:write) + feature(ai_generation) |
| pipeline | GET | /pipelines/providers |
any(pipelines:read) + feature(ai_generation) |
| pipeline | GET | /pipelines/registry |
any(pipelines:read) |
| pipeline | POST | /pipelines/registry |
any(pipelines:write) |
| pipeline | DELETE | /pipelines/registry/:id |
any(pipelines:write) |
| pipeline | GET | /pipelines/scorecard |
any(pipelines:read) + feature(advanced_reporting) |
| pipeline | POST | /pipelines/validate |
any(pipelines:write) |
| platform | GET | /admin/org-idp |
any(org:idp) |
| platform | DELETE | /admin/org-idp/:orgId |
any(org:idp) + aal2 + step-up(totp,webauthn) |
| platform | GET | /admin/org-idp/:orgId |
any(org:idp) |
| platform | PATCH | /admin/org-idp/:orgId |
any(org:idp) + aal2 + step-up(totp,webauthn) |
| platform | PUT | /admin/org-idp/:orgId |
any(org:idp) + aal2 + step-up(totp,webauthn) |
| platform | GET | /admin/orgs/:orgId/k8s-namespace.yaml |
sysadmin + step-up(any) |
| platform | DELETE | /admin/orgs/:orgId/kms-config |
any(org:kms) + aal2 + step-up(totp,webauthn) |
| platform | GET | /admin/orgs/:orgId/kms-config |
any(org:kms) |
| platform | PUT | /admin/orgs/:orgId/kms-config |
any(org:kms) + aal2 + step-up(totp,webauthn) |
| platform | POST | /admin/orgs/:orgId/kms-config/test |
any(org:kms) |
| platform | GET | /admin/console-check |
sysadmin + aal2 |
| platform | GET | /admin/summary |
sysadmin |
| platform | DELETE | /admin/users/:id/grants |
sysadmin + aal2 + step-up(totp,webauthn) |
| platform | POST | /admin/users/:id/grants |
sysadmin + aal2 + step-up(totp,webauthn) |
| platform | POST | /admin/users/:id/mfa-reset |
sysadmin + aal2 + step-up(totp,webauthn) |
| platform | POST | /audit/events |
service-principal + internal(ask,billing,compliance,image-registry,message,pipeline,plugin,quota,reporting) |
| platform | GET | /audit/verify |
sysadmin |
| platform | GET | /dashboards |
any(dashboards:read) |
| platform | POST | /dashboards |
any(dashboards:write) |
| platform | GET | /dashboards/:id |
any(dashboards:read) |
| platform | POST | /dashboards/:id/clone |
any(dashboards:write) |
| platform | GET | /dashboards/deleted |
any(dashboards:read) |
| platform | GET | /internal/ecosystem/approvers |
service-principal + internal(plugin) |
| platform | GET | /internal/ecosystem/publisher-eligibility/:orgId |
service-principal + internal(plugin) |
| platform | POST | /internal/notify-email |
service-principal + internal(compliance,plugin,reporting) |
| platform | GET | /internal/reporting/access-posture/:orgId |
service-principal + internal(reporting) |
| platform | GET | /internal/reporting/recipient-check/:orgId |
service-principal + internal(reporting) |
| platform | GET | /internal/reporting/report-authority/:orgId/:userId |
service-principal + internal(reporting) |
| platform | GET | /internal/notify-email/status |
service-principal + internal(ask,plugin,reporting) |
| platform | GET | /invitation |
any(invitations:manage) |
| platform | DELETE | /invitation/:invitationId |
any(invitations:manage) + org-admin-assurance |
| platform | POST | /invitation/:invitationId/resend |
any(invitations:manage) + org-admin-assurance |
| platform | POST | /invitation/send |
any(invitations:manage) + org-admin-assurance |
| platform | GET | /observability/alert-destinations |
any(observability:read) |
| platform | POST | /observability/alert-destinations |
any(observability:write) |
| platform | DELETE | /observability/alert-destinations/:id |
any(observability:write) |
| platform | PUT | /observability/alert-destinations/:id |
any(observability:write) |
| platform | POST | /observability/alert-destinations/:id/purge |
any(observability:write) + step-up(any) |
| platform | POST | /observability/alert-destinations/:id/restore |
any(observability:write) + step-up(any) |
| platform | POST | /observability/alert-destinations/:id/test |
any(observability:write) |
| platform | GET | /observability/alert-destinations/all |
sysadmin |
| platform | GET | /observability/alert-destinations/deleted |
any(observability:read) |
| platform | GET | /observability/alert-rules |
any(observability:read) |
| platform | POST | /observability/alert-rules |
any(observability:write) |
| platform | DELETE | /observability/alert-rules/:id |
any(observability:write) |
| platform | PUT | /observability/alert-rules/:id |
any(observability:write) |
| platform | POST | /observability/alert-rules/:id/purge |
any(observability:write) + step-up(any) |
| platform | POST | /observability/alert-rules/:id/restore |
any(observability:write) + step-up(any) |
| platform | GET | /observability/alert-rules/deleted |
any(observability:read) |
| platform | GET | /observability/alert-rules/materialized.yml |
sysadmin |
| platform | GET | /observability/alerts |
any(observability:read) |
| platform | GET | /observability/audit-query |
any(observability:read) |
| platform | GET | /observability/catalog |
any(observability:read) |
| platform | GET | /observability/logs |
any(observability:read) |
| platform | GET | /observability/logs/context |
any(observability:read) |
| platform | GET | /observability/logs/export |
any(logs:export) + org-admin-assurance |
| platform | GET | /observability/logs/raw |
any(observability:read) |
| platform | GET | /observability/logs/volume |
any(observability:read) |
| platform | GET | /observability/query |
any(observability:read) |
| platform | GET | /observability/silences |
any(observability:read) |
| platform | POST | /observability/silences |
any(observability:write) |
| platform | DELETE | /observability/silences/:id |
any(observability:write) |
| platform | POST | /organization |
any(org:settings) |
| platform | POST | /organization/names |
service-principal |
| platform | DELETE | /organization/:id |
sysadmin + step-up(any) |
| platform | PUT | /organization/:id |
sysadmin + step-up(any) |
| platform | GET | /organization/:id/authenticator-policy |
any(org:settings) |
| platform | PATCH | /organization/:id/authenticator-policy |
any(org:settings) + step-up(any) |
| platform | GET | /organization/:id/domains |
any(org:settings) |
| platform | POST | /organization/:id/domains |
any(org:settings) |
| platform | DELETE | /organization/:id/domains/:domainId |
any(org:settings) |
| platform | PATCH | /organization/:id/domains/:domainId |
any(org:settings) |
| platform | POST | /organization/:id/domains/:domainId/verify |
any(org:settings) |
| platform | GET | /organization/:id/export |
any(org:settings) |
| platform | PATCH | /organization/:id/identity |
any(org:settings) |
| platform | DELETE | /organization/:id/idp |
any(org:idp) + aal2 + step-up(totp,webauthn) |
| platform | GET | /organization/:id/idp |
any(org:idp) |
| platform | PATCH | /organization/:id/idp |
any(org:idp) + aal2 + step-up(totp,webauthn) |
| platform | PUT | /organization/:id/idp |
any(org:idp) + aal2 + step-up(totp,webauthn) |
| platform | GET | /organization/:id/idp/group-mappings |
any(roles:manage) |
| platform | POST | /organization/:id/idp/group-mappings |
any(roles:manage) + org-admin-assurance |
| platform | DELETE | /organization/:id/idp/group-mappings/:mappingId |
any(roles:manage) + org-admin-assurance |
| platform | PUT | /organization/:id/idp/group-mappings/:mappingId |
any(roles:manage) + org-admin-assurance |
| platform | POST | /organization/:id/idp/metadata/import |
any(org:idp) |
| platform | GET | /organization/:id/idp/sp-info |
any(org:idp) |
| platform | POST | /organization/:id/idp/test |
any(org:idp) |
| platform | POST | /organization/:id/idp/test/complete |
any(org:idp) |
| platform | GET | /organization/:id/impersonation-policy |
any(org:impersonation) |
| platform | PATCH | /organization/:id/impersonation-policy |
any(org:impersonation) + step-up(any) |
| platform | GET | /organization/:id/join-requests |
any(org:settings) |
| platform | POST | /organization/:id/join-requests/:reqId/:decision |
any(org:settings) |
| platform | POST | /organization/:id/members |
any(members:manage) + org-admin-assurance |
| platform | DELETE | /organization/:id/members/:userId |
any(members:manage) + org-admin-assurance |
| platform | PATCH | /organization/:id/members/:userId/activate |
any(members:manage) + org-admin-assurance |
| platform | PATCH | /organization/:id/members/:userId/deactivate |
any(members:manage) + org-admin-assurance |
| platform | POST | /organization/:id/members/bulk-add |
any(members:manage) + org-admin-assurance |
| platform | GET | /organization/:id/mfa-policy |
any(org:settings) |
| platform | PATCH | /organization/:id/mfa-policy |
any(org:settings) + step-up(any) |
| platform | GET | /organization/:id/mfa-resets |
any(members:manage) |
| platform | POST | /organization/:id/mfa-resets |
any(members:manage) + aal2 + step-up(any) |
| platform | POST | /organization/:id/mfa-resets/:requestId/approve |
any(members:manage) + aal2 + step-up(totp,webauthn) |
| platform | POST | /organization/:id/mfa-resets/:requestId/deny |
any(members:manage) |
| platform | POST | /organization/:id/move |
sysadmin + step-up(any) |
| platform | GET | /organization/:id/password-policy |
any(org:settings) |
| platform | PATCH | /organization/:id/password-policy |
any(org:settings) + step-up(any) |
| platform | POST | /organization/:id/restore |
any(org:settings) + step-up(any) |
| platform | POST | /organization/:id/roles |
any(roles:manage) + org-admin-assurance |
| platform | DELETE | /organization/:id/roles/:roleId |
any(roles:manage) + org-admin-assurance |
| platform | PUT | /organization/:id/roles/:roleId |
any(roles:manage) + org-admin-assurance |
| platform | POST | /organization/:id/roles/:roleId/members |
any(roles:manage) + org-admin-assurance |
| platform | DELETE | /organization/:id/roles/:roleId/members/:userId |
any(roles:manage) + org-admin-assurance |
| platform | GET | /organization/:id/service-accounts |
any(service_accounts:manage) |
| platform | POST | /organization/:id/service-accounts |
any(service_accounts:manage) + aal2(except bootstrap-setup) + step-up(any) |
| platform | DELETE | /organization/:id/service-accounts/:accountId |
any(service_accounts:manage) + step-up(any) |
| platform | GET | /organization/:id/service-accounts/:accountId |
any(service_accounts:manage) |
| platform | PATCH | /organization/:id/service-accounts/:accountId |
any(service_accounts:manage) + step-up(any) |
| platform | POST | /organization/:id/service-accounts/:accountId/keys |
any(service_accounts:manage) + aal2(except bootstrap-setup) + step-up(any) |
| platform | DELETE | /organization/:id/service-accounts/:accountId/keys/:keyId |
any(service_accounts:manage) |
| platform | DELETE | /organization/:id/teams/:teamId |
any(org:settings) + step-up(any) |
| platform | GET | /organization/:id/teams/deleted |
any(org:settings) |
| platform | PATCH | /organization/:id/tier |
sysadmin + step-up(any) |
| platform | PATCH | /organization/:id/transfer-owner |
any(org:settings) + aal2 + step-up(any) |
| platform | PUT | /organization/ai-config |
any(org:settings) + step-up(any) |
| platform | GET | /organizations |
sysadmin |
| platform | GET | /users |
any(members:manage) |
| platform | POST | /users |
any(members:manage) |
| platform | DELETE | /users/:id |
any(members:manage) + aal2 + step-up(any) |
| platform | GET | /users/:id |
any(members:manage) |
| platform | PUT | /users/:id |
any(members:manage) + aal2 + step-up(any) |
| platform | PUT | /users/:id/features |
any(members:manage) + aal2 + step-up(any) |
| platform | POST | /users/bulk-delete |
any(members:manage) + aal2 + step-up(any) |
| plugin | GET | /internal/plugins/public-names |
service-principal + internal(image-registry) |
| plugin | GET | /plugins |
any(plugins:read) |
| plugin | POST | /plugins |
any(plugins:write) |
| plugin | DELETE | /plugins/:id |
any(plugins:write) |
| plugin | GET | /plugins/:id |
any(plugins:read) |
| plugin | GET | /plugins/:id/sbom |
any(plugins:read) |
| plugin | PUT | /plugins/:id |
any(plugins:write) |
| plugin | POST | /plugins/:id/deprecate |
any(plugins:write) |
| plugin | POST | /plugins/:id/purge |
any(plugins:write) + step-up(any) |
| plugin | POST | /plugins/:id/restore |
any(plugins:write) + step-up(any) |
| plugin | POST | /plugins/:id/yank |
any(plugins:write) |
| plugin | POST | /plugins/bulk/delete |
any(plugins:write) + feature(bulk_operations) |
| plugin | PUT | /plugins/bulk/update |
any(plugins:write) + feature(bulk_operations) |
| plugin | GET | /plugins/catalog |
any(plugins:read) |
| plugin | GET | /plugins/deleted |
any(plugins:read) |
| plugin | POST | /plugins/deploy-generated |
any(plugins:write) |
| plugin | GET | /plugins/ecosystem/advisories |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/advisories |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | PATCH | /plugins/ecosystem/advisories/:id |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/advisories/:id/withdraw |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | GET | /plugins/ecosystem/listings |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/listings/:id/state |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/listings/:id/versions/:version/deprecate |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/listings/:id/versions/:version/unyank |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/listings/:id/versions/:version/yank |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | GET | /plugins/ecosystem/overview |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | GET | /plugins/ecosystem/publishers |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | POST | /plugins/ecosystem/publishers/:id/suspend |
system-org + any(publishers:verify) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/publishers/:id/tier |
system-org + any(publishers:verify) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/publishers/:id/unsuspend |
system-org + any(publishers:verify) + aal2 + step-up(any) |
| plugin | GET | /plugins/ecosystem/requests |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | GET | /plugins/ecosystem/requests/:id |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | GET | /plugins/ecosystem/requests/:id/submission-sbom |
system-org + any(plugins:moderate) + aal2 |
| plugin | GET | /plugins/ecosystem/requests/:id/submission-scan |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/requests/:id/approve |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | POST | /plugins/ecosystem/requests/:id/reject |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | POST | /plugins/ecosystem/requests/:id/second-approve |
system-org + any(plugins:moderate|publishers:verify) + aal2 |
| plugin | POST | /plugins/ecosystem/resign |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | GET | /plugins/ecosystem/reviews |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/reviews/:id/hold |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/reviews/:id/release |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/reviews/:id/remove |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/reviews/:id/remove-reply |
system-org + any(plugins:moderate) + aal2 |
| plugin | GET | /plugins/ecosystem/reserved-names |
system-org + any(plugins:moderate) + aal2 |
| plugin | DELETE | /plugins/ecosystem/reserved-names/:name |
system-org + any(plugins:moderate) + aal2 |
| plugin | PUT | /plugins/ecosystem/reserved-names/:name |
system-org + any(plugins:moderate) + aal2 |
| plugin | GET | /plugins/ecosystem/rules |
system-org + any(plugins:moderate) + aal2 |
| plugin | POST | /plugins/ecosystem/rules |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | DELETE | /plugins/ecosystem/rules/:id |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | PATCH | /plugins/ecosystem/rules/:id |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | POST | /plugins/ecosystem/rules/:id/approve-change |
system-org + any(plugins:moderate) + aal2 + step-up(any) |
| plugin | GET | /plugins/publish-requests |
any(plugins:read) |
| plugin | POST | /plugins/publish-requests |
any(plugins:publish|publishers:manage) |
| plugin | POST | /plugins/publish-requests/:id/transfer-response |
any(publishers:manage) + step-up(any) |
| plugin | POST | /plugins/publish-requests/:id/withdraw |
any(plugins:publish|publishers:manage) |
| plugin | GET | /plugins/publish-requests/draft |
any(plugins:publish) |
| plugin | GET | /plugins/publisher |
any(plugins:read) |
| plugin | PATCH | /plugins/publisher |
any(publishers:manage) |
| plugin | POST | /plugins/publisher |
any(publishers:manage) |
| plugin | GET | /plugins/publisher/advisories |
any(plugins:read) |
| plugin | GET | /plugins/publisher/incoming-transfers |
any(publishers:manage) |
| plugin | GET | /plugins/publisher/insights |
any(plugins:read) |
| plugin | GET | /plugins/publisher/listings |
any(plugins:read) |
| plugin | POST | /plugins/publisher/listings/:listingId/deprecate |
any(plugins:publish) |
| plugin | POST | /plugins/publisher/listings/:listingId/pause |
any(plugins:publish) |
| plugin | POST | /plugins/publisher/terms |
any(publishers:manage) |
| plugin | GET | /plugins/find |
any(plugins:read) |
| plugin | POST | /plugins/generate |
any(plugins:write) + feature(ai_generation) |
| plugin | POST | /plugins/generate/stream |
any(plugins:write) + feature(ai_generation) |
| plugin | POST | /plugins/inspect |
any(plugins:write) |
| plugin | GET | /plugins/install-policy |
any(plugins:read) |
| plugin | PUT | /plugins/install-policy |
any(plugin_installs:manage) + step-up(any) |
| plugin | GET | /plugins/installs |
any(plugins:read) |
| plugin | POST | /plugins/installs |
any(plugins:install) |
| plugin | DELETE | /plugins/installs/:id |
any(plugins:install) |
| plugin | PATCH | /plugins/installs/:id |
any(plugins:install) |
| plugin | POST | /plugins/installs/:id/approve |
any(plugin_installs:manage) |
| plugin | GET | /plugins/installs/change-requests |
any(plugin_installs:manage) |
| plugin | POST | /plugins/installs/:id/change-requests |
any(plugins:install) |
| plugin | POST | /plugins/installs/:id/change-requests/approve |
any(plugin_installs:manage) |
| plugin | POST | /plugins/installs/:id/change-requests/reject |
any(plugin_installs:manage) |
| plugin | POST | /plugins/installs/:id/deny |
any(plugin_installs:manage) |
| plugin | GET | /plugins/listings/:publisher/:name/install-state |
any(plugins:read) |
| plugin | GET | /plugins/listings/:publisher/:name/review-state |
any(plugins:read) |
| plugin | POST | /plugins/listings/:publisher/:name/reviews |
any(plugins:read) + aal1 |
| plugin | DELETE | /plugins/reviews/:id |
any(plugins:read) + aal1 |
| plugin | PATCH | /plugins/reviews/:id |
any(plugins:read) + aal1 |
| plugin | DELETE | /plugins/reviews/:id/helpful |
any(plugins:read) + aal1 |
| plugin | PUT | /plugins/reviews/:id/helpful |
any(plugins:read) + aal1 |
| plugin | DELETE | /plugins/reviews/:id/reply |
any(publishers:manage) + aal1 |
| plugin | PUT | /plugins/reviews/:id/reply |
any(publishers:manage) + aal1 |
| plugin | POST | /plugins/reviews/:id/report |
any(plugins:read) + aal1 |
| plugin | POST | /plugins/lookup |
any(plugins:read) |
| plugin | GET | /plugins/plugin-usage |
any(plugins:read) |
| plugin | GET | /plugins/providers |
any(plugins:read) + feature(ai_generation) |
| plugin | GET | /plugins/security-notifications |
any(plugins:read) |
| plugin | PUT | /plugins/security-notifications |
any(org:settings) |
| plugin | POST | /plugins/security-notifications/test |
any(org:settings) |
| plugin | GET | /plugins/shadowing |
any(plugins:read) |
| plugin | DELETE | /plugins/queue/dlq |
sysadmin |
| plugin | GET | /plugins/queue/dlq |
any(plugins:write) |
| plugin | POST | /plugins/queue/dlq/:jobId/replay |
any(plugins:write) |
| plugin | GET | /plugins/queue/failed |
any(plugins:write) |
| plugin | POST | /plugins/queue/failed/:jobId/retry |
any(plugins:write) |
| plugin | GET | /plugins/queue/status |
sysadmin |
| plugin | GET | /plugins/queue/triage |
any(plugins:write) |
| plugin | GET | /plugins/vuln-waivers |
any(plugins:read) |
| quota | GET | /quotas |
any(quotas:read) |
| quota | DELETE | /quotas/:orgId |
sysadmin + step-up(any) |
| quota | GET | /quotas/:orgId |
any(quotas:read)+svc |
| quota | PUT | /quotas/:orgId |
sysadmin |
| quota | GET | /quotas/:orgId/:quotaType |
any(quotas:read)+svc |
| quota | GET | /quotas/:orgId/at-risk |
any(quotas:read) |
| quota | POST | /quotas/:orgId/decrement |
service-principal + internal(ask,billing,compliance,image-registry,message,pipeline,platform,plugin,quota,reporting) |
| quota | POST | /quotas/:orgId/increment |
service-principal + internal(ask,billing,compliance,image-registry,message,pipeline,platform,plugin,quota,reporting) |
| quota | POST | /quotas/:orgId/reset |
sysadmin + step-up(any) |
| quota | GET | /quotas/all |
sysadmin |
| quota | GET | /quotas/at-risk |
sysadmin |
| reporting | POST | /reports/deployments/:executionId/outcome |
any(pipelines:write) + feature(advanced_reporting) |
| reporting | GET | /reports/execution/action-failures |
any(reports:read) |
| reporting | GET | /reports/execution/build-health |
any(reports:read) |
| reporting | GET | /reports/execution/count |
any(reports:read) |
| reporting | GET | /reports/execution/dora |
any(reports:read) + feature(advanced_reporting) |
| reporting | GET | /reports/execution/dora/trend |
any(reports:read) + feature(advanced_reporting) |
| reporting | GET | /reports/execution/duration |
any(reports:read) |
| reporting | GET | /reports/execution/environments |
any(reports:read) + feature(advanced_reporting) |
| reporting | GET | /reports/execution/errors |
sysadmin + any(reports:read) |
| reporting | GET | /reports/execution/list |
any(reports:read) |
| reporting | GET | /reports/execution/stage-bottlenecks |
any(reports:read) |
| reporting | GET | /reports/execution/stage-failures |
any(reports:read) |
| reporting | POST | /reports/execution/stream/ticket |
any(reports:read) |
| reporting | GET | /reports/execution/success-rate |
any(reports:read) |
| reporting | GET | /reports/incidents |
any(reports:read) + feature(advanced_reporting) |
| reporting | POST | /reports/incidents/test |
any(reports:read) + feature(advanced_reporting) |
| reporting | GET | /reports/ingest-health |
any(reports:read) |
| reporting | GET | /reports/plugins/build-duration |
any(reports:read) |
| reporting | GET | /reports/plugins/build-failures |
sysadmin + any(reports:read) |
| reporting | GET | /reports/plugins/build-success-rate |
any(reports:read) |
| reporting | GET | /reports/plugins/distribution |
any(reports:read) |
| reporting | GET | /reports/plugins/runtime-duration |
any(reports:read) |
| reporting | GET | /reports/plugins/runtime-success-rate |
any(reports:read) |
| reporting | GET | /reports/plugins/summary |
any(reports:read) |
| reporting | GET | /reports/plugins/versions |
any(reports:read) |
| reporting | GET | /reports/retention |
any(reports:read) |
| reporting | PUT | /reports/retention-sync/:orgId |
service-principal + internal(billing) |
| reporting | PUT | /reports/stakeholder-sync/:orgId |
service-principal + internal(billing) |
| reporting | GET | /reports/retention-sync/:orgId |
service-principal + internal(billing) |
| reporting | GET | /reports/settings/incidents |
any(reports:read) + feature(advanced_reporting) |
| reporting | PUT | /reports/settings/incidents |
any(reports:read) + any(org:settings) + feature(advanced_reporting) |
| reporting | POST | /reports/stakeholder-internal/owner-left/:orgId/:userId |
service-principal + internal(platform) |
| reporting | GET | /reports/stakeholder/definitions |
any(reports:read) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/definitions |
any(reports:author) + feature(stakeholder_reports) |
| reporting | DELETE | /reports/stakeholder/definitions/:id |
any(reports:author) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/definitions/:id |
any(reports:read) + feature(stakeholder_reports) |
| reporting | PUT | /reports/stakeholder/definitions/:id |
any(reports:author) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/definitions/:id/runs |
any(reports:read) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/definitions/:id/runs |
any(reports:author) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/definitions/:id/transfer |
any(reports:author) + feature(stakeholder_reports) |
| reporting | DELETE | /reports/stakeholder/links/:id |
any(reports:share) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/delivery-status |
any(reports:read) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder-preview |
any(reports:read) |
| reporting | POST | /reports/stakeholder-preview |
any(reports:author) |
| reporting | GET | /reports/stakeholder/policy |
any(reports:read) + feature(stakeholder_reports) |
| reporting | PUT | /reports/stakeholder/policy |
any(org:settings) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/recipients |
any(reports:read) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/recipients |
any(reports:author) + feature(stakeholder_reports) |
| reporting | DELETE | /reports/stakeholder/recipients/:id |
any(reports:author) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/recipients/:id/resend |
any(reports:author) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/runs/:id |
any(reports:read) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/runs/:id/links |
any(reports:read) + feature(stakeholder_reports) |
| reporting | GET | /reports/stakeholder/runs/:id/pdf |
any(reports:read) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/runs/:id/links |
any(reports:share) + feature(stakeholder_reports) |
| reporting | PUT | /reports/stakeholder/runs/:id/notes |
any(reports:author) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/runs/:id/summary |
any(reports:author) + feature(stakeholder_reports) |
| reporting | POST | /reports/stakeholder/runs/:id/publish |
any(reports:share) + feature(stakeholder_reports) |