openapi: 3.0.1
info:
  title: Secfix Public API
  description: "Machine-to-machine API for the Secfix compliance platform. Authenticate\
    \ with the OAuth 2.0 client_credentials grant via POST /oauth/token, then call\
    \ /v1 endpoints with the bearer access token. Errors follow RFC 7807 (application/problem+json)\
    \ with stable code strings; lists use opaque cursor pagination."
  contact:
    name: Secfix Support
    url: https://secfix.com
    email: support@secfix.com
  license:
    name: Proprietary
    url: https://secfix.com/license
  version: 1.0.0
servers:
- url: https://api.secfix.com
  description: Production
security:
- bearerAuth: []
tags:
- name: Health
  description: Service liveness.
- name: Inventory
  description: List and govern assets across all categories.
- name: OAuth
  description: Token endpoint for OAuth 2.0 client-credentials authentication.
- name: Computers
  description: Read-only monitored computers with device compliance posture.
paths:
  /oauth/token:
    post:
      tags:
      - OAuth
      summary: Exchange client credentials for an access token.
      description: "OAuth 2.0 client_credentials grant. Send form-urlencoded grant_type=client_credentials,\
        \ client_id and client_secret. Returns a bearer access token for the Secfix\
        \ Public API audience."
      operationId: token
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/OAuthTokenRequest'
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessTokenResponse'
  /v1/computers:
    get:
      tags:
      - Computers
      summary: List monitored computers (cursor-paginated).
      description: Requires the computers:read scope.
      operationId: list_2
      parameters:
      - name: pageSize
        in: query
        required: false
        schema:
          type: integer
          format: int32
      - name: pageCursor
        in: query
        required: false
        schema:
          type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPageComputerDto'
  /v1/computers/{id}:
    get:
      tags:
      - Computers
      summary: Get one monitored computer by its public id.
      description: Requires the computers:read scope.
      operationId: get_1
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ComputerDto'
  /v1/health:
    get:
      tags:
      - Health
      summary: Liveness probe.
      description: Unauthenticated. Returns the service status and the API version.
      operationId: health
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthDto'
  /v1/inventory/assets:
    get:
      tags:
      - Inventory
      summary: "List assets (cursor-paginated, all categories)."
      description: "Requires the inventory:read scope. HIDDEN and soft-deleted assets\
        \ are excluded. Pass categoryKey to restrict to a single top-level category,\
        \ subKey to restrict to a single granular sub-type (e.g. a CLOUD sub-type),\
        \ hasOwner/hasDescription to filter on governance completeness, classification\
        \ to restrict to one data classification, and completeStatus (COMPLETE/INCOMPLETE)\
        \ as a friendly alias for hasOwner."
      operationId: list_1
      parameters:
      - name: pageSize
        in: query
        required: false
        schema:
          type: integer
          format: int32
      - name: pageCursor
        in: query
        required: false
        schema:
          type: string
      - name: categoryKey
        in: query
        description: Restrict to a single top-level inventory category. Omit for all
          categories.
        required: false
        schema:
          type: string
          enum:
          - CLOUD
          - COMPUTER
          - CUSTOM
          - INFORMATION
          - EMPLOYEE
      - name: subKey
        in: query
        description: Restrict to a single granular category sub-type (matches the
          key returned on AssetDto.categoryKey). Must be consistent with categoryKey
          when both are supplied.
        required: false
        schema:
          type: string
          enum:
          - CLOUD
          - CLOUD_AUTOSCALE_GROUPS
          - CLOUD_COMPUTE_INSTANCE
          - CLOUD_CONTAINER_REPOSITORY
          - CLOUD_DATA_WAREHOUSE
          - CLOUD_LOAD_BALANCER
          - CLOUD_NO_SQL_DATABASE
          - CLOUD_PAAS_APPS
          - CLOUD_QUEUE
          - CLOUD_RELATIONAL_DATABASE
          - CLOUD_STORAGE_BUCKET
          - CLOUD_OTHER
          - COMPUTER
          - CUSTOM
          - INFORMATION
          - EMPLOYEE
      - name: hasOwner
        in: query
        description: Filter by whether the asset has an owner assigned. Omit to not
          filter.
        required: false
        schema:
          type: boolean
      - name: hasDescription
        in: query
        description: Filter by whether the asset has a governance description. Omit
          to not filter.
        required: false
        schema:
          type: boolean
      - name: classification
        in: query
        description: Restrict to a single data classification. Omit to not filter.
        required: false
        schema:
          type: string
          enum:
          - CONFIDENTIAL
          - INTERNAL
          - PUBLIC
          - UNKNOWN
      - name: completeStatus
        in: query
        description: "Filter by governance completeness (a friendly alias for hasOwner):\
          \ COMPLETE when an owner is assigned, else INCOMPLETE. Omit to not filter."
        required: false
        schema:
          type: string
          enum:
          - COMPLETE
          - INCOMPLETE
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPageAssetDto'
    patch:
      tags:
      - Inventory
      summary: Bulk-update governance metadata on many assets.
      description: Requires the inventory:write scope. Tags are not supported in bulk;
        employee ids are rejected with no partial apply.
      operationId: bulkUpdate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkAssetMetadataPatchRequest'
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkUpdateSummaryDto'
  /v1/inventory/assets/{id}:
    get:
      tags:
      - Inventory
      summary: Get one asset by its public id.
      description: Requires the inventory:read scope.
      operationId: get
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetDto'
    patch:
      tags:
      - Inventory
      summary: Update governance metadata (and tags) on one asset.
      description: Requires the inventory:write scope. Governance fields only; employee
        rows are read-only.
      operationId: update
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssetMetadataPatchRequest'
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssetDto'
  /v1/inventory/categories:
    get:
      tags:
      - Inventory
      summary: List asset categories (cursor-paginated).
      description: Requires the inventory:read scope.
      operationId: list
      parameters:
      - name: pageSize
        in: query
        required: false
        schema:
          type: integer
          format: int32
      - name: pageCursor
        in: query
        required: false
        schema:
          type: string
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CursorPageAssetCategoryDto'
components:
  schemas:
    AccessTokenResponse:
      type: object
      properties:
        access_token:
          type: string
          description: The signed RS256 bearer access token.
          example: eyJhbGciOiJSUzI1NiIsImtpZCI6...
        expires_in:
          type: integer
          description: Token lifetime in seconds.
          format: int64
          example: 86400
        token_type:
          type: string
          description: Always "Bearer".
          example: Bearer
      description: OAuth 2.0 client-credentials token response.
    AssetCategoryDto:
      type: object
      properties:
        displayLabel:
          type: string
          description: Human-readable category label.
          example: Cloud
        key:
          type: string
          description: Stable asset category key.
          example: CLOUD
      description: Asset category. key is the stable category identifier.
    AssetDto:
      type: object
      properties:
        accountId:
          type: string
          description: Cloud account id (CLOUD assets).
          example: "123456789012"
        categoryKey:
          type: string
          description: Asset category key.
          example: CLOUD
          enum:
          - CLOUD
          - COMPUTER
          - CUSTOM
          - INFORMATION
          - EMPLOYEE
        classification:
          type: string
          description: Data classification.
          example: CONFIDENTIAL
        completeStatus:
          type: string
          description: "Read-only completeness status. COMPLETE when an owner is assigned,\
            \ else INCOMPLETE. Applies to all categories."
          readOnly: true
          example: COMPLETE
          enum:
          - COMPLETE
          - INCOMPLETE
        createdAt:
          type: string
          description: Creation timestamp (UTC).
          format: date-time
          example: 2026-01-15T09:30:00Z
        dataStored:
          $ref: '#/components/schemas/DataStoredDto'
        description:
          type: string
          description: Governance description.
          example: Primary production web server.
        email:
          type: string
          description: "Employee email - PII, surfaced under inventory:read (EMPLOYEE\
            \ assets)."
          example: jane.doe@example.com
        externalId:
          type: string
          description: Identifier of the asset in its source system.
          example: i-0abc123def456
        id:
          type: string
          description: Opaque public asset id (UUID).
          format: uuid
          example: 3f1c9a2e-8b4d-4e7a-9c1f-2a5b6c7d8e9f
        lastCheckedAt:
          type: string
          description: "Timestamp of the last compliance check (UTC), where applicable."
          format: date-time
          example: 2026-06-30T02:00:00Z
        name:
          type: string
          description: Asset display name.
          example: prod-web-01
        osVersion:
          type: string
          description: "Operating system family and version, combined (COMPUTER assets)."
          example: macOS 14.5
        ownerId:
          type: string
          description: Owner's employee UUID.
          format: uuid
          example: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d
        ownerSource:
          type: string
          description: Origin of the owner assignment.
          example: MANUAL
        region:
          type: string
          description: Cloud region/location (CLOUD assets).
          example: eu-central-1
        serialNumber:
          type: string
          description: Hardware serial number (COMPUTER assets).
          example: C02XY1234ABC
        tags:
          type: array
          description: Structured tags on the asset.
          items:
            $ref: '#/components/schemas/TagDto'
        type:
          type: string
          description: Asset type within its category.
          example: SERVER
      description: Public asset. The id is an opaque public reference (never the internal
        PK); for EMPLOYEE-category rows it is the stable employee UUID. Category-specific
        fields are populated only for their owning category; completeStatus is read-only.
    AssetMetadataPatchRequest:
      type: object
      properties:
        classification:
          type: string
          description: Data classification.
          example: CONFIDENTIAL
        description:
          maxLength: 500
          minLength: 0
          type: string
          description: Governance description (max 500 chars).
          example: Primary production web server.
        ownerId:
          type: string
          description: New owner's employee UUID.
          format: uuid
          example: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d
        tags:
          maxItems: 20
          minItems: 0
          type: array
          description: Tags to set (single-asset PATCH only; not supported in bulk).
            Diffed add/remove against existing customer tag keys; an unknown key is
            rejected.
          items:
            $ref: '#/components/schemas/TagDto'
      description: "Governance-only metadata update. Governance fields only - no name,\
        \ device facts, status, create or delete."
    BulkAssetMetadataPatchRequest:
      required:
      - ids
      - patch
      type: object
      properties:
        ids:
          maxItems: 100
          minItems: 1
          type: array
          description: Public asset ids to update (1 to 100).
          items:
            type: string
            description: Public asset ids to update (1 to 100).
            format: uuid
        patch:
          $ref: '#/components/schemas/AssetMetadataPatchRequest'
      description: Bulk governance update. Applies patch to every id. tags are not
        supported in bulk (a non-null patch.tags is rejected). Employee ids are rejected
        with no partial apply.
    BulkUpdateSummaryDto:
      type: object
      properties:
        failedUpdates:
          type: integer
          description: Number of assets that could not be updated.
          format: int32
          example: 2
        successfulUpdates:
          type: integer
          description: Number of assets successfully updated.
          format: int32
          example: 18
      description: Summary of a bulk governance update. The updated assets are not
        returned.
    CompliancePostureDto:
      type: object
      properties:
        agentVersion:
          type: string
          description: "Version of the monitoring agent, if present."
          example: 3.4.1
        antivirusInstalled:
          type: boolean
          description: Whether antivirus is installed.
          example: true
        diskEncryptionEnabled:
          type: boolean
          description: Whether disk encryption is enabled.
          example: true
        passwordManagerInstalled:
          type: boolean
          description: Whether a password manager is installed.
          example: false
        screenLockEnabled:
          type: boolean
          description: Whether screen lock is enabled.
          example: true
      description: Aggregate device compliance posture (Vanta Monitored-Computers
        parity).
    ComputerDto:
      type: object
      properties:
        compliance:
          $ref: '#/components/schemas/CompliancePostureDto'
        id:
          type: string
          description: Opaque public computer id (UUID).
          format: uuid
          example: 7c2d1e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f
        isMonitored:
          type: boolean
          description: Whether the device is monitored (computed from agent/MDM presence).
          example: true
        lastCheckedAt:
          type: string
          description: Timestamp of the last device check-in (UTC).
          format: date-time
          example: 2026-06-30T02:00:00Z
        name:
          type: string
          description: Computer name / hostname.
          example: MacBook-Pro-Jane
        operatingSystem:
          type: string
          description: Operating system family.
          example: macOS
        osVersion:
          type: string
          description: Operating system version.
          example: "14.5"
        ownerId:
          type: string
          description: Owner's employee UUID.
          format: uuid
          example: a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d
        serialNumber:
          type: string
          description: Hardware serial number.
          example: C02XG2JMJGH7
        tags:
          type: array
          description: Structured tags on the computer.
          items:
            $ref: '#/components/schemas/TagDto'
      description: "Monitored computer with aggregate compliance posture. Read-only\
        \ in v1 (governance PATCH targets /v1/inventory/assets/{id})."
    CursorPageAssetCategoryDto:
      type: object
      properties:
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
        results:
          type: array
          description: The page of results.
          items:
            $ref: '#/components/schemas/AssetCategoryDto'
      description: Standard cursor-paginated list envelope.
    CursorPageAssetDto:
      type: object
      properties:
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
        results:
          type: array
          description: The page of results.
          items:
            $ref: '#/components/schemas/AssetDto'
      description: Standard cursor-paginated list envelope.
    CursorPageComputerDto:
      type: object
      properties:
        pageInfo:
          $ref: '#/components/schemas/PageInfo'
        results:
          type: array
          description: The page of results.
          items:
            $ref: '#/components/schemas/ComputerDto'
      description: Standard cursor-paginated list envelope.
    DataStoredDto:
      type: object
      properties:
        containsPatientData:
          type: boolean
          description: Whether the asset contains patient data.
          example: false
        containsUserData:
          type: boolean
          description: Whether the asset contains user data.
          example: true
        userDataInfo:
          type: string
          description: Free-text descriptor of the user data contained in the asset.
          example: Customer contact records
      description: User/patient-data flags for INFORMATION/CUSTOM assets. Read-only.
    HealthDto:
      type: object
      properties:
        status:
          type: string
          description: Liveness status. Always "ok" when the service is serving requests.
          example: ok
        version:
          type: string
          description: Public API version.
          example: 1.0.0
      description: Service liveness status.
    OAuthTokenRequest:
      required:
      - client_id
      - client_secret
      - grant_type
      type: object
      properties:
        audience:
          type: string
          description: Target API audience. Optional - omit it and the Secfix Public
            API audience is used. Supplying any other value is rejected with 400 unsupported_audience.
        client_id:
          type: string
          description: The application's client id.
          example: aB3xY7...
        client_secret:
          type: string
          description: The application's client secret.
          example: s3cr3t...
        grant_type:
          type: string
          description: OAuth 2.0 grant type.
          example: client_credentials
          enum:
          - client_credentials
      description: OAuth 2.0 client-credentials token request (form-urlencoded).
    PageInfo:
      type: object
      properties:
        endCursor:
          type: string
          description: Opaque cursor for the next page (pass as pageCursor). Null
            when there are no more results.
          example: eyJjIjoiMjAyNi0wNi0zMFQwMjowMDowMFoiLCJyIjoiM2YxYzlhMmUifQ..
        hasNextPage:
          type: boolean
          description: Whether more results are available after this page.
          example: true
        totalCount:
          type: integer
          description: Total number of results matching the request across all pages
            (not just this page).
          format: int64
          example: 137
      description: Cursor-pagination metadata.
    TagDto:
      type: object
      properties:
        key:
          maxLength: 1000
          minLength: 0
          type: string
          description: Tag key (an existing customer tag definition).
          example: environment
        value:
          maxLength: 255
          minLength: 0
          type: string
          description: Tag value.
          example: production
      description: "Structured asset tag. On writes, key must match an existing customer\
        \ tag key; value is read-only in v1."
  securitySchemes:
    bearerAuth:
      type: http
      description: Bearer access token obtained from /oauth/token.
      scheme: bearer
      bearerFormat: JWT
    oauth2ClientCredentials:
      type: oauth2
      description: OAuth 2.0 client-credentials grant via /oauth/token.
      flows:
        clientCredentials:
          tokenUrl: /oauth/token
          scopes:
            all:read: Read access to every resource.
            all:write: Write access to every resource.
            computers:read: Read monitored computers and device posture.
            frameworks:read: Read compliance frameworks.
            inventory:read: Read the asset inventory.
            inventory:write: Update asset governance metadata.
