458 lines
14 KiB
Markdown
458 lines
14 KiB
Markdown
# 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:
|
|
- **Multi-turn conversations** about vulnerabilities, components, and security posture
|
|
- **Grounded responses** with citations to internal evidence (SBOMs, VEX, attestations)
|
|
- **Action proposals** for risk approval, quarantine, and VEX creation
|
|
- **Streaming responses** for real-time feedback
|
|
|
|
## Controlled Gateway and Budgets
|
|
- **Chat Gateway** enforces Authority auth, quotas, and token budgets per user/org.
|
|
- **Settings overrides**: quotas and tool allowlists are configurable via UI/CLI settings; env values are defaults.
|
|
- **Doctor action** reports quota/tool limits and last denial for troubleshooting.
|
|
- **Scrubber** removes secrets and PII using regex + entropy filters + allowlists.
|
|
- **Tool gating** runs policy checks before any tool invocation; read-only by default.
|
|
|
|
## Sanctioned Tools (v1)
|
|
- Read-only: `vex.query`, `sbom.read`, `scanner.findings.topk`.
|
|
- Action tools require explicit confirmation plus policy allow.
|
|
|
|
---
|
|
|
|
## API Reference
|
|
|
|
### Endpoint Families and Migration Timeline
|
|
|
|
- Canonical chat surface: `/api/v1/chat/*`
|
|
- Legacy compatibility surface: `/v1/advisory-ai/conversations*`
|
|
- Legacy sunset date (UTC): **December 31, 2026**
|
|
- Legacy responses emit migration headers:
|
|
- `Deprecation: true`
|
|
- `Sunset: Thu, 31 Dec 2026 23:59:59 GMT`
|
|
- `Link: </api/v1/chat/query>; rel="successor-version"`
|
|
|
|
### 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).
|
|
|
|
```http
|
|
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:**
|
|
```json
|
|
{
|
|
"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.
|
|
|
|
```http
|
|
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 an explicit deterministic fallback response with metadata (no placeholder responses).
|
|
|
|
### Get Conversation
|
|
|
|
Retrieves a conversation with its history.
|
|
|
|
```http
|
|
GET /v1/advisory-ai/conversations/{conversationId}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"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.
|
|
|
|
```http
|
|
GET /v1/advisory-ai/conversations?tenantId=tenant-123&userId=user-xyz&limit=20
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Delete Conversation
|
|
|
|
Deletes a conversation and its history.
|
|
|
|
```http
|
|
DELETE /v1/advisory-ai/conversations/{conversationId}
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Chat Settings
|
|
|
|
Read or update chat quota/tool settings (defaults come from env).
|
|
|
|
```http
|
|
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.
|
|
|
|
```http
|
|
GET /api/v1/chat/doctor
|
|
```
|
|
|
|
---
|
|
|
|
## Object Link Format
|
|
|
|
AI responses include object links that reference internal evidence. These links enable deep navigation to source data.
|
|
|
|
### Supported Link Types
|
|
|
|
| Type | Format | Example | Description |
|
|
|------|--------|---------|-------------|
|
|
| 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 |
|
|
|
|
### Link Resolution
|
|
|
|
Object links are validated by the grounding system:
|
|
- **Valid links** resolve to existing objects and render as clickable chips
|
|
- **Invalid links** are flagged as grounding issues and may lower the grounding score
|
|
- Links must be within `MaxLinkDistance` characters of related claims to count as grounding
|
|
|
|
### Example Response with Links
|
|
|
|
```markdown
|
|
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
|
|
|
|
| Action | Required Role | Parameters | Description |
|
|
|--------|---------------|------------|-------------|
|
|
| `approve` | `approver` | `cve_id`, `rationale?`, `expiry?` | Accept risk for a vulnerability |
|
|
| `quarantine` | `operator` | `image_digest` | Block an image from deployment |
|
|
| `defer` | `triage` | `cve_id`, `assignee?` | Mark for later investigation |
|
|
| `generate_manifest` | `admin` | `integration_type` | Create integration manifest |
|
|
| `create_vex` | `issuer` | `product`, `vulnerability`, `status` | Draft 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:
|
|
```json
|
|
{
|
|
"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:
|
|
- Prompt hash, redaction metadata, and model identifier
|
|
- Tool calls (inputs/outputs hashes) and policy decisions
|
|
- Evidence links surfaced in responses
|
|
- Action confirmations and results
|
|
|
|
Audit records live in Postgres with optional DSSE signatures for evidence export.
|
|
Apply `src/AdvisoryAI/StellaOps.AdvisoryAI/Storage/Migrations/001_chat_audit.sql`
|
|
to create the tables (adjust schema if needed).
|
|
|
|
---
|
|
|
|
## 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 Range | Quality | Description |
|
|
|-------------|---------|-------------|
|
|
| 0.90-1.00 | Excellent | All claims cited, all links valid |
|
|
| 0.70-0.89 | Good | Most claims cited, minor issues |
|
|
| 0.50-0.69 | Acceptable | Some claims uncited |
|
|
| < 0.50 | Rejected | Response 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:
|
|
- Vulnerability status: "is affected", "is not affected", "is vulnerable"
|
|
- Fix status: "has been fixed", "is patched", "is mitigated"
|
|
- Severity assessments: "CVSS score is 9.8", "severity is critical"
|
|
- Investigation status: "is under investigation"
|
|
|
|
### Grounding Issues
|
|
|
|
| Issue Type | Severity | Description |
|
|
|------------|----------|-------------|
|
|
| `InvalidLink` | Error | Object link does not resolve |
|
|
| `UngroundedClaim` | Warning | Security claim without nearby citation |
|
|
| `BelowThreshold` | Critical | Overall score below minimum |
|
|
|
|
### Configuration
|
|
|
|
```yaml
|
|
AdvisoryAI:
|
|
Chat:
|
|
Grounding:
|
|
MinGroundingScore: 0.5 # Minimum acceptable score
|
|
MaxLinkDistance: 200 # Max chars between claim and citation
|
|
```
|
|
|
|
---
|
|
|
|
## Example Flows
|
|
|
|
### Vulnerability Investigation
|
|
|
|
```text
|
|
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
|
|
|
|
```text
|
|
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
|
|
|
|
```yaml
|
|
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 Code | Error | Description |
|
|
|-------------|-------|-------------|
|
|
| 400 | InvalidRequest | Malformed request body |
|
|
| 401 | Unauthorized | Missing or invalid token |
|
|
| 403 | Forbidden | Insufficient permissions |
|
|
| 404 | ConversationNotFound | Conversation does not exist |
|
|
| 429 | RateLimited | Too many requests |
|
|
| 500 | InternalError | Server error |
|
|
|
|
---
|
|
|
|
## See Also
|
|
|
|
- [AdvisoryAI Architecture](architecture.md)
|
|
- [Deployment Guide](deployment.md)
|
|
- [Security Guardrails](/docs/security/assistant-guardrails.md)
|
|
- [Controlled Conversational Interface Advisory](../../../docs-archived/product/advisories/13-Jan-2026%20-%20Controlled%20Conversational%20Interface.md)
|