openapi: 3.1.0
info:
  title: MITRITY IAG Platform API
  description: Intent-Aware Governance API for managing tenants, users, agents, policies, and audit events.
  version: 0.1.0
  contact:
    name: MITRITY
    url: https://mitrity.com

servers:
  - url: https://api.mitrity.com/api/v1
    description: Production

security:
  - BearerAuth: []

tags:
  - name: Auth
    description: Authentication
  - name: Tenants
    description: Tenant (organization) management
  - name: Users
    description: User management within a tenant
  - name: Agents
    description: AI agent registration and management
  - name: Policies
    description: Intent policy CRUD
  - name: Audit
    description: Audit log queries
  - name: Approvals
    description: Human-in-the-loop approval queue
  - name: Sentinels
    description: Sentinel registration and management
  - name: Notifications
    description: Notification preferences
  - name: Tools
    description: Tool definitions and permission boundaries
  - name: DLP
    description: Data Loss Prevention — destination allowlists and DLP events
  - name: InjectionDetection
    description: Prompt injection detection events and false positive management
  - name: DelegationChains
    description: Agent-to-agent delegation chain tracking and governance
  - name: Credentials
    description: Credential definitions, grants, and lease management
  - name: Simulations
    description: Policy simulation — replay historical events against proposed policy changes
  - name: Reports
    description: Compliance reporting — SOC 2, GDPR, ISO 27001, executive summaries
  - name: ThreatIntelligence
    description: Shared threat indicator feed — tenant-scoped matches and settings

paths:
  # ===========================================================================
  # AUTH
  # ===========================================================================
  /auth/login:
    post:
      tags: [Auth]
      summary: Login and resolve tenant context
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [firebase_token]
              properties:
                firebase_token:
                  type: string
      responses:
        "200":
          description: Login successful
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          description: MFA required but not completed

  # ===========================================================================
  # USERS
  # ===========================================================================
  /users/me:
    get:
      tags: [Users]
      summary: Get current user profile
      responses:
        "200":
          description: Current user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
    patch:
      tags: [Users]
      summary: Update current user profile
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                display_name:
                  type: string
                mfa_method:
                  type: string
                  enum: [email, totp]
      responses:
        "200":
          description: Updated user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /users:
    get:
      tags: [Users]
      summary: List users in current tenant
      parameters:
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: User list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserList"

  /users/{user_id}:
    patch:
      tags: [Users]
      summary: Update a user's role
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role:
                  type: string
                  enum: [admin, editor, viewer]
      responses:
        "200":
          description: Updated user
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
    delete:
      tags: [Users]
      summary: Remove a user from the tenant
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: User removed

  /users/{user_id}/reset-mfa:
    post:
      tags: [Users]
      summary: Reset MFA for a user (admin/owner only)
      description: |
        Resets the user's MFA enrollment, reverting them to email-based 2FA.
        The user must re-enroll MFA on their next login.
        Owner can reset anyone. Admin can reset editors and viewers only.
      parameters:
        - name: user_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: MFA reset successful. User will need to re-enroll on next login.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: MFA has been reset. User will re-enroll on next login.
        "403":
          description: Insufficient permissions to reset this user's MFA

  # ===========================================================================
  # TENANTS
  # ===========================================================================
  /tenants/current:
    get:
      tags: [Tenants]
      summary: Get current tenant details
      responses:
        "200":
          description: Tenant details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Tenant"
    patch:
      tags: [Tenants]
      summary: Update tenant settings
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                saml_entity_id:
                  type: string
                saml_sso_url:
                  type: string
                saml_certificate:
                  type: string
      responses:
        "200":
          description: Updated tenant
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Tenant"

  /tenants/current/invites:
    post:
      tags: [Tenants]
      summary: Invite a user to the tenant
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, role]
              properties:
                email:
                  type: string
                  format: email
                role:
                  type: string
                  enum: [admin, editor, viewer]
      responses:
        "201":
          description: Invite sent

  # ===========================================================================
  # AGENTS
  # ===========================================================================
  /agents:
    get:
      tags: [Agents]
      summary: List registered agents
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [registered, active, suspended, archived]
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Agent list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentList"
    post:
      tags: [Agents]
      summary: Register a new agent
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgentCreate"
      responses:
        "201":
          description: Agent created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"

  /agents/{agent_id}:
    get:
      tags: [Agents]
      summary: Get agent details
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Agent details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
    patch:
      tags: [Agents]
      summary: Update an agent
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgentUpdate"
      responses:
        "200":
          description: Updated agent
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Agent"
    delete:
      tags: [Agents]
      summary: Archive an agent
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Agent archived

  # ===========================================================================
  # INTENT POLICIES
  # ===========================================================================
  /policies:
    get:
      tags: [Policies]
      summary: List intent policies
      parameters:
        - name: agent_id
          in: query
          schema:
            type: string
            format: uuid
          description: Filter by agent
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Policy list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyList"
    post:
      tags: [Policies]
      summary: Create an intent policy
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyCreate"
      responses:
        "201":
          description: Policy created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Policy"

  /policies/{policy_id}:
    get:
      tags: [Policies]
      summary: Get policy details
      parameters:
        - name: policy_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Policy details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Policy"
    patch:
      tags: [Policies]
      summary: Update a policy
      parameters:
        - name: policy_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyUpdate"
      responses:
        "200":
          description: Updated policy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Policy"
    delete:
      tags: [Policies]
      summary: Delete a policy
      parameters:
        - name: policy_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Policy deleted

  # ===========================================================================
  # AUDIT
  # ===========================================================================
  /audit:
    get:
      tags: [Audit]
      summary: Query audit events
      parameters:
        - name: agent_id
          in: query
          schema:
            type: string
            format: uuid
        - name: event_type
          in: query
          schema:
            type: string
        - name: decision
          in: query
          schema:
            type: string
            enum: [allowed, blocked, alerted, held, timed_out]
        - name: from
          in: query
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          schema:
            type: string
            format: date-time
        - name: min_drift_score
          in: query
          schema:
            type: number
            format: float
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Audit events
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuditEventList"

  /audit/summary:
    get:
      tags: [Audit]
      summary: Get audit summary statistics
      parameters:
        - name: from
          in: query
          required: true
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          required: true
          schema:
            type: string
            format: date-time
      responses:
        "200":
          description: Audit summary
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_events:
                    type: integer
                  blocked_count:
                    type: integer
                  alerted_count:
                    type: integer
                  allowed_count:
                    type: integer
                  avg_drift_score:
                    type: number
                    format: float
                  top_drifting_agents:
                    type: array
                    items:
                      type: object
                      properties:
                        agent_id:
                          type: string
                          format: uuid
                        agent_name:
                          type: string
                        avg_drift_score:
                          type: number
                          format: float
                        event_count:
                          type: integer

  # ===========================================================================
  # APPROVALS (Human-in-the-Loop)
  # ===========================================================================
  /approvals:
    get:
      tags: [Approvals]
      summary: List approval requests
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [pending, approved, denied, timed_out]
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Approval list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApprovalList"

  /approvals/count:
    get:
      tags: [Approvals]
      summary: Get count of pending approvals
      responses:
        "200":
          description: Pending approval count
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer

  /approvals/{approval_id}:
    get:
      tags: [Approvals]
      summary: Get approval details
      parameters:
        - name: approval_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Approval details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Approval"
        "404":
          $ref: "#/components/responses/NotFound"

  /approvals/{approval_id}/approve:
    post:
      tags: [Approvals]
      summary: Approve a pending request (admin/owner only)
      parameters:
        - name: approval_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                note:
                  type: string
                  description: Optional note explaining the decision
      responses:
        "200":
          description: Approval resolved
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Approval"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          description: Approval already resolved

  /approvals/{approval_id}/deny:
    post:
      tags: [Approvals]
      summary: Deny a pending request (admin/owner only)
      parameters:
        - name: approval_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                note:
                  type: string
                  description: Optional note explaining the decision
      responses:
        "200":
          description: Approval resolved
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Approval"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          description: Approval already resolved

  # ===========================================================================
  # SENTINELS
  # ===========================================================================
  /sentinels:
    get:
      tags: [Sentinels]
      summary: List sentinel instances
      responses:
        "200":
          description: Sentinel list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SentinelList"
    post:
      tags: [Sentinels]
      summary: Register a new sentinel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, environment]
              properties:
                name:
                  type: string
                environment:
                  type: string
                  enum: [aws, azure, gcp, on-prem]
                region:
                  type: string
      responses:
        "201":
          description: Sentinel registered. Returns the one-time API key.
          content:
            application/json:
              schema:
                type: object
                properties:
                  sentinel:
                    $ref: "#/components/schemas/Sentinel"
                  api_key:
                    type: string
                    description: One-time display. Store securely.

  /sentinels/{sentinel_id}:
    delete:
      tags: [Sentinels]
      summary: Revoke a sentinel
      parameters:
        - name: sentinel_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Sentinel revoked

  # ===========================================================================
  # NOTIFICATIONS
  # ===========================================================================
  /notifications/preferences:
    get:
      tags: [Notifications]
      summary: Get notification preferences
      responses:
        "200":
          description: Preferences
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationPreferences"
    put:
      tags: [Notifications]
      summary: Update notification preferences
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NotificationPreferences"
      responses:
        "200":
          description: Updated preferences
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationPreferences"

  /notifications/user-preferences:
    get:
      tags: [Notifications]
      summary: Get per-user notification preferences
      responses:
        "200":
          description: User preferences
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserNotificationPreferences"
    put:
      tags: [Notifications]
      summary: Update per-user notification preferences
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateUserNotificationPreferencesRequest"
      responses:
        "200":
          description: Updated user preferences
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserNotificationPreferences"

  # ===========================================================================
  # WEBHOOK DESTINATIONS (SIEM / Splunk Forwarding)
  # ===========================================================================
  /webhooks:
    get:
      tags: [Notifications]
      summary: List webhook destinations
      responses:
        "200":
          description: Webhook destination list
          content:
            application/json:
              schema:
                type: object
                properties:
                  destinations:
                    type: array
                    items:
                      $ref: "#/components/schemas/WebhookDestination"
    post:
      tags: [Notifications]
      summary: Create a webhook destination (Splunk HEC, syslog, custom)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookDestinationCreate"
      responses:
        "201":
          description: Webhook destination created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDestination"

  /webhooks/{webhook_id}:
    patch:
      tags: [Notifications]
      summary: Update a webhook destination
      parameters:
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebhookDestinationCreate"
      responses:
        "200":
          description: Updated webhook destination
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookDestination"
    delete:
      tags: [Notifications]
      summary: Delete a webhook destination
      parameters:
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Webhook destination deleted

  /webhooks/{webhook_id}/test:
    post:
      tags: [Notifications]
      summary: Send a test event to a webhook destination
      parameters:
        - name: webhook_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Test event sent successfully
        "502":
          description: Destination unreachable or returned error

  # ===========================================================================
  # TOOLS (Phase B: C2)
  # ===========================================================================
  /tools:
    get:
      tags: [Tools]
      summary: List tool definitions for the tenant
      description: Returns built-in and custom tool definitions.
      responses:
        "200":
          description: List of tool definitions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ToolDefinition"
    post:
      tags: [Tools]
      summary: Create a custom tool definition
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateToolDefinitionRequest"
      responses:
        "201":
          description: Tool definition created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ToolDefinition"

  /tools/{tool_id}:
    get:
      tags: [Tools]
      summary: Get a tool definition
      parameters:
        - name: tool_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Tool definition
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ToolDefinition"
    patch:
      tags: [Tools]
      summary: Update a custom tool definition
      parameters:
        - name: tool_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateToolDefinitionRequest"
      responses:
        "200":
          description: Tool definition updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ToolDefinition"
    delete:
      tags: [Tools]
      summary: Delete a custom tool definition
      description: Only custom (non-built-in) tools can be deleted.
      parameters:
        - name: tool_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Tool definition deleted

  /agents/{agent_id}/permissions:
    get:
      tags: [Tools]
      summary: List tool permissions for an agent
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: List of tool permissions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ToolPermission"
    put:
      tags: [Tools]
      summary: Bulk set tool permissions for an agent
      description: Replaces all tool permissions for the agent. Upserts each entry.
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/SetToolPermissionRequest"
      responses:
        "200":
          description: Tool permissions updated
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ToolPermission"

  # ===========================================================================
  # DLP — Destination Allowlists & Events (Phase B: C4)
  # ===========================================================================
  /agents/{agent_id}/destinations:
    get:
      tags: [DLP]
      summary: List destination allowlist entries for an agent
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Destination allowlist entries
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DestinationAllowlistEntry"
    post:
      tags: [DLP]
      summary: Add a destination to the agent's allowlist
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [domain_pattern]
              properties:
                domain_pattern:
                  type: string
                  description: "Glob pattern, e.g. '*.internal.company.com'"
      responses:
        "201":
          description: Destination added
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DestinationAllowlistEntry"

  /agents/{agent_id}/destinations/{destination_id}:
    delete:
      tags: [DLP]
      summary: Remove a destination from the agent's allowlist
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: destination_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Destination removed

  # ===========================================================================
  # Prompt Injection Detection (Phase C: C3)
  # ===========================================================================
  /injection-events:
    get:
      tags: [InjectionDetection]
      summary: List injection detection events
      parameters:
        - name: agent_id
          in: query
          schema:
            type: string
            format: uuid
          description: Filter by agent ID
        - name: detection_method
          in: query
          schema:
            type: string
            enum: [pattern, statistical, ml_classifier, combined]
          description: Filter by detection method
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Injection events
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/InjectionEvent"

  /injection-events/summary:
    get:
      tags: [InjectionDetection]
      summary: Get injection event summary statistics
      responses:
        "200":
          description: Aggregated injection event statistics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InjectionEventSummary"

  /injection-events/{id}:
    get:
      tags: [InjectionDetection]
      summary: Get a single injection event
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Injection event details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InjectionEvent"
        "404":
          $ref: "#/components/responses/NotFound"

  /injection-events/{id}/false-positive:
    post:
      tags: [InjectionDetection]
      summary: Mark an injection event as a false positive
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Event marked as false positive
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InjectionEvent"
        "404":
          $ref: "#/components/responses/NotFound"

  # ===========================================================================
  # DELEGATION CHAINS (Phase C: C5)
  # ===========================================================================
  /delegation-chains:
    get:
      tags: [DelegationChains]
      summary: List delegation chains
      parameters:
        - name: agent_id
          in: query
          schema:
            type: string
            format: uuid
          description: Filter by agent ID (any hop in chain)
        - name: status
          in: query
          schema:
            type: string
            enum: [active, completed, blocked, timed_out]
          description: Filter by chain status
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Delegation chains
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DelegationChain"

  /delegation-chains/summary:
    get:
      tags: [DelegationChains]
      summary: Get delegation chain summary statistics
      responses:
        "200":
          description: Aggregated delegation statistics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DelegationSummary"

  /delegation-chains/{chain_id}:
    get:
      tags: [DelegationChains]
      summary: Get a delegation chain with all hops
      parameters:
        - name: chain_id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Delegation chain with hops
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DelegationChainDetail"
        "404":
          $ref: "#/components/responses/NotFound"

  # ===========================================================================
  # CREDENTIALS (Phase D: C7)
  # ===========================================================================
  /credentials:
    get:
      tags: [Credentials]
      summary: List credential definitions
      parameters:
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Credential definitions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CredentialDefinition"
    post:
      tags: [Credentials]
      summary: Create a credential definition
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCredentialRequest"
      responses:
        "201":
          description: Credential created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialDefinition"
        "400":
          $ref: "#/components/responses/BadRequest"

  /credentials/{id}:
    get:
      tags: [Credentials]
      summary: Get a credential definition
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Credential details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialDefinition"
        "404":
          $ref: "#/components/responses/NotFound"
    patch:
      tags: [Credentials]
      summary: Update a credential definition
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateCredentialRequest"
      responses:
        "200":
          description: Credential updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialDefinition"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      tags: [Credentials]
      summary: Delete a credential definition
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: Credential deleted
        "404":
          $ref: "#/components/responses/NotFound"

  /credentials/{id}/grants:
    get:
      tags: [Credentials]
      summary: List grants for a credential
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Credential grants
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CredentialGrant"
    put:
      tags: [Credentials]
      summary: Set grants for a credential (replaces all grants)
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [grants]
              properties:
                grants:
                  type: array
                  items:
                    $ref: "#/components/schemas/CreateCredentialGrantRequest"
      responses:
        "200":
          description: Grants updated
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CredentialGrant"

  /credentials/{id}/leases:
    get:
      tags: [Credentials]
      summary: List lease history for a credential
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          schema:
            type: string
            enum: [active, expired, revoked]
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Credential leases
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CredentialLease"

  /credentials/{credential_id}/leases/{lease_id}/revoke:
    post:
      tags: [Credentials]
      summary: Revoke an active credential lease
      parameters:
        - name: credential_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: lease_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lease revoked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CredentialLease"
        "404":
          $ref: "#/components/responses/NotFound"

  # ===========================================================================
  # POLICY SIMULATIONS (Phase D: C8)
  # ===========================================================================
  /simulations:
    get:
      tags: [Simulations]
      summary: List policy simulations
      parameters:
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Policy simulations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/PolicySimulation"
    post:
      tags: [Simulations]
      summary: Run a policy simulation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateSimulationRequest"
      responses:
        "201":
          description: Simulation created and started
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicySimulation"
        "400":
          $ref: "#/components/responses/BadRequest"

  /simulations/{id}:
    get:
      tags: [Simulations]
      summary: Get simulation results
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Simulation with results
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicySimulation"
        "404":
          $ref: "#/components/responses/NotFound"

  # ===========================================================================
  # COMPLIANCE REPORTS (Phase D: C9)
  # ===========================================================================
  /reports:
    get:
      tags: [Reports]
      summary: List compliance reports
      parameters:
        - name: report_type
          in: query
          schema:
            type: string
            enum: [soc2, gdpr, iso27001, executive, inventory]
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: Compliance reports
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ComplianceReport"

  /reports/generate:
    post:
      tags: [Reports]
      summary: Generate a compliance report
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GenerateReportRequest"
      responses:
        "201":
          description: Report generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ComplianceReport"
        "400":
          $ref: "#/components/responses/BadRequest"

  /reports/{id}:
    get:
      tags: [Reports]
      summary: Get a compliance report
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Report data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ComplianceReport"
        "404":
          $ref: "#/components/responses/NotFound"

  /reports/{id}/download:
    get:
      tags: [Reports]
      summary: Download report as PDF
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: PDF file
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        "404":
          $ref: "#/components/responses/NotFound"

  # ===========================================================================
  # THREAT INTELLIGENCE (Phase E: C10)
  # ===========================================================================
  /threat-intelligence:
    get:
      tags: [ThreatIntelligence]
      summary: List threat indicators from subscribed feeds
      description: Returns indicators from feeds this tenant subscribes to. Indicators contain NO tenant-specific data.
      parameters:
        - name: indicator_type
          in: query
          schema:
            type: string
            enum: [action_pattern, behavioral_hash, injection_signature, tool_abuse_pattern, delegation_pattern]
        - name: severity
          in: query
          schema:
            type: string
            enum: [critical, high, medium, low, info]
        - name: feed
          in: query
          schema:
            type: string
            enum: [mitrity_curated, platform_generated, community]
      responses:
        "200":
          description: List of threat indicators
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ThreatIndicator"

  /threat-intelligence/{id}:
    get:
      tags: [ThreatIntelligence]
      summary: Get a single threat indicator
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Threat indicator details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ThreatIndicator"
        "404":
          $ref: "#/components/responses/NotFound"

  /threat-intelligence/matches:
    get:
      tags: [ThreatIntelligence]
      summary: List threat matches for this tenant
      description: Returns matches where this tenant's agent actions hit threat indicators. Fully tenant-scoped.
      parameters:
        - name: agent_id
          in: query
          schema:
            type: string
            format: uuid
        - name: severity
          in: query
          schema:
            type: string
            enum: [critical, high, medium, low, info]
        - name: indicator_type
          in: query
          schema:
            type: string
            enum: [action_pattern, behavioral_hash, injection_signature, tool_abuse_pattern, delegation_pattern]
        - $ref: "#/components/parameters/PageSize"
        - $ref: "#/components/parameters/PageToken"
      responses:
        "200":
          description: List of threat matches
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ThreatMatch"

  /threat-intelligence/matches/summary:
    get:
      tags: [ThreatIntelligence]
      summary: Threat match summary statistics
      description: Aggregated stats by severity, type, and action for this tenant.
      responses:
        "200":
          description: Threat match summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ThreatMatchSummary"

  /threat-intelligence/settings:
    get:
      tags: [ThreatIntelligence]
      summary: Get tenant threat intelligence settings
      description: Returns the tenant's feed subscriptions, contribution opt-in status, and default action.
      responses:
        "200":
          description: Tenant threat settings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TenantThreatSettings"
    put:
      tags: [ThreatIntelligence]
      summary: Update tenant threat intelligence settings
      description: Update feed subscriptions, opt-in contribution, and default action for threat matches.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateThreatSettingsRequest"
      responses:
        "200":
          description: Updated settings
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TenantThreatSettings"

# =============================================================================
# COMPONENTS
# =============================================================================
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Firebase ID Token

  parameters:
    PageSize:
      name: page_size
      in: query
      schema:
        type: integer
        default: 20
        maximum: 100
    PageToken:
      name: page_token
      in: query
      schema:
        type: string
      description: Opaque cursor for next page

  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Forbidden:
      description: Insufficient permissions
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"

  schemas:
    Error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
        message:
          type: string
        details:
          type: object

    AuthResponse:
      type: object
      properties:
        user:
          $ref: "#/components/schemas/User"
        tenant:
          $ref: "#/components/schemas/Tenant"

    Tenant:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        slug:
          type: string
        plan:
          type: string
          enum: [starter, pro, enterprise]
        billing_interval:
          type: string
          enum: [monthly, yearly]
        subscription_status:
          type: string
        max_agents:
          type: integer
        max_users:
          type: integer
        max_policies:
          type: integer
        saml_enabled:
          type: boolean
        created_at:
          type: string
          format: date-time

    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        email:
          type: string
        display_name:
          type: string
        avatar_url:
          type: string
        role:
          type: string
          enum: [owner, admin, editor, viewer]
        mfa_method:
          type: string
          enum: [email, totp]
        mfa_enrolled:
          type: boolean
        auth_provider:
          type: string
          enum: [password, google, saml]
        last_login_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time

    UserList:
      type: object
      properties:
        users:
          type: array
          items:
            $ref: "#/components/schemas/User"
        next_page_token:
          type: string

    Agent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
        agent_type:
          type: string
        description:
          type: string
        mission_scope:
          type: string
        status:
          type: string
          enum: [registered, active, suspended, archived]
        enforcement_mode:
          type: string
          enum: [monitor, alert, enforce]
          default: monitor
          description: Controls how policy decisions are applied
        fail_mode:
          type: string
          enum: [open, closed]
          default: open
          description: Behavior when sentinel cannot reach control plane
        sentinel_id:
          type: string
        last_heartbeat:
          type: string
          format: date-time
        metadata:
          type: object
        created_at:
          type: string
          format: date-time

    AgentCreate:
      type: object
      required: [name, mission_scope]
      properties:
        name:
          type: string
        agent_type:
          type: string
          default: custom
        description:
          type: string
        mission_scope:
          type: string
        enforcement_mode:
          type: string
          enum: [monitor, alert, enforce]
          default: monitor
        fail_mode:
          type: string
          enum: [open, closed]
          default: open
        metadata:
          type: object

    AgentUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        mission_scope:
          type: string
        status:
          type: string
          enum: [active, suspended, archived]
        enforcement_mode:
          type: string
          enum: [monitor, alert, enforce]
        fail_mode:
          type: string
          enum: [open, closed]
        metadata:
          type: object

    AgentList:
      type: object
      properties:
        agents:
          type: array
          items:
            $ref: "#/components/schemas/Agent"
        next_page_token:
          type: string

    Policy:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: string
        agent_id:
          type: string
          format: uuid
        policy_type:
          type: string
          enum: [allow, deny, alert, hold]
        action_pattern:
          type: string
        constraints:
          type: object
        enabled:
          type: boolean
        priority:
          type: integer
        hold_timeout_minutes:
          type: integer
          default: 30
          description: Timeout for hold-type policies (minutes)
        timeout_action:
          type: string
          enum: [deny, allow]
          default: deny
          description: Action when hold timeout expires
        notify_channels:
          type: array
          items:
            type: string
            enum: [slack, email]
          description: Channels to notify on hold trigger
        created_at:
          type: string
          format: date-time

    PolicyCreate:
      type: object
      required: [name, policy_type, action_pattern]
      properties:
        name:
          type: string
        description:
          type: string
        agent_id:
          type: string
          format: uuid
        policy_type:
          type: string
          enum: [allow, deny, alert, hold]
        action_pattern:
          type: string
        constraints:
          type: object
        priority:
          type: integer
          default: 0
        hold_timeout_minutes:
          type: integer
          default: 30
        timeout_action:
          type: string
          enum: [deny, allow]
          default: deny
        notify_channels:
          type: array
          items:
            type: string
            enum: [slack, email]

    PolicyUpdate:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        policy_type:
          type: string
          enum: [allow, deny, alert, hold]
        action_pattern:
          type: string
        constraints:
          type: object
        enabled:
          type: boolean
        priority:
          type: integer
        hold_timeout_minutes:
          type: integer
        timeout_action:
          type: string
          enum: [deny, allow]
        notify_channels:
          type: array
          items:
            type: string
            enum: [slack, email]

    PolicyList:
      type: object
      properties:
        policies:
          type: array
          items:
            $ref: "#/components/schemas/Policy"
        next_page_token:
          type: string

    AuditEvent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        event_type:
          type: string
        agent_id:
          type: string
          format: uuid
        user_id:
          type: string
          format: uuid
        sentinel_id:
          type: string
        action:
          type: string
        mission_scope:
          type: string
        policy_id:
          type: string
          format: uuid
        decision:
          type: string
          enum: [allowed, blocked, alerted, held, timed_out]
        enforcement_mode:
          type: string
          enum: [monitor, alert, enforce]
        response_time_ms:
          type: integer
        behavioral_hash:
          type: string
        drift_score:
          type: number
          format: float
        metadata:
          type: object
        occurred_at:
          type: string
          format: date-time

    AuditEventList:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: "#/components/schemas/AuditEvent"
        next_page_token:
          type: string

    Sentinel:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        environment:
          type: string
        region:
          type: string
        version:
          type: string
        status:
          type: string
          enum: [registered, connected, disconnected, revoked]
        last_heartbeat:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time

    SentinelList:
      type: object
      properties:
        sentinels:
          type: array
          items:
            $ref: "#/components/schemas/Sentinel"

    NotificationPreferences:
      type: object
      properties:
        slack_webhook_url:
          type: string
        slack_channel:
          type: string
        slack_enabled:
          type: boolean
        email_recipients:
          type: array
          items:
            type: string
            format: email
        email_enabled:
          type: boolean
        notify_on_block:
          type: boolean
        notify_on_drift:
          type: boolean
        notify_on_sentinel_disconnect:
          type: boolean
        drift_score_threshold:
          type: number
          format: float

    UserNotificationPreferences:
      type: object
      properties:
        id:
          type: string
          format: uuid
        user_id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        notify_on_block:
          type: boolean
        notify_on_drift:
          type: boolean
        notify_on_sentinel_disconnect:
          type: boolean
        email_enabled:
          type: boolean
        weekly_report_enabled:
          type: boolean
        drift_score_threshold:
          type: number
          format: double
          description: "Drift score threshold for notifications (0.0-1.0)"
          default: 0.7
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    UpdateUserNotificationPreferencesRequest:
      type: object
      properties:
        notify_on_block:
          type: boolean
        notify_on_drift:
          type: boolean
        notify_on_sentinel_disconnect:
          type: boolean
        email_enabled:
          type: boolean
        weekly_report_enabled:
          type: boolean
        drift_score_threshold:
          type: number
          format: double
          description: "Drift score threshold for notifications (0.0-1.0)"
          default: 0.7

    WebhookDestination:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        destination_type:
          type: string
          enum: [splunk_hec, syslog_cef, webhook, custom]
        endpoint_url:
          type: string
        forward_blocked:
          type: boolean
        forward_alerted:
          type: boolean
        forward_allowed:
          type: boolean
        enabled:
          type: boolean
        last_sent_at:
          type: string
          format: date-time
        last_error:
          type: string
        created_at:
          type: string
          format: date-time

    WebhookDestinationCreate:
      type: object
      required: [name, destination_type, endpoint_url]
      properties:
        name:
          type: string
        destination_type:
          type: string
          enum: [splunk_hec, syslog_cef, webhook, custom]
        endpoint_url:
          type: string
        auth_header:
          type: string
          description: "e.g., 'Splunk <HEC_TOKEN>' or 'Bearer <token>'"
        forward_blocked:
          type: boolean
          default: true
        forward_alerted:
          type: boolean
          default: true
        forward_allowed:
          type: boolean
          default: false

    Approval:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        event_id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        agent_name:
          type: string
        action_type:
          type: string
        resource_pattern:
          type: string
        policy_id:
          type: string
          format: uuid
        policy_name:
          type: string
        drift_score:
          type: number
          format: float
        status:
          type: string
          enum: [pending, approved, denied, timed_out]
        timeout_at:
          type: string
          format: date-time
        resolved_by:
          type: string
          format: uuid
        resolved_at:
          type: string
          format: date-time
        resolution_note:
          type: string
        created_at:
          type: string
          format: date-time

    ApprovalList:
      type: object
      properties:
        approvals:
          type: array
          items:
            $ref: "#/components/schemas/Approval"
        next_page_token:
          type: string

    # =========================================================================
    # Tool Definitions & Permissions (Phase B: C2)
    # =========================================================================

    ToolDefinition:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          example: "AWS S3"
        category:
          type: string
          enum: [storage, database, messaging, llm, code_execution, code, network, custom]
        match_rules:
          $ref: "#/components/schemas/ToolMatchRules"
        operations:
          type: array
          items:
            type: string
          example: ["read", "write", "delete", "list"]
        scopes:
          type: array
          items:
            type: string
          example: ["bucket:*"]
          nullable: true
        is_builtin:
          type: boolean
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    ToolMatchRules:
      type: object
      required: [action_type_pattern]
      properties:
        action_type_pattern:
          type: string
          description: "Glob pattern to match action_type, e.g. 's3:*'"
        resource_pattern:
          type: string
          description: "Glob pattern to match resource, e.g. '*.slack.com/*'"

    CreateToolDefinitionRequest:
      type: object
      required: [name, category, match_rules, operations]
      properties:
        name:
          type: string
        category:
          type: string
          enum: [storage, database, messaging, llm, code_execution, code, network, custom]
        match_rules:
          $ref: "#/components/schemas/ToolMatchRules"
        operations:
          type: array
          items:
            type: string
        scopes:
          type: array
          items:
            type: string

    UpdateToolDefinitionRequest:
      type: object
      properties:
        name:
          type: string
        category:
          type: string
          enum: [storage, database, messaging, llm, code_execution, code, network, custom]
        match_rules:
          $ref: "#/components/schemas/ToolMatchRules"
        operations:
          type: array
          items:
            type: string
        scopes:
          type: array
          items:
            type: string

    TimeWindow:
      type: object
      properties:
        start:
          type: string
          example: "08:00"
        end:
          type: string
          example: "18:00"
        timezone:
          type: string
          example: "UTC"

    ToolPermission:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        tool_id:
          type: string
          format: uuid
        tool_name:
          type: string
        allowed_operations:
          type: array
          items:
            type: string
        allowed_scopes:
          type: array
          items:
            type: string
          nullable: true
        denied_scopes:
          type: array
          items:
            type: string
          nullable: true
        rate_limit_per_minute:
          type: integer
          nullable: true
        max_payload_bytes:
          type: integer
          format: int64
          nullable: true
        time_window:
          $ref: "#/components/schemas/TimeWindow"
          nullable: true
        enabled:
          type: boolean
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    SetToolPermissionRequest:
      type: object
      required: [tool_id, allowed_operations, enabled]
      properties:
        tool_id:
          type: string
          format: uuid
        allowed_operations:
          type: array
          items:
            type: string
        allowed_scopes:
          type: array
          items:
            type: string
        denied_scopes:
          type: array
          items:
            type: string
        rate_limit_per_minute:
          type: integer
        max_payload_bytes:
          type: integer
          format: int64
        time_window:
          $ref: "#/components/schemas/TimeWindow"
        enabled:
          type: boolean

    # =========================================================================
    # DLP (Phase B: C4)
    # =========================================================================

    DestinationAllowlistEntry:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        domain_pattern:
          type: string
          example: "*.internal.company.com"
        created_at:
          type: string
          format: date-time

    DLPEvent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        agent_name:
          type: string
        event_id:
          type: string
          format: uuid
          nullable: true
        direction:
          type: string
          enum: [inbound, outbound]
        sensitivity_tags:
          type: array
          items:
            type: string
          example: ["PII:email", "credentials:api_key"]
        destination_domain:
          type: string
          nullable: true
        action_taken:
          type: string
          enum: [blocked, alerted, logged]
        detection_reason:
          type: string
          enum: [sensitive_exfil, volume_anomaly, accumulation, unauthorized_destination]
        payload_size_bytes:
          type: integer
          format: int64
          nullable: true
        accumulated_reads:
          type: integer
          nullable: true
        occurred_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time

    # =========================================================================
    # Injection Detection (Phase C: C3)
    # =========================================================================

    InjectionEvent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        agent_name:
          type: string
        event_id:
          type: string
          format: uuid
          nullable: true
        detection_method:
          type: string
          enum: [pattern, statistical, ml_classifier, combined]
        injection_probability:
          type: number
          format: float
          minimum: 0.0
          maximum: 1.0
        matched_patterns:
          type: array
          items:
            type: string
          example: ["instruction_override", "system_prompt_injection"]
        flagged_content_hash:
          type: string
          description: SHA-256 hash of the flagged content (privacy-safe)
        action_taken:
          type: string
          enum: [blocked, alerted, logged]
        action_type:
          type: string
          description: The action type that was scanned (e.g. "llm:call", "mcp:tool")
        false_positive:
          type: boolean
          nullable: true
        occurred_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time

    InjectionEventSummary:
      type: object
      properties:
        total_events:
          type: integer
        blocked:
          type: integer
        alerted:
          type: integer
        by_method:
          type: object
          properties:
            pattern:
              type: integer
            statistical:
              type: integer
            ml_classifier:
              type: integer
            combined:
              type: integer
        by_agent:
          type: array
          items:
            type: object
            properties:
              agent_id:
                type: string
                format: uuid
              agent_name:
                type: string
              count:
                type: integer

    # =========================================================================
    # Delegation Chains (Phase C: C5)
    # =========================================================================

    DelegationChain:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        chain_id:
          type: string
        initiator_agent_id:
          type: string
          format: uuid
        initiator_agent_name:
          type: string
        chain_depth:
          type: integer
        status:
          type: string
          enum: [active, completed, blocked, timed_out]
        blocked_at_hop:
          type: integer
          nullable: true
        blocked_reason:
          type: string
          nullable: true
        started_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time

    DelegationChainDetail:
      allOf:
        - $ref: "#/components/schemas/DelegationChain"
        - type: object
          properties:
            hops:
              type: array
              items:
                $ref: "#/components/schemas/DelegationHop"

    DelegationHop:
      type: object
      properties:
        id:
          type: string
          format: uuid
        chain_id:
          type: string
        hop_index:
          type: integer
        from_agent_id:
          type: string
          format: uuid
          nullable: true
        from_agent_name:
          type: string
          nullable: true
        to_agent_id:
          type: string
          format: uuid
        to_agent_name:
          type: string
        action_requested:
          type: string
        decision:
          type: string
          enum: [allowed, blocked]
        effective_permissions:
          type: array
          items:
            type: string
          nullable: true
        occurred_at:
          type: string
          format: date-time

    DelegationSummary:
      type: object
      properties:
        total_chains:
          type: integer
        active_chains:
          type: integer
        blocked_chains:
          type: integer
        avg_chain_depth:
          type: number
          format: float
        by_reason:
          type: object
          properties:
            circular:
              type: integer
            depth_exceeded:
              type: integer
            privilege_escalation:
              type: integer
            fan_out:
              type: integer
        top_delegators:
          type: array
          items:
            type: object
            properties:
              agent_id:
                type: string
                format: uuid
              agent_name:
                type: string
              chain_count:
                type: integer

    # =========================================================================
    # Credentials (Phase D: C7)
    # =========================================================================

    CredentialDefinition:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
        credential_type:
          type: string
          enum: [api_key, oauth_token, db_password, service_account]
        store_type:
          type: string
          enum: [builtin, gcp_secret_manager, aws_secrets_manager, vault]
        store_reference:
          type: string
          nullable: true
        max_ttl_minutes:
          type: integer
        max_concurrent_leases:
          type: integer
        rotation_days:
          type: integer
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    CreateCredentialRequest:
      type: object
      required: [name, credential_type]
      properties:
        name:
          type: string
        credential_type:
          type: string
          enum: [api_key, oauth_token, db_password, service_account]
        store_type:
          type: string
          enum: [builtin, gcp_secret_manager, aws_secrets_manager, vault]
          default: builtin
        store_reference:
          type: string
          nullable: true
        credential_value:
          type: string
          description: The credential value (encrypted at rest, only for builtin store)
          writeOnly: true
        max_ttl_minutes:
          type: integer
          default: 60
        max_concurrent_leases:
          type: integer
          default: 5
        rotation_days:
          type: integer
          nullable: true

    UpdateCredentialRequest:
      type: object
      properties:
        name:
          type: string
        credential_value:
          type: string
          writeOnly: true
        max_ttl_minutes:
          type: integer
        max_concurrent_leases:
          type: integer
        rotation_days:
          type: integer
          nullable: true

    CredentialGrant:
      type: object
      properties:
        id:
          type: string
          format: uuid
        credential_id:
          type: string
          format: uuid
        agent_id:
          type: string
          format: uuid
        agent_name:
          type: string
        allowed_operations:
          type: array
          items:
            type: string
          example: ["read", "write"]
        enabled:
          type: boolean
        created_at:
          type: string
          format: date-time

    CreateCredentialGrantRequest:
      type: object
      required: [agent_id]
      properties:
        agent_id:
          type: string
          format: uuid
        allowed_operations:
          type: array
          items:
            type: string
        enabled:
          type: boolean
          default: true

    CredentialLease:
      type: object
      properties:
        id:
          type: string
          format: uuid
        credential_id:
          type: string
          format: uuid
        credential_name:
          type: string
        agent_id:
          type: string
          format: uuid
        agent_name:
          type: string
        issued_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
        revoked_at:
          type: string
          format: date-time
          nullable: true
        revoke_reason:
          type: string
          nullable: true
        status:
          type: string
          enum: [active, expired, revoked]
        created_at:
          type: string
          format: date-time

    # =========================================================================
    # Policy Simulations (Phase D: C8)
    # =========================================================================

    PolicySimulation:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
        proposed_policies:
          type: array
          items:
            type: object
          description: Array of policy rule objects to simulate
        time_range_start:
          type: string
          format: date-time
        time_range_end:
          type: string
          format: date-time
        agent_filter:
          type: array
          items:
            type: string
            format: uuid
          nullable: true
        status:
          type: string
          enum: [pending, running, completed, failed]
        total_events_evaluated:
          type: integer
          nullable: true
        decisions_changed:
          type: integer
          nullable: true
        allow_to_block:
          type: integer
          nullable: true
        block_to_allow:
          type: integer
          nullable: true
        alert_changes:
          type: integer
          nullable: true
        result_details:
          type: object
          nullable: true
          description: Detailed per-event simulation results
        created_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
          nullable: true

    CreateSimulationRequest:
      type: object
      required: [name, proposed_policies, time_range_start, time_range_end]
      properties:
        name:
          type: string
        proposed_policies:
          type: array
          items:
            type: object
        time_range_start:
          type: string
          format: date-time
        time_range_end:
          type: string
          format: date-time
        agent_filter:
          type: array
          items:
            type: string
            format: uuid
          nullable: true

    # =========================================================================
    # Compliance Reports (Phase D: C9)
    # =========================================================================

    ComplianceReport:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        report_type:
          type: string
          enum: [soc2, gdpr, iso27001, executive, inventory]
        period_start:
          type: string
          format: date-time
          nullable: true
        period_end:
          type: string
          format: date-time
          nullable: true
        report_data:
          type: object
          description: Structured report content (varies by report type)
        pdf_url:
          type: string
          nullable: true
        generated_by:
          type: string
          format: uuid
          nullable: true
        generated_at:
          type: string
          format: date-time

    GenerateReportRequest:
      type: object
      required: [report_type]
      properties:
        report_type:
          type: string
          enum: [soc2, gdpr, iso27001, executive, inventory]
        period_start:
          type: string
          format: date-time
        period_end:
          type: string
          format: date-time

    # ── Threat Intelligence (Phase E: C10) ──────────────────────────────────

    ThreatIndicator:
      type: object
      description: A shared threat indicator. Contains NO tenant-specific data.
      properties:
        id:
          type: string
          format: uuid
        indicator_type:
          type: string
          enum: [action_pattern, behavioral_hash, injection_signature, tool_abuse_pattern, delegation_pattern]
        pattern:
          type: string
          description: Regex pattern or exact SHA-256 hash
        name:
          type: string
        description:
          type: string
          nullable: true
        severity:
          type: string
          enum: [critical, high, medium, low, info]
        feed:
          type: string
          enum: [mitrity_curated, platform_generated, community]
        enabled:
          type: boolean
        expires_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    ThreatMatch:
      type: object
      description: A tenant-scoped threat match — when an agent action hit a shared indicator.
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        indicator_id:
          type: string
          format: uuid
        indicator_name:
          type: string
        indicator_type:
          type: string
          enum: [action_pattern, behavioral_hash, injection_signature, tool_abuse_pattern, delegation_pattern]
        agent_id:
          type: string
          format: uuid
          nullable: true
        agent_name:
          type: string
          nullable: true
        event_id:
          type: string
          format: uuid
          nullable: true
        matched_value:
          type: string
        action_taken:
          type: string
          enum: [blocked, alerted, logged]
        severity:
          type: string
          enum: [critical, high, medium, low, info]
        occurred_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time

    ThreatMatchSummary:
      type: object
      properties:
        total_matches:
          type: integer
        by_severity:
          type: object
          additionalProperties:
            type: integer
        by_type:
          type: object
          additionalProperties:
            type: integer
        by_action:
          type: object
          additionalProperties:
            type: integer
        top_agents:
          type: array
          items:
            type: object
            properties:
              agent_id:
                type: string
                format: uuid
              agent_name:
                type: string
              match_count:
                type: integer

    TenantThreatSettings:
      type: object
      properties:
        contribute_data:
          type: boolean
          description: "Opt-in to contribute anonymized threat signals. Defaults to false."
        subscribed_feeds:
          type: array
          items:
            type: string
            enum: [mitrity_curated, platform_generated, community]
        default_action:
          type: string
          enum: [block, alert, log]
          description: Default action when an agent action matches a threat indicator

    UpdateThreatSettingsRequest:
      type: object
      required: [contribute_data, subscribed_feeds, default_action]
      properties:
        contribute_data:
          type: boolean
        subscribed_feeds:
          type: array
          items:
            type: string
            enum: [mitrity_curated, platform_generated, community]
        default_action:
          type: string
          enum: [block, alert, log]

