# Proposed contract, version 1: endpoints, errors, paging, idempotency, security and the capability of every
# operation. Resource schemas were initialized from the data model (docs/06-data) and are kept aligned with it; input
# schemas (*Input, *Request) and views are specific to this contract. Status: proposal for review, not confirmed design.
# Conventions: docs/05-interfaces/choosing-an-interface.md. Vendor extensions: x-moonitoring-audience (who calls),
# x-moonitoring-capability (the capability checked), x-moonitoring-entitlement (the entitlement feature checked),
# x-moonitoring-requirements (the requirements of 1.requisiti-raffinati.txt the operation serves).
openapi: 3.1.0
info:
  title: Access Staff API
  version: 1.0.0
  description: 'Moonitoring users (people and service accounts), the staff roles and their memberships, and the
    catalog of capabilities every system publishes. Entirely separate from Organization access: nothing here references
    a User or an Organization.'
servers:
- url: https://access.moonitoring.com/staff/v1
  description: Prod
- url: https://stage-access.moonitoring.com/staff/v1
  description: Stage, through IAP
security:
- bearer: []
tags:
- name: Me
  description: The signed-in staff member
- name: Users
  description: Moonitoring users
- name: Roles
  description: Staff roles
- name: Catalogs
  description: Capabilities published by the systems
paths:
  /me:
    get:
      summary: Who am I
      operationId: getCurrentStaffUser
      description: The staff member behind the token, with their roles and capabilities. The Console calls it first
        and shows only the sections those capabilities allow.
      tags:
      - Me
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrentStaffUser'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '26'
      - '24'
      - '25'
  /users:
    get:
      summary: List Moonitoring users
      operationId: listStaffUsers
      tags:
      - Users
      parameters:
      - name: type
        in: query
        required: false
        schema:
          type: string
          enum:
          - MoonitoringPerson
          - MoonitoringServiceAccount
        description: Only this kind.
      - name: include_disabled
        in: query
        required: false
        schema:
          type: boolean
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MoonitoringUser'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.read
      x-moonitoring-requirements:
      - '26'
      - '1006.1'
    post:
      summary: Create a Moonitoring user
      operationId: createStaffUser
      tags:
      - Users
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MoonitoringUserInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringUser'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.manage
      x-moonitoring-requirements:
      - '26'
      - 26.*.1
      - 26.*.2
      - '1006.2'
  /users/{user_id}:
    get:
      summary: Read a Moonitoring user
      operationId: getStaffUser
      tags:
      - Users
      parameters:
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringUser'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.read
      x-moonitoring-requirements:
      - '26'
      - '1006.1'
  /users/{user_id}/disable:
    post:
      summary: Disable a Moonitoring user
      operationId: disableStaffUser
      tags:
      - Users
      parameters:
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringUser'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.manage
      x-moonitoring-requirements:
      - '26.5'
      - '1006.2'
  /users/{user_id}/google-service-account:
    put:
      summary: Link a Google service account
      operationId: linkStaffGoogleServiceAccount
      description: 'Lets the Google service account with this e-mail act as this MoonitoringServiceAccount through
        Identity-Aware Proxy (decided 2026-11-13): an IAP assertion for that e-mail is then exchanged for this
        account''s staff token, with no key. The user must be an enabled MoonitoringServiceAccount; the e-mail must be
        a Google service account''s (ending in `.gserviceaccount.com`), is kept in lower case, and may be linked to
        no other enabled account (409). Linking the e-mail the account already has changes nothing. Replaces a
        previous link; each change is the audit event `access.moonitoring_access.link_google_service_account`.'
      tags:
      - Users
      parameters:
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleServiceAccountLinkInput'
      responses:
        '200':
          description: The service account, with its link.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringUser'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.manage
      x-moonitoring-requirements:
      - 26.*.2.5
      - '1006.2'
    delete:
      summary: Unlink the Google service account
      operationId: unlinkStaffGoogleServiceAccount
      description: 'Stops the linked Google service account from acting as this MoonitoringServiceAccount: its next
        exchange of an IAP assertion is refused, and staff tokens already issued expire within five minutes. An
        account with no link is answered as it is. Each change is the audit event
        `access.moonitoring_access.unlink_google_service_account`.'
      tags:
      - Users
      parameters:
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The service account, without a link.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringUser'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.manage
      x-moonitoring-requirements:
      - 26.*.2.5
      - '1006.2'
  /users/{user_id}/memberships:
    get:
      summary: List a user's staff memberships
      operationId: listStaffMemberships
      tags:
      - Users
      parameters:
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: include_revoked
        in: query
        required: false
        schema:
          type: boolean
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MoonitoringAccessControlMembership'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.read
      x-moonitoring-requirements:
      - '24'
      - '1006.1'
    post:
      summary: Give a staff role
      operationId: createStaffMembership
      tags:
      - Users
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StaffMembershipInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringAccessControlMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.manage
      x-moonitoring-requirements:
      - '24'
      - '25.4'
      - '1006.2'
  /users/{user_id}/memberships/{membership_id}/revoke:
    post:
      summary: Revoke a staff role
      operationId: revokeStaffMembership
      tags:
      - Users
      parameters:
      - name: user_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: membership_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringAccessControlMembership'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.manage
      x-moonitoring-requirements:
      - '24.5'
      - '24.6'
      - '1006.2'
  /roles:
    get:
      summary: List staff roles
      operationId: listStaffRoles
      tags:
      - Roles
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MoonitoringRoleAccessControl'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.read
      x-moonitoring-requirements:
      - '25'
      - '1006.1'
    post:
      summary: Create a staff role
      operationId: createStaffRole
      description: The caller must outrank the new role and hold every capability in it (req 25.4); otherwise 403.
      tags:
      - Roles
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StaffRoleInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringRoleAccessControl'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_roles.manage
      x-moonitoring-requirements:
      - '25'
      - '1006'
      - '1006.3'
  /roles/{role_id}:
    patch:
      summary: Update a staff role
      operationId: updateStaffRole
      description: The caller must outrank the role and hold every capability it has and every one it gains, and must
        not hold the role (req 25.4); otherwise 403. Administrators is never changed through it.
      tags:
      - Roles
      parameters:
      - name: role_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StaffRoleInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MoonitoringRoleAccessControl'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_roles.manage
      x-moonitoring-requirements:
      - '25'
      - '25.5'
      - '1006.3'
  /capability-catalogs:
    get:
      summary: List the capability catalogs
      operationId: listCapabilityCatalogs
      description: 'The catalog each system published at its last deploy: the union is what a role may contain,
        what an entitlement may name and which tools an agent may bind. Each capability carries its risk (decided
        2026-11-11), so the Console marks the admin ones. Collected through the `Catalog` gRPC service
        every system implements.'
      tags:
      - Catalogs
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CapabilityCatalog'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: access.moonitoring_access.read
      x-moonitoring-requirements:
      - '1002'
      - '1006'
      - '68.3'
      - '122'
components:
  schemas:
    MoonitoringAccessControlMembership:
      description: Grants a Moonitoring user a role on the platform. It mirrors organization memberships but lives
        in a separate structure, so platform administration never depends on customer data.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        user:
          type: string
          format: uuid
          description: ID of the MoonitoringUser.
        assigner:
          type: string
          format: uuid
          description: 'ID of the MoonitoringUser. Empty for the first member of the system and for a membership the
            job access-bootstrap-admin made (decided 2026-11-11): the Console shows "access-bootstrap-admin job" and
            reads who ran it from the audit event, whose `actor_system` is access-bootstrap-admin and whose `after`
            names the `operator`.'
        role:
          type: string
          format: uuid
          description: ID of the MoonitoringRoleAccessControl.
        revoked_at:
          type: string
          format: date-time
          description: When the membership ended; rows are never deleted.
        revoked_by:
          type: string
          format: uuid
          description: ID of the MoonitoringUser.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - user
      - role
      - system_version
      - created_at
      - updated_at
    MoonitoringRoleAccessControl:
      description: A named bundle of platform capabilities for Moonitoring users, ordered by priority like organization
        roles.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        name:
          type: string
          description: Unique.
        capabilities:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/MoonitoringCapabilityEnum
        priority:
          type: integer
          description: Higher value = higher priority = higher permissions; also used for ordering. A staff member
            grants, revokes or edits a role only if they outrank it and hold every capability in it, and never a role
            they hold (req 25.4).
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        key:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/MoonitoringPredefinedRoleEnum
          description: The stable key of a predefined staff role (req 1029), absent for a role staff created. Set by
            access; no operation sets or changes it.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - name
      - priority
      - system_version
      - created_at
      - updated_at
    MoonitoringUser:
      description: 'Anyone who acts for Moonitoring itself: a person on the team, or a service account such as model
        training, the continuous integration (CI) pipeline that builds our software, or an internal job. Moonitoring
        users never reference organization users or roles, which keeps platform access isolated from customer access.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        disabled_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - MoonitoringPerson
          - MoonitoringServiceAccount
          description: Which kind of MoonitoringUser this is (enum, disjoint + complete).
      required:
      - id
      - created_at
      - updated_at
      - type
    MoonitoringPerson:
      allOf:
      - $ref: '#/components/schemas/MoonitoringUser'
      - type: object
        properties:
          name:
            type: string
          surname:
            type: string
          email:
            type: string
            format: regex
            description: Unique.
        required:
        - name
        - surname
        - email
      description: A MoonitoringUser whose type is MoonitoringPerson.
    MoonitoringServiceAccount:
      allOf:
      - $ref: '#/components/schemas/MoonitoringUser'
      - type: object
        properties:
          description:
            type: string
          owner:
            type: string
            format: uuid
            description: ID of the MoonitoringUser that is a MoonitoringPerson.
          credential_ref:
            type: string
            description: Reference to the credential in the secret manager. Secrets and keys never enter the database.
          last_used_at:
            type: string
            format: date-time
          google_service_account:
            type: string
            format: email
            description: The e-mail of the Google service account allowed to act as this account through
              Identity-Aware Proxy, in lower case; absent when none is (req 26.*.2.5). Unique among enabled
              MoonitoringServiceAccounts.
        required:
        - description
        - owner
        - credential_ref
      description: A MoonitoringUser whose type is MoonitoringServiceAccount.
    CurrentStaffUser:
      type: object
      description: The signed-in Moonitoring user, their active roles and the union of their capabilities.
      properties:
        user:
          $ref: '#/components/schemas/MoonitoringUser'
        memberships:
          type: array
          items:
            $ref: '#/components/schemas/MoonitoringAccessControlMembership'
        roles:
          type: array
          items:
            $ref: '#/components/schemas/MoonitoringRoleAccessControl'
        capabilities:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/MoonitoringCapabilityEnum
      required:
      - user
      - memberships
      - roles
      - capabilities
    MoonitoringUserInput:
      type: object
      description: 'Creates a Moonitoring user: a person, identified by their Google Workspace e-mail, or a service
        account for CI and internal jobs.'
      properties:
        type:
          type: string
          enum:
          - MoonitoringPerson
          - MoonitoringServiceAccount
        name:
          type: string
        surname:
          type: string
        email:
          type: string
          format: email
        description:
          type: string
          description: Service accounts only.
        owner:
          type: string
          format: uuid
          description: 'Service accounts only: the person responsible.'
        public_key:
          type: object
          description: 'Service accounts only: the key it signs token requests with.'
          properties:
            kty:
              type: string
            crv:
              type: string
            x:
              type: string
            kid:
              type: string
          required:
          - kty
      required:
      - type
    GoogleServiceAccountLinkInput:
      type: object
      description: The Google service account to link to a MoonitoringServiceAccount (req 26.*.2.5).
      properties:
        email:
          type: string
          format: email
          pattern: ^[^@\s]+@[^@\s]+\.gserviceaccount\.com$
          description: The Google service account's e-mail, `<name>@<project>.iam.gserviceaccount.com`; compared and
            kept in lower case.
      required:
      - email
      additionalProperties: false
    StaffMembershipInput:
      type: object
      description: Gives a Moonitoring user a staff role. The caller's highest role must have a higher priority
        than the role given, and nobody assigns a role to themselves.
      properties:
        role:
          type: string
          format: uuid
          description: ID of the MoonitoringRoleAccessControl.
      required:
      - role
    StaffRoleInput:
      type: object
      description: Input to create or change a MoonitoringRoleAccessControl; server-managed fields are left out.
      properties:
        name:
          type: string
          description: Unique.
        capabilities:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/MoonitoringCapabilityEnum
        priority:
          type: integer
          description: Higher value = higher priority = higher permissions; also used for ordering. A user who can
            assign roles can assign only roles whose priority is lower than that of their own role.
      required:
      - name
      - priority
      additionalProperties: false
    CapabilityCatalog:
      type: object
      description: 'The catalog one system publishes from its code: its capabilities for Organization roles and
        for staff roles, its entitlement features and its agent tools.'
      properties:
        system:
          type: string
          description: Short name of the system, e.g. farm.
        version:
          type: string
          description: Release of the system that published it.
        organization_capabilities:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type: string
              risk:
                type: string
                enum:
                - read
                - write
                - admin
                description: 'As the system declares it (decided 2026-11-11): read only reads, write changes data,
                  admin changes who can act, where data goes or whether something exists.'
            required:
            - name
            - risk
        staff_capabilities:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type: string
              risk:
                type: string
                enum:
                - read
                - write
                - admin
                description: 'As the system declares it (decided 2026-11-11): read only reads, write changes data,
                  admin changes who can act, where data goes or whether something exists.'
            required:
            - name
            - risk
        features:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
                description: Named like a capability, <system>.<feature>.
              description:
                type: string
              metered:
                type: boolean
            required:
            - name
        tools:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type: string
              risk:
                type: string
                enum:
                - read
                - write
                - dangerous
              data_class:
                type: string
                enum:
                - public
                - personal
            required:
            - name
        published_at:
          type: string
          format: date-time
      required:
      - system
      - version
      - organization_capabilities
      - staff_capabilities
      - features
      - tools
      - published_at
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'The short-lived token signed by `access`: an Organization user token, a staff token or a client
        token, as the operation''s audience says.'
