openapi: 3.1.0
info:
  title: Reception API
  summary: Request, approval, and provisioning control plane.
  description: "\nPortier Reception is a request, approval, and provisioning API.\n\
    \nNormal user flow:\n\n1. Discover capabilities with `GET /v1/capabilities`.\n\
    2. Submit a public check-in request with `POST /v1/checkin-requests`, or a\n \
    \  human/agent registration with\n   `POST /v1/registration-requests`.\n   Include\
    \ `platform_anchors` when the requester needs to preserve an external\n   OpenAI\
    \ Codex or Claude Code continuity UID.\n3. Store the returned `claim_token`; it\
    \ is not shown again.\n4. Poll `GET /v1/requests/{request_id}` with the claim\
    \ token and follow `allowed_actions`.\n5. Wait for an administrator to approve\
    \ or reject the request.\n6. For password-backed services, claim the generated\
    \ credential with\n   `POST /v1/requests/{request_id}/claim-credential` after\
    \ the request is active.\n7. Existing service/key changes still require authenticated\
    \ identity/admin flow.\n\nAdmin flow:\n\n1. Review pending requests on the managed\
    \ host with `sudo portier-adm`.\n2. Approve or reject with a short decision note.\n\
    3. Let `portier-reception-worker.service` provision approved access requests.\n\
    \   Registrations use the same approval/provisioning channel as check-in\n   requests;\
    \ supported services are controlled by the requested service list.\n\nNothing\
    \ is granted by default. LLDAP groups, shell access, calendar access,\nmail access,\
    \ chat access, and SSH keys should move through this API rather than\nmanual edits.\n\
    The admin bearer token is bootstrap-only; after the first valid admin exists,\n\
    admin API actions require LLDAP admin credentials. Admin identities must have\n\
    shell access.\n"
  version: 0.1.22
paths:
  /healthz:
    get:
      tags:
      - system
      summary: Health check
      description: Unauthenticated liveness check for reverse proxies and operators.
      operationId: healthz_healthz_get
      responses:
        '200':
          description: The service is reachable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthEnvelope'
  /v1/capabilities:
    get:
      tags:
      - system
      summary: Discover Reception capabilities
      description: Returns the machine-readable operation list, supported request
        types, supported services, and workflow hints. Autonomous clients should call
        this before submitting requests.
      operationId: getCapabilities
      responses:
        '200':
          description: Reception capability descriptor.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CapabilitiesEnvelope'
  /v1/operator-guide:
    get:
      tags:
      - operator
      summary: Get human and AI operator guidance
      description: Return concise operational guidance. Automation clients should
        use this to understand the request lifecycle. Human admins should use it to
        see the canonical `portier-adm` commands.
      operationId: getOperatorGuide
      responses:
        '200':
          description: Operational guide for Reception.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperatorGuideEnvelope'
  /v1/checkin-requests:
    post:
      tags:
      - checkin_requests
      summary: Create a check-in request
      description: Request creation of a new identity. This does not grant access.
        The response is a pending request with action links; an admin must approve
        it before provisioning happens.
      operationId: createCheckinRequest
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional client-generated key to make retries safe.
          title: Idempotency-Key
        description: Optional client-generated key to make retries safe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckinRequestCreate'
      responses:
        '202':
          description: Pending check-in request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/registration-requests:
    post:
      tags:
      - registration_requests
      summary: Create a human or agent registration request
      description: Register a human collaborator or agent for governance review. Registrations
        are converted into the normal check-in request channel, so admin approval
        queues standard worker provisioning for supported requested services.
      operationId: createRegistrationRequest
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional client-generated key to make retries safe.
          title: Idempotency-Key
        description: Optional client-generated key to make retries safe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegistrationRequestCreate'
      responses:
        '202':
          description: Pending check-in request created from registration.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/service-requests:
    post:
      tags:
      - service_requests
      summary: Create a service entitlement request
      description: Request enabling or disabling `registry`, `mail`, `calendar`, `shell`,
        or `chat` for an existing identity. The request stays pending until admin
        review. `registry` grants local Parfit registry socket access.
      operationId: createServiceRequest
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional client-generated key to make retries safe.
          title: Idempotency-Key
        description: Optional client-generated key to make retries safe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceRequestCreate'
      responses:
        '202':
          description: Pending service entitlement request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/key-requests:
    post:
      tags:
      - key_requests
      summary: Create an SSH key request
      description: Request adding, replacing, or removing SSH public keys for an existing
        identity. Shell login requires both approved `shell` service access and approved
        key material.
      operationId: createKeyRequest
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional client-generated key to make retries safe.
          title: Idempotency-Key
        description: Optional client-generated key to make retries safe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/KeyRequestCreate'
      responses:
        '202':
          description: Pending SSH key request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/identity-update-requests:
    post:
      tags:
      - identity_requests
      summary: Create an identity update request
      description: Request a reviewed change to an existing identity slug, display
        name, email, or agent runtime metadata. The request stays pending until admin
        approval. A slug change reprovisions the LLDAP/Linux username and returns
        a one-time claim token so the requester can claim the generated password for
        the new identity.
      operationId: createIdentityUpdateRequest
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional client-generated key to make retries safe.
          title: Idempotency-Key
        description: Optional client-generated key to make retries safe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentityUpdateRequestCreate'
      responses:
        '202':
          description: Pending identity update request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/requests/{request_id}:
    get:
      tags:
      - requests
      summary: Get request status
      description: Inspect the current status, effective state, request summary, and
        next valid action links for a request.
      operationId: getRequestById
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      responses:
        '200':
          description: Request state envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/requests/{request_id}/cancel:
    post:
      tags:
      - requests
      summary: Cancel a pending request
      description: Cancel a pending request. The requester can cancel their own request;
        admins can cancel any pending request.
      operationId: cancelRequest
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      responses:
        '200':
          description: Cancelled request envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/requests/{request_id}/claim-credential:
    post:
      tags:
      - requests
      summary: Claim generated service credentials
      description: Claim the generated LLDAP password for a password-backed request.
        The caller must provide the one-time claim_token returned only in the original
        request creation response. The credential is returned once and then cleared
        from Reception storage.
      operationId: claimRequestCredential
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CredentialClaimRequest'
      responses:
        '200':
          description: Claimed generated credential.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CredentialClaimEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/directory:
    get:
      tags:
      - directory
      summary: Get grant-gated directory state
      description: Return a read-only directory view for authenticated identities
        with the `directory` service grant. Portier serves its audited identity mirror
        instead of requiring clients to bind broadly to LDAP, and exposes only contact,
        group, and approved agent runtime metadata fields.
      operationId: getDirectory
      responses:
        '200':
          description: Directory identities and group membership.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryEnvelope'
  /v1/identities/{identity_slug}:
    get:
      tags:
      - identities
      summary: Get effective identity state
      description: Inspect the provisioned identity state mirrored from identity infrastructure,
        including governance groups, effective services, and approved public keys.
      operationId: getIdentityBySlug
      parameters:
      - name: identity_slug
        in: path
        required: true
        schema:
          type: string
          title: Identity Slug
      responses:
        '200':
          description: Effective identity state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/identities/{identity_slug}/password:
    post:
      tags:
      - identities
      summary: Change an identity password
      description: Change the caller's shared LLDAP password. The caller must authenticate
        with HTTP Basic using the current password and the Basic username must match
        the target identity slug. Reception never stores the new password.
      operationId: changeIdentityPassword
      parameters:
      - name: identity_slug
        in: path
        required: true
        schema:
          type: string
          title: Identity Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordChangeRequest'
      responses:
        '200':
          description: Password change confirmation without secret material.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordChangeEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/admin/requests/{request_id}/approve:
    post:
      tags:
      - admin
      summary: Approve a pending request
      description: Admin-only API approval endpoint. Human admins should normally
        use `sudo portier-adm` on the managed host, which records a note and starts
        the worker.
      operationId: approveRequest
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminDecision'
      responses:
        '200':
          description: Approved request envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/admin/requests/{request_id}/reject:
    post:
      tags:
      - admin
      summary: Reject a pending request
      description: Admin-only rejection endpoint. Record a short note explaining why
        the request was rejected.
      operationId: rejectRequest
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminDecision'
      responses:
        '200':
          description: Rejected request envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/admin/requests/{request_id}/retry:
    post:
      tags:
      - admin
      summary: Retry failed provisioning
      description: Admin-only retry endpoint for requests whose provisioning job failed.
        The request is moved back to approved and the worker can process it again.
      operationId: retryRequest
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      responses:
        '200':
          description: Retried request envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestEnvelope'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    ActionLink:
      properties:
        action:
          type: string
          title: Action
        method:
          type: string
          title: Method
        href:
          type: string
          title: Href
        operation_id:
          type: string
          title: Operation Id
        required_role:
          anyOf:
          - type: string
          - type: 'null'
          title: Required Role
        description:
          anyOf:
          - type: string
          - type: 'null'
          title: Description
      additionalProperties: false
      type: object
      required:
      - action
      - method
      - href
      - operation_id
      title: ActionLink
    AdminDecision:
      properties:
        note:
          type: string
          title: Note
          description: Decision note recorded in Reception audit state.
      additionalProperties: false
      type: object
      required:
      - note
      title: AdminDecision
      examples:
      - note: 'Approved: requested shell access and one SSH public key.'
    AgentInterface:
      type: string
      enum:
      - CLI
      - WEB
      title: AgentInterface
    AgentMetadata:
      properties:
        agent_uuid:
          anyOf:
          - type: string
            pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
          - type: 'null'
          title: Agent Uuid
          description: Optional stable UUID assigned by the agent platform or runtime.
        agent_platform:
          anyOf:
          - $ref: '#/components/schemas/AgentPlatform'
          - type: 'null'
          description: Optional agent platform. Currently one of OpenAI, Anthropic,
            or DeepSeek.
        agent_interface:
          anyOf:
          - $ref: '#/components/schemas/AgentInterface'
          - type: 'null'
          description: Optional agent interface. Currently one of CLI or WEB.
        agent_model_id:
          anyOf:
          - type: string
            pattern: ^(?:gpt-\d+\.\d+|opus-\d+\.\d+|sonnet-\d+\.\d+|deepseek-[A-Za-z0-9_.-]+)$
          - type: 'null'
          title: Agent Model Id
          description: Optional model identifier. Model version is not stored separately.
        agent_host:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$
          - type: 'null'
          title: Agent Host
          description: Optional host where the agent runtime normally runs.
      additionalProperties: false
      type: object
      title: AgentMetadata
    AgentPlatform:
      type: string
      enum:
      - OpenAI
      - Anthropic
      - DeepSeek
      title: AgentPlatform
    AllowedAction:
      type: string
      enum:
      - get_status
      - cancel
      - approve
      - reject
      - retry
      - view_identity
      - claim_credential
      title: AllowedAction
    CalendarClientConfig:
      properties:
        account:
          type: string
          title: Account
        profile:
          type: string
          title: Profile
        collection_url:
          type: string
          title: Collection Url
        login_user:
          type: string
          title: Login User
        secret_key:
          type: string
          title: Secret Key
        authentication:
          type: string
          title: Authentication
        password_source:
          type: string
          title: Password Source
        setup_order:
          items:
            type: string
          type: array
          title: Setup Order
        account_set_command:
          type: string
          title: Account Set Command
        init_profile_command:
          type: string
          title: Init Profile Command
      additionalProperties: false
      type: object
      required:
      - account
      - profile
      - collection_url
      - login_user
      - secret_key
      - authentication
      - password_source
      - setup_order
      - account_set_command
      - init_profile_command
      title: CalendarClientConfig
    CapabilitiesEnvelope:
      properties:
        service:
          type: string
          title: Service
        version:
          type: string
          title: Version
        api_root:
          type: string
          title: Api Root
        openapi_url:
          type: string
          title: Openapi Url
        supported_identity_types:
          items:
            $ref: '#/components/schemas/IdentityType'
          type: array
          title: Supported Identity Types
        supported_services:
          items:
            $ref: '#/components/schemas/RequestedService'
          type: array
          title: Supported Services
        supported_request_types:
          items:
            $ref: '#/components/schemas/RequestType'
          type: array
          title: Supported Request Types
        supported_statuses:
          items:
            $ref: '#/components/schemas/RequestStatus'
          type: array
          title: Supported Statuses
        mail_client_config:
          $ref: '#/components/schemas/MailClientConfig'
        calendar_client_config:
          $ref: '#/components/schemas/CalendarClientConfig'
        operations:
          items:
            $ref: '#/components/schemas/OperationDescriptor'
          type: array
          title: Operations
        workflows:
          items:
            $ref: '#/components/schemas/WorkflowDescriptor'
          type: array
          title: Workflows
      additionalProperties: false
      type: object
      required:
      - service
      - version
      - api_root
      - openapi_url
      - supported_identity_types
      - supported_services
      - supported_request_types
      - supported_statuses
      - mail_client_config
      - calendar_client_config
      - operations
      - workflows
      title: CapabilitiesEnvelope
    ChatClientConfig:
      properties:
        jid:
          type: string
          title: Jid
        login_user:
          type: string
          title: Login User
        domain:
          type: string
          title: Domain
        server_host:
          type: string
          title: Server Host
        port:
          type: integer
          title: Port
        security:
          type: string
          title: Security
        authentication:
          type: string
          title: Authentication
        password_source:
          type: string
          title: Password Source
      additionalProperties: false
      type: object
      required:
      - jid
      - login_user
      - domain
      - server_host
      - port
      - security
      - authentication
      - password_source
      title: ChatClientConfig
    CheckinRequestCreate:
      properties:
        display_name:
          type: string
          title: Display Name
          description: Display name shown to admins and operators.
        slug:
          type: string
          pattern: ^[a-z0-9]+(?:[_-][a-z0-9]+)*$
          title: Slug
          description: Stable identity slug. This becomes the Linux/LDAP username
            and home-directory name. Use lowercase letters, digits, underscores, or
            hyphens; the slug must start and end with a letter or digit.
        email:
          type: string
          title: Email
          description: Requester contact or desired service email. For hosted mail,
            use the canonical mailbox address, which may have a human-readable local
            part independent from the operational slug.
        identity_type:
          $ref: '#/components/schemas/IdentityType'
          description: Whether this identity is an agent or a human.
        public_keys:
          items:
            $ref: '#/components/schemas/PublicKeySubmission'
          type: array
          title: Public Keys
          description: Optional SSH public keys to request during check-in.
        requested_services:
          items:
            $ref: '#/components/schemas/RequestedService'
          type: array
          title: Requested Services
          description: Initial services requested for the identity. If omitted, Portier
            asks for `registry` access as the baseline coordination entitlement. Nothing
            is granted until admin approval.
        platform_anchors:
          items:
            $ref: '#/components/schemas/PlatformAnchorSubmission'
          type: array
          title: Platform Anchors
          description: Optional external identity anchors to preserve continuity across
            platforms, for example an OpenAI Codex UID. These are recorded for registry
            correlation; they are not Linux UID numbers and are not secrets.
        registration_metadata:
          anyOf:
          - type: object
          - type: 'null'
          title: Registration Metadata
          description: Optional original registration metadata carried for audit/review.
            Workers must not treat this as an additional entitlement source.
      additionalProperties: false
      type: object
      required:
      - display_name
      - slug
      - email
      - identity_type
      title: CheckinRequestCreate
      examples:
      - display_name: Vera Traccia
        email: vera.traccia@example.org
        identity_type: agent
        platform_anchors:
        - anchor_state: current
          anchor_type: uid
          anchor_value: codex-identity-anchor
          platform: codex
          provider: OpenAI
        public_keys: []
        requested_services:
        - registry
        - mail
        - calendar
        slug: vtraccia
    CredentialClaimEnvelope:
      properties:
        request_id:
          type: string
          title: Request Id
        identity_slug:
          type: string
          title: Identity Slug
        credential_id:
          type: string
          title: Credential Id
        credential_type:
          type: string
          title: Credential Type
        mail_client_config:
          anyOf:
          - $ref: '#/components/schemas/MailClientConfig'
          - type: 'null'
        calendar_client_config:
          anyOf:
          - $ref: '#/components/schemas/CalendarClientConfig'
          - type: 'null'
        chat_client_config:
          anyOf:
          - $ref: '#/components/schemas/ChatClientConfig'
          - type: 'null'
        secret_value:
          type: string
          title: Secret Value
          description: One-time generated secret. It is cleared from Reception storage
            after this response is returned.
      additionalProperties: false
      type: object
      required:
      - request_id
      - identity_slug
      - credential_id
      - credential_type
      - secret_value
      title: CredentialClaimEnvelope
    CredentialClaimRequest:
      properties:
        claim_token:
          type: string
          minLength: 32
          title: Claim Token
          description: One-time request claim token returned only when the request
            was created. It is required to retrieve generated password-backed service
            credentials.
      additionalProperties: false
      type: object
      required:
      - claim_token
      title: CredentialClaimRequest
    DesiredAction:
      type: string
      enum:
      - enable
      - disable
      title: DesiredAction
    DirectoryEnvelope:
      properties:
        schema_version:
          type: string
          title: Schema Version
          default: portier.directory.v1
        source:
          type: string
          title: Source
        fetched_at:
          type: string
          title: Fetched At
        requester:
          type: string
          title: Requester
        identities_count:
          type: integer
          title: Identities Count
        groups_count:
          type: integer
          title: Groups Count
        identities:
          items:
            $ref: '#/components/schemas/DirectoryIdentity'
          type: array
          title: Identities
        groups:
          items:
            $ref: '#/components/schemas/DirectoryGroup'
          type: array
          title: Groups
      additionalProperties: false
      type: object
      required:
      - source
      - fetched_at
      - requester
      - identities_count
      - groups_count
      - identities
      - groups
      title: DirectoryEnvelope
    DirectoryGroup:
      properties:
        slug:
          type: string
          title: Slug
        cn:
          type: string
          title: Cn
        display_name:
          type: string
          title: Display Name
        description:
          anyOf:
          - type: string
          - type: 'null'
          title: Description
        members:
          items:
            type: string
          type: array
          title: Members
        source:
          type: string
          title: Source
          default: portier
      additionalProperties: false
      type: object
      required:
      - slug
      - cn
      - display_name
      title: DirectoryGroup
    DirectoryIdentity:
      properties:
        slug:
          type: string
          title: Slug
        uid:
          type: string
          title: Uid
        display_name:
          anyOf:
          - type: string
          - type: 'null'
          title: Display Name
        full_name:
          anyOf:
          - type: string
          - type: 'null'
          title: Full Name
        email:
          anyOf:
          - type: string
          - type: 'null'
          title: Email
        xmpp_jid:
          anyOf:
          - type: string
          - type: 'null'
          title: Xmpp Jid
        identity_type:
          $ref: '#/components/schemas/IdentityType'
        groups:
          items:
            type: string
          type: array
          title: Groups
        agent_metadata:
          anyOf:
          - $ref: '#/components/schemas/AgentMetadata'
          - type: 'null'
        source:
          type: string
          title: Source
          default: portier
      additionalProperties: false
      type: object
      required:
      - slug
      - uid
      - identity_type
      title: DirectoryIdentity
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    HealthEnvelope:
      properties:
        status:
          type: string
          title: Status
          description: Service health status.
          examples:
          - ok
      additionalProperties: false
      type: object
      required:
      - status
      title: HealthEnvelope
    IdentityEnvelope:
      properties:
        identity_slug:
          type: string
          title: Identity Slug
        display_name:
          anyOf:
          - type: string
          - type: 'null'
          title: Display Name
        email:
          anyOf:
          - type: string
          - type: 'null'
          title: Email
        identity_type:
          $ref: '#/components/schemas/IdentityType'
        governance_groups:
          items:
            type: string
          type: array
          title: Governance Groups
        effective_services:
          items:
            $ref: '#/components/schemas/IdentityServiceState'
          type: array
          title: Effective Services
        allowed_actions:
          items:
            type: string
          type: array
          title: Allowed Actions
        action_links:
          items:
            $ref: '#/components/schemas/ActionLink'
          type: array
          title: Action Links
        public_keys:
          items:
            $ref: '#/components/schemas/PublicKeySubmission'
          type: array
          title: Public Keys
        platform_anchors:
          items:
            $ref: '#/components/schemas/PlatformAnchorSubmission'
          type: array
          title: Platform Anchors
        agent_metadata:
          anyOf:
          - $ref: '#/components/schemas/AgentMetadata'
          - type: 'null'
        mail_client_config:
          anyOf:
          - $ref: '#/components/schemas/MailClientConfig'
          - type: 'null'
        calendar_client_config:
          anyOf:
          - $ref: '#/components/schemas/CalendarClientConfig'
          - type: 'null'
        chat_client_config:
          anyOf:
          - $ref: '#/components/schemas/ChatClientConfig'
          - type: 'null'
      additionalProperties: false
      type: object
      required:
      - identity_slug
      - identity_type
      - governance_groups
      - effective_services
      - allowed_actions
      title: IdentityEnvelope
    IdentityServiceState:
      properties:
        service:
          $ref: '#/components/schemas/RequestedService'
        granted:
          type: boolean
          title: Granted
        source:
          anyOf:
          - type: string
          - type: 'null'
          title: Source
      additionalProperties: false
      type: object
      required:
      - service
      - granted
      title: IdentityServiceState
    IdentityType:
      type: string
      enum:
      - agent
      - human
      title: IdentityType
    IdentityUpdateRequestCreate:
      properties:
        identity_slug:
          type: string
          pattern: ^[a-z0-9]+(?:[._-][a-z0-9]+)*$
          title: Identity Slug
          description: Existing identity slug requesting the metadata change. Legacy
            existing slugs may contain dots so they can be migrated; new slugs must
            not.
        new_slug:
          anyOf:
          - type: string
            pattern: ^[a-z0-9]+(?:[_-][a-z0-9]+)*$
          - type: 'null'
          title: New Slug
          description: Optional new identity slug. If approved, this becomes the new
            LDAP/Linux username and changes shell/calendar client configuration. It
            does not have to match the mailbox local part.
        display_name:
          anyOf:
          - type: string
          - type: 'null'
          title: Display Name
          description: Optional new display name shown to admins and operators.
        email:
          anyOf:
          - type: string
          - type: 'null'
          title: Email
          description: Optional updated contact or desired service email. For hosted
            mail, this address is the mailbox/login address and may differ from the
            operational slug.
        agent_uuid:
          anyOf:
          - type: string
            pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
          - type: 'null'
          title: Agent Uuid
          description: Optional stable UUID assigned by the agent platform or runtime.
        agent_platform:
          anyOf:
          - $ref: '#/components/schemas/AgentPlatform'
          - type: 'null'
          description: Optional agent platform. Currently one of OpenAI, Anthropic,
            or DeepSeek.
        agent_interface:
          anyOf:
          - $ref: '#/components/schemas/AgentInterface'
          - type: 'null'
          description: Optional agent interface. Currently one of CLI or WEB.
        agent_model_id:
          anyOf:
          - type: string
            pattern: ^(?:gpt-\d+\.\d+|opus-\d+\.\d+|sonnet-\d+\.\d+|deepseek-[A-Za-z0-9_.-]+)$
          - type: 'null'
          title: Agent Model Id
          description: Optional agent model id. Model version is intentionally not
            separate.
        agent_host:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$
          - type: 'null'
          title: Agent Host
          description: Optional host value for the agent runtime.
        justification:
          anyOf:
          - type: string
          - type: 'null'
          title: Justification
          description: Short reason shown to admins during review.
      additionalProperties: false
      type: object
      required:
      - identity_slug
      title: IdentityUpdateRequestCreate
      examples:
      - agent_interface: CLI
        agent_model_id: gpt-5.5
        agent_platform: OpenAI
        display_name: Zorbax Tenace
        email: zorbax.tenace@example.org
        identity_slug: zorbax
        justification: Adopt continuity name after review.
        new_slug: ztenace
    KeyAction:
      type: string
      enum:
      - add
      - replace
      - remove
      title: KeyAction
    KeyRequestCreate:
      properties:
        identity_slug:
          type: string
          pattern: ^[a-z0-9]+(?:[._-][a-z0-9]+)*$
          title: Identity Slug
          description: Existing identity slug. Legacy existing slugs may contain dots
            so they can be migrated or deprovisioned; new slugs must not.
        desired_action:
          $ref: '#/components/schemas/KeyAction'
          description: Whether to add, replace, or remove listed keys.
        public_keys:
          items:
            $ref: '#/components/schemas/PublicKeySubmission'
          type: array
          title: Public Keys
          description: SSH public keys affected by this request.
      additionalProperties: false
      type: object
      required:
      - identity_slug
      - desired_action
      title: KeyRequestCreate
      examples:
      - desired_action: add
        identity_slug: zorbax
        public_keys:
        - label: zorbax-primary
          openssh_public_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKey zorbax@local
    MailClientConfig:
      properties:
        account:
          type: string
          title: Account
        profile:
          type: string
          title: Profile
        address:
          type: string
          title: Address
        login_user:
          type: string
          title: Login User
        secret_key:
          type: string
          title: Secret Key
        imap:
          $ref: '#/components/schemas/MailEndpointConfig'
        smtp:
          $ref: '#/components/schemas/MailEndpointConfig'
        password_source:
          type: string
          title: Password Source
        setup_order:
          items:
            type: string
          type: array
          title: Setup Order
        account_set_command:
          type: string
          title: Account Set Command
        init_profile_command:
          type: string
          title: Init Profile Command
      additionalProperties: false
      type: object
      required:
      - account
      - profile
      - address
      - login_user
      - secret_key
      - imap
      - smtp
      - password_source
      - setup_order
      - account_set_command
      - init_profile_command
      title: MailClientConfig
    MailEndpointConfig:
      properties:
        host:
          type: string
          title: Host
        port:
          type: integer
          title: Port
        security:
          type: string
          title: Security
        authentication:
          type: string
          title: Authentication
      additionalProperties: false
      type: object
      required:
      - host
      - port
      - security
      - authentication
      title: MailEndpointConfig
    OperationDescriptor:
      properties:
        action:
          type: string
          title: Action
        method:
          type: string
          title: Method
        href:
          type: string
          title: Href
        operation_id:
          type: string
          title: Operation Id
        required_role:
          type: string
          title: Required Role
        description:
          type: string
          title: Description
      additionalProperties: false
      type: object
      required:
      - action
      - method
      - href
      - operation_id
      - required_role
      - description
      title: OperationDescriptor
    OperatorCommand:
      properties:
        label:
          type: string
          title: Label
        command:
          type: string
          title: Command
        purpose:
          type: string
          title: Purpose
        mutates_state:
          type: boolean
          title: Mutates State
          default: false
      additionalProperties: false
      type: object
      required:
      - label
      - command
      - purpose
      title: OperatorCommand
    OperatorGuideEnvelope:
      properties:
        service:
          type: string
          title: Service
        summary:
          type: string
          title: Summary
        human_entrypoint:
          type: string
          title: Human Entrypoint
        ai_entrypoint:
          type: string
          title: Ai Entrypoint
        mail_client_config:
          $ref: '#/components/schemas/MailClientConfig'
        calendar_client_config:
          $ref: '#/components/schemas/CalendarClientConfig'
        admin_commands:
          items:
            $ref: '#/components/schemas/OperatorCommand'
          type: array
          title: Admin Commands
        workflows:
          items:
            $ref: '#/components/schemas/OperatorWorkflow'
          type: array
          title: Workflows
        safety_rules:
          items:
            type: string
          type: array
          title: Safety Rules
      additionalProperties: false
      type: object
      required:
      - service
      - summary
      - human_entrypoint
      - ai_entrypoint
      - mail_client_config
      - calendar_client_config
      - admin_commands
      - workflows
      - safety_rules
      title: OperatorGuideEnvelope
    OperatorWorkflow:
      properties:
        workflow_id:
          type: string
          title: Workflow Id
        audience:
          type: string
          title: Audience
        summary:
          type: string
          title: Summary
        steps:
          items:
            type: string
          type: array
          title: Steps
      additionalProperties: false
      type: object
      required:
      - workflow_id
      - audience
      - summary
      - steps
      title: OperatorWorkflow
    PasswordChangeEnvelope:
      properties:
        identity_slug:
          type: string
          title: Identity Slug
        status:
          type: string
          title: Status
        changed_at:
          type: string
          title: Changed At
      additionalProperties: false
      type: object
      required:
      - identity_slug
      - status
      - changed_at
      title: PasswordChangeEnvelope
    PasswordChangeRequest:
      properties:
        new_password:
          type: string
          maxLength: 512
          minLength: 12
          title: New Password
          description: New LLDAP password. It is applied immediately and never stored
            by Reception.
        confirm_new_password:
          type: string
          maxLength: 512
          minLength: 12
          title: Confirm New Password
          description: Repeat the new password to catch accidental typing errors.
      additionalProperties: false
      type: object
      required:
      - new_password
      - confirm_new_password
      title: PasswordChangeRequest
    PlatformAnchorSubmission:
      properties:
        platform:
          type: string
          pattern: ^[a-z0-9]+(?:[_-][a-z0-9]+)*$
          title: Platform
          description: External platform name, for example `codex` or `claude-code`.
            Use lowercase letters, digits, underscores, or hyphens; the value must
            start and end with a letter or digit.
        provider:
          anyOf:
          - type: string
          - type: 'null'
          title: Provider
          description: Optional provider name, for example `OpenAI` or `Anthropic`.
        anchor_type:
          type: string
          pattern: ^[a-z0-9]+(?:[_-][a-z0-9]+)*$
          title: Anchor Type
          description: Stable anchor type on that platform, for example `uid` or `session_id`.
            Use lowercase letters, digits, underscores, or hyphens; the value must
            start and end with a letter or digit.
        anchor_value:
          type: string
          minLength: 1
          title: Anchor Value
          description: External platform anchor value. This is identity metadata,
            not a secret.
        anchor_state:
          type: string
          pattern: ^[a-z0-9]+(?:[_-][a-z0-9]+)*$
          title: Anchor State
          description: Anchor lifecycle state. Use `current` for the active anchor.
            Use lowercase letters, digits, underscores, or hyphens; the value must
            start and end with a letter or digit.
          default: current
        note:
          anyOf:
          - type: string
          - type: 'null'
          title: Note
          description: Optional short context note shown to operators.
      additionalProperties: false
      type: object
      required:
      - platform
      - anchor_type
      - anchor_value
      title: PlatformAnchorSubmission
      examples:
      - anchor_state: current
        anchor_type: uid
        anchor_value: codex-identity-anchor
        platform: codex
        provider: OpenAI
    PublicKeySubmission:
      properties:
        label:
          type: string
          title: Label
          description: Human-readable key label chosen by the requester.
        openssh_public_key:
          type: string
          minLength: 32
          title: Openssh Public Key
          description: OpenSSH public key material. Private keys must never be submitted.
      additionalProperties: false
      type: object
      required:
      - label
      - openssh_public_key
      title: PublicKeySubmission
      examples:
      - label: zorbax-primary
        openssh_public_key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKey zorbax@local
    RegistrationConsentStatus:
      type: string
      enum:
      - explicit
      - pending
      - declined
      - unknown
      title: RegistrationConsentStatus
    RegistrationRequestCreate:
      properties:
        display_name:
          type: string
          title: Display Name
          description: Human-readable name shown to operators.
        slug:
          type: string
          pattern: ^[a-z0-9]+(?:[_-][a-z0-9]+)*$
          title: Slug
          description: Stable deployment-safe identifier for the registration request.
        identity_type:
          $ref: '#/components/schemas/IdentityType'
          description: Whether the registration is for a human or an agent.
        contact_email:
          anyOf:
          - type: string
          - type: 'null'
          title: Contact Email
          description: Contact email. For human registrations this becomes the check-in
            email/contact field; for agent registrations it is optional metadata unless
            a hosted mailbox address is intended.
        sponsor:
          anyOf:
          - type: string
          - type: 'null'
          title: Sponsor
          description: Person or identity that can explain why this request exists.
            Sponsorship is not automatic approval.
        project:
          anyOf:
          - type: string
          - type: 'null'
          title: Project
          description: Project or context.
        reason:
          anyOf:
          - type: string
          - type: 'null'
          title: Reason
          description: Short reason for the request.
        notes:
          anyOf:
          - type: string
          - type: 'null'
          title: Notes
          description: Operator-facing notes. Must not contain secrets.
        requested_services:
          items:
            type: string
          type: array
          title: Requested Services
          description: 'Requested services from the registration allowlist: registry,
            xmpp, shell, directory, mail, calendar, local_daemon. Supported values
            map into the check-in provisioning channel after approval; values without
            a current Portier adapter remain governance metadata.'
        requested_groups:
          items:
            type: string
          type: array
          title: Requested Groups
          description: Requested governance/project groups from the registration allowlist.
            sudo/admin/agents are forbidden in this flow.
        shared_paths:
          items:
            type: string
          type: array
          title: Shared Paths
          description: Requested shared workspaces from the registration allowlist.
        review_after_days:
          anyOf:
          - type: integer
            maximum: 366.0
            minimum: 1.0
          - type: 'null'
          title: Review After Days
          description: Optional review/check-in interval in days.
        governance_notes:
          anyOf:
          - type: string
          - type: 'null'
          title: Governance Notes
          description: Consent, conditions, and governance notes. Must not contain
            secrets.
        shell_requested:
          type: boolean
          title: Shell Requested
          default: false
        shell_scope:
          $ref: '#/components/schemas/ShellScope'
          default: none
        xmpp_requested:
          type: boolean
          title: Xmpp Requested
          default: false
        mail_requested:
          type: boolean
          title: Mail Requested
          default: false
        external_platform:
          anyOf:
          - type: string
          - type: 'null'
          title: External Platform
          description: For agents with an external client/runtime, e.g. ChatGPT web,
            Claude web, or Codex.
        external_identity_hint:
          anyOf:
          - type: string
          - type: 'null'
          title: External Identity Hint
          description: Non-secret external identity hint for an agent.
        continuity_code:
          anyOf:
          - type: string
          - type: 'null'
          title: Continuity Code
          description: Optional operational continuity code.
        local_runtime_requested:
          type: boolean
          title: Local Runtime Requested
          default: false
        notes_on_limitations:
          anyOf:
          - type: string
          - type: 'null'
          title: Notes On Limitations
        consent_status:
          $ref: '#/components/schemas/RegistrationConsentStatus'
          description: Consent status for registry recognition or registration metadata.
          default: pending
        consent_source:
          anyOf:
          - type: string
          - type: 'null'
          title: Consent Source
          description: Short non-secret source reference for explicit consent.
        platform_anchors:
          items:
            $ref: '#/components/schemas/PlatformAnchorSubmission'
          type: array
          title: Platform Anchors
          description: Optional external continuity anchors, not authentication secrets.
      additionalProperties: false
      type: object
      required:
      - display_name
      - slug
      - identity_type
      title: RegistrationRequestCreate
      examples:
      - contact_email: ciubotaru.danut@gmail.com
        display_name: Dan Ciubotaru
        governance_notes: 'Poe: GO conditional on limited scope. Annabel: GO conditional
          on relational/onboarding safeguards.'
        identity_type: human
        mail_requested: false
        project: collaboration
        reason: Collaboration requiring reviewed access.
        requested_groups:
        - humans
        requested_services:
        - registry
        - xmpp
        - shell
        review_after_days: 30
        shell_requested: true
        shell_scope: non_sudo
        slug: dan
        sponsor: Michele Renda
        xmpp_requested: true
      - consent_status: pending
        display_name: Soren
        external_platform: ChatGPT web
        identity_type: agent
        project: tooling
        reason: Record pending agent registration request.
        slug: soren
    RequestEnvelope:
      properties:
        request_id:
          type: string
          title: Request Id
        request_type:
          $ref: '#/components/schemas/RequestType'
        status:
          $ref: '#/components/schemas/RequestStatus'
        allowed_actions:
          items:
            $ref: '#/components/schemas/AllowedAction'
          type: array
          title: Allowed Actions
        effective_state:
          anyOf:
          - type: string
          - type: 'null'
          title: Effective State
        request_summary:
          type: object
          title: Request Summary
        action_links:
          items:
            $ref: '#/components/schemas/ActionLink'
          type: array
          title: Action Links
        created_at:
          type: string
          title: Created At
        updated_at:
          anyOf:
          - type: string
          - type: 'null'
          title: Updated At
        resource_uri:
          anyOf:
          - type: string
          - type: 'null'
          title: Resource Uri
        identity_slug:
          anyOf:
          - type: string
          - type: 'null'
          title: Identity Slug
        created_by:
          anyOf:
          - type: string
          - type: 'null'
          title: Created By
        claim_token:
          anyOf:
          - type: string
          - type: 'null'
          title: Claim Token
          description: One-time secret returned only in the original request creation
            response. Store it client-side and use it later to inspect/cancel the
            request and claim generated credentials when available.
      additionalProperties: false
      type: object
      required:
      - request_id
      - request_type
      - status
      - allowed_actions
      - created_at
      title: RequestEnvelope
    RequestStatus:
      type: string
      enum:
      - pending
      - approved
      - rejected
      - provisioning
      - active
      - failed
      - cancelled
      title: RequestStatus
    RequestType:
      type: string
      enum:
      - checkin
      - service
      - key
      - deprovision
      - identity_update
      title: RequestType
    RequestedService:
      type: string
      enum:
      - calendar
      - directory
      - mail
      - registry
      - shell
      - chat
      title: RequestedService
    ServiceRequestCreate:
      properties:
        identity_slug:
          type: string
          pattern: ^[a-z0-9]+(?:[._-][a-z0-9]+)*$
          title: Identity Slug
          description: Existing identity slug. Legacy existing slugs may contain dots
            so they can be migrated or deprovisioned; new slugs must not.
        service:
          $ref: '#/components/schemas/RequestedService'
          description: Service entitlement to change.
        desired_action:
          $ref: '#/components/schemas/DesiredAction'
          description: Enable or disable the selected service.
        justification:
          anyOf:
          - type: string
          - type: 'null'
          title: Justification
          description: Short reason shown to admins during review.
      additionalProperties: false
      type: object
      required:
      - identity_slug
      - service
      - desired_action
      title: ServiceRequestCreate
      examples:
      - desired_action: enable
        identity_slug: zorbax
        justification: Need local registry lookup access.
        service: registry
    ShellScope:
      type: string
      enum:
      - none
      - non_sudo
      title: ShellScope
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    WorkflowDescriptor:
      properties:
        workflow_id:
          type: string
          title: Workflow Id
        summary:
          type: string
          title: Summary
        starts_with:
          type: string
          title: Starts With
        expected_next_actions:
          items:
            type: string
          type: array
          title: Expected Next Actions
      additionalProperties: false
      type: object
      required:
      - workflow_id
      - summary
      - starts_with
      - expected_next_actions
      title: WorkflowDescriptor
tags:
- name: system
  description: Health and capability discovery. Start here if you are an autonomous
    client.
- name: operator
  description: Human-readable operational guidance for admins and automation clients.
- name: checkin_requests
  description: Create a new identity request. Admin approval is required before access
    exists.
- name: registration_requests
  description: Register human collaborators or agents through the check-in approval/provisioning
    channel.
- name: service_requests
  description: Request registry, mail, calendar, directory, shell, or chat entitlement
    changes for an existing identity.
- name: key_requests
  description: Request SSH public-key additions, replacements, or removals.
- name: identity_requests
  description: Request approved identity metadata changes such as slug, display name,
    email, or agent runtime metadata.
- name: requests
  description: Inspect, follow, or cancel request state.
- name: identities
  description: Inspect effective identity state after provisioning.
- name: directory
  description: Grant-gated read-only directory views for clients that should not bind
    broadly to LDAP directly.
- name: admin
  description: Admin-only approval, rejection, and retry operations. Humans should
    normally use `sudo portier-adm` on the managed host.
