AdvisoryAI Chat Interface

Sprint: SPRINT_20260107_006_003 Task CH-016 Status: Active Last Updated: 2026-02-24

The AdvisoryAI Chat Interface provides a conversational experience for security operators to investigate vulnerabilities, understand findings, and take remediation actions—all grounded in internal evidence with citations.

Overview

The chat interface enables:

Controlled Gateway and Budgets

Sanctioned Tools (v1)


API Reference

Endpoint Families and Migration Timeline

Create Conversation

Creates a new conversation session.

Required headers: X-StellaOps-User, X-StellaOps-Client, and either X-StellaOps-Roles (chat:user or chat:admin) or X-StellaOps-Scopes (advisory-ai:view, advisory-ai:operate, advisory-ai:admin, plus legacy advisory:chat / advisory:run aliases).

POST /v1/advisory-ai/conversations
Content-Type: application/json
X-StellaOps-User: user-xyz
X-StellaOps-Roles: chat:user
X-StellaOps-Client: ui

{
  "tenantId": "tenant-123",
  "context": {
    "currentCveId": "CVE-2023-44487",
    "currentComponent": "pkg:npm/lodash@4.17.21",
    "currentImageDigest": "sha256:abc123",
    "scanId": "s-789",
    "sbomId": "sbom-123"
  },
  "metadata": {
    "source": "ui",
    "version": "1.0"
  }
}

Response:

{
  "conversationId": "conv-abc123",
  "tenantId": "tenant-123",
  "userId": "user-xyz",
  "createdAt": "2026-01-09T12:00:00Z",
  "updatedAt": "2026-01-09T12:00:00Z",
  "turns": []
}

Send Message (Streaming)

Sends a user message and streams the AI response.

POST /v1/advisory-ai/conversations/{conversationId}/turns
Content-Type: application/json
Accept: text/event-stream
X-StellaOps-User: user-xyz
X-StellaOps-Roles: chat:user
X-StellaOps-Client: ui

{
  "content": "Is CVE-2023-44487 exploitable in our environment?",
  "stream": true
}

content is the canonical add-turn payload field. A temporary compatibility shim still accepts legacy message input and maps it to content; empty/whitespace payloads return HTTP 400. Legacy message usage emits a warning header: Warning: 299 - Legacy chat payload field 'message' is deprecated; use 'content'.

Response (Server-Sent Events):

event: token
data: {"content": "Based on the reachability analysis "}

event: token
data: {"content": "[reach:api-gateway:grpc.Server], "}

event: citation
data: {"type": "reach", "path": "api-gateway:grpc.Server", "verified": true}

event: token
data: {"content": "this vulnerability **is reachable** in your environment."}

event: action
data: {"type": "approve", "label": "Accept Risk", "enabled": true, "parameters": {"cve_id": "CVE-2023-44487"}}

event: grounding
data: {"score": 0.92, "citations": 3, "claims": 2}

event: done
data: {"turnId": "turn-xyz", "groundingScore": 0.92}

Conversation add-turn responses now use the same grounded runtime path as the chat gateway. When runtime generation is unavailable, the service returns HTTP 503 with CHAT_RUNTIME_UNAVAILABLE; it does not create an assistant fallback turn, echo the user prompt, or return placeholder answer metadata.

Get Conversation

Retrieves a conversation with its history.

GET /v1/advisory-ai/conversations/{conversationId}
Authorization: Bearer <token>

Response:

{
  "conversationId": "conv-abc123",
  "tenantId": "tenant-123",
  "userId": "user-xyz",
  "createdAt": "2026-01-09T12:00:00Z",
  "updatedAt": "2026-01-09T12:05:00Z",
  "context": { ... },
  "turns": [
    {
      "turnId": "turn-001",
      "role": "user",
      "content": "Is CVE-2023-44487 exploitable?",
      "timestamp": "2026-01-09T12:01:00Z"
    },
    {
      "turnId": "turn-002",
      "role": "assistant",
      "content": "Based on the reachability analysis...",
      "timestamp": "2026-01-09T12:01:05Z",
      "evidenceLinks": [
        {"type": "reach", "uri": "reach://api-gateway:grpc.Server", "label": "Reachability trace"}
      ],
      "groundingScore": 0.92
    }
  ],
  "turnCount": 2
}

List Conversations

Lists conversations for a tenant/user.

GET /v1/advisory-ai/conversations?tenantId=tenant-123&userId=user-xyz&limit=20
Authorization: Bearer <token>

Delete Conversation

Deletes a conversation and its history.

DELETE /v1/advisory-ai/conversations/{conversationId}
Authorization: Bearer <token>

Chat Settings

Read or update chat quota/tool settings (defaults come from env).

GET /api/v1/chat/settings
PUT /api/v1/chat/settings?scope=tenant
DELETE /api/v1/chat/settings?scope=tenant

Chat Doctor

Returns quota and tool access status to diagnose limits.

GET /api/v1/chat/doctor

AI responses include object links that reference internal evidence. These links enable deep navigation to source data.

TypeFormatExampleDescription
SBOM[sbom:{id}][sbom:abc123]Link to SBOM document
Reachability[reach:{service}:{function}][reach:api-gateway:grpc.Server]Link to reachability trace
Runtime[runtime:{service}:traces][runtime:api-gateway:traces]Link to runtime traces
VEX[vex:{issuer}:{digest}][vex:stellaops:sha256:abc]Link to VEX statement
Attestation[attest:dsse:{digest}][attest:dsse:sha256:xyz]Link to DSSE attestation
Authority Key[auth:keys/{keyId}][auth:keys/gitlab-oidc]Link to signing key
Documentation[docs:{path}][docs:scopes/ci-webhook]Link to documentation
Finding[finding:{id}][finding:CVE-2024-12345]Link to finding detail
Scan[scan:{id}][scan:scan-2026-02-24-001]Link to scan detail
Policy[policy:{id}][policy:DENY-CRITICAL-PROD]Link to policy detail

Object links are validated by the grounding system:

The vulnerability **CVE-2023-44487** affects your deployment.

**Evidence:**
- The component is present in your SBOM [sbom:scan-2026-01-09-abc123]
- Reachability analysis shows the vulnerable function is called [reach:api-gateway:grpc.Server]
- No VEX statement currently exists for this product

**Recommendation:** Consider creating a VEX statement to document your assessment.

Action Types

The AI can propose actions that users can execute directly from the chat interface. Actions are permission-gated and require explicit confirmation.

Available Actions

ActionRequired RoleParametersDescription
approveapprovercve_id, rationale?, expiry?Accept risk for a vulnerability
quarantineoperatorimage_digestBlock an image from deployment
defertriagecve_id, assignee?Mark for later investigation
generate_manifestadminintegration_typeCreate integration manifest
create_vexissuerproduct, vulnerability, statusDraft VEX statement

Action Button Format

Actions appear in responses using this format:

[Action Label]{action:type,param1=value1,param2=value2}

Example:

You may want to accept this risk: [Accept Risk]{action:approve,cve_id=CVE-2023-44487,rationale=tested}

Action Execution Flow

  1. Parsing: ActionProposalParser extracts actions from model output
  2. Permission Check: User roles are validated against required role
  3. Policy Check: Tool lattice rules allow/deny the action in this context
  4. Display: Allowed actions render as buttons; blocked actions show disabled with reason
  5. Confirmation: User clicks button and confirms in modal
  6. Execution: Backend executes action with audit trail
  7. Result: Success/failure displayed in chat

Blocked Actions

When a user lacks permission for an action:

{
  "actionType": "approve",
  "label": "Accept Risk",
  "isAllowed": false,
  "blockedReason": "Requires 'approver' role. You have: viewer, triage"
}

Audit Log

Every chat session records an immutable audit trail:

Audit records live in Postgres with optional DSSE signatures for evidence export. The chat-audit tables (advisoryai.chat_sessions at line 27, chat_messages, chat_policy_decisions, chat_tool_invocations, chat_evidence_links) are created on startup by the single live migration src/AdvisoryAI/StellaOps.AdvisoryAI/Storage/Migrations/001_v1_advisoryai_baseline.sql — no manual psql step. (The pre-1.0 001_chat_audit.sql was folded into that baseline and is archived under Storage/Migrations/_archived/pre_1.0/mig061/, excluded from embedding.)


Grounding System

All AI responses are validated for proper grounding—ensuring claims are backed by evidence.

Grounding Score

The grounding score (0.0-1.0) measures response quality:

Score RangeQualityDescription
0.90-1.00ExcellentAll claims cited, all links valid
0.70-0.89GoodMost claims cited, minor issues
0.50-0.69AcceptableSome claims uncited
< 0.50RejectedResponse regenerated

Grounding Validation

The validator checks:

  1. Link Validity: Do object links resolve to real objects?
  2. Claim Grounding: Are security claims near valid citations?
  3. Citation Density: Are there enough citations for the response length?

Claim Detection

Claims requiring grounding include:

Grounding Issues

Issue TypeSeverityDescription
InvalidLinkErrorObject link does not resolve
UngroundedClaimWarningSecurity claim without nearby citation
BelowThresholdCriticalOverall score below minimum

Configuration

AdvisoryAI:
  Chat:
    Grounding:
      MinGroundingScore: 0.5      # Minimum acceptable score
      MaxLinkDistance: 200        # Max chars between claim and citation

Example Flows

Vulnerability Investigation

User: What is the status of CVE-2023-44487 in our environment?

Assistant: CVE-2023-44487 (HTTP/2 Rapid Reset) **is reachable** in your environment
[reach:api-gateway:grpc.Server].

**Status:** AFFECTED
- Component: grpc-go v1.56.0 [sbom:scan-abc123]
- Reachable path: api-gateway -> grpc.Server.handleStream()
- No VEX statement exists

**Recommended actions:**
[Accept Risk]{action:approve,cve_id=CVE-2023-44487}
[Create VEX]{action:create_vex,product=api-gateway,vulnerability=CVE-2023-44487,status=affected}

Action Execution

User: Please create a VEX statement marking CVE-2023-44487 as affected for api-gateway.

Assistant: I will create a VEX statement with the following details:

- **Product:** api-gateway
- **Vulnerability:** CVE-2023-44487
- **Status:** affected
- **Justification:** Vulnerable code is reachable

[Create VEX Statement]{action:create_vex,product=api-gateway,vulnerability=CVE-2023-44487,status=affected,justification=vulnerable_code_present}

Configuration

AdvisoryAI:
  Guardrails:
    EntropyThreshold: 3.5
    EntropyMinLength: 20
    AllowlistFile: "data/advisory-ai/allowlist.txt"
  Chat:
    ConversationRetention: '7.00:00:00'  # 7 days
    MaxTurnsPerConversation: 50
    TokenBudget: 8192
    StreamingEnabled: true
    Quotas:
      RequestsPerMinute: 60
      RequestsPerDay: 500
      TokensPerDay: 100000
      ToolCallsPerDay: 10000
    Tools:
      AllowAll: false
      AllowedTools:
        - "vex.query"
        - "sbom.read"
        - "scanner.findings.topk"
    Audit:
      Enabled: true
      ConnectionString: "Host=localhost;Database=stellaops;Username=stellaops;Password=changeme"
      SchemaName: "advisoryai"
      IncludeEvidenceBundle: false
      RetentionPeriod: '90.00:00:00'
    Grounding:
      MinGroundingScore: 0.5
      MaxLinkDistance: 200
    Actions:
      RequireConfirmation: true
      RequirePolicyAllow: true
      AuditAllExecutions: true

Error Handling

Status CodeErrorDescription
400InvalidRequestMalformed request body
401UnauthorizedMissing or invalid token
403ForbiddenInsufficient permissions
404ConversationNotFoundConversation does not exist
429RateLimitedToo many requests
500InternalErrorServer error

See Also