skillguard/lib/api-spec/openapi.yaml
Replit Agent 434ec07885 Add live progress updates and detailed scan checkpoints to scan results
Introduce streaming endpoint for NDJSON scan progress, incorporate scan checkpoints into scan details, and update UI components to display this new information.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 0d01f99a-ea6a-447d-82fd-311715434a39
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2852b526-3bf8-4a93-a62a-a50e26291074
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/e32d2b99-1721-47dd-833c-98b372f48008/0d01f99a-ea6a-447d-82fd-311715434a39/8MCgDZm
Replit-Helium-Checkpoint-Created: true
2026-06-10 18:53:17 +00:00

733 lines
17 KiB
YAML

openapi: 3.1.0
info:
# Do not change the title, if the title changes, the import paths will be broken
title: Api
version: 0.1.0
description: API specification
servers:
- url: /api
description: Base API path
tags:
- name: health
description: Health operations
- name: scans
description: Skill scans and audit reports
- name: providers
description: Configurable external AI providers
- name: prompts
description: Configurable AI analysis prompts
- name: rules
description: Static rule catalog configuration
- name: dashboard
description: Dashboard summaries
paths:
/healthz:
get:
operationId: healthCheck
tags: [health]
summary: Health check
description: Returns server health status
responses:
"200":
description: Healthy
content:
application/json:
schema:
$ref: "#/components/schemas/HealthStatus"
/dashboard:
get:
operationId: getDashboard
tags: [dashboard]
summary: Dashboard summary
description: Aggregated statistics across all scans.
responses:
"200":
description: Dashboard summary
content:
application/json:
schema:
$ref: "#/components/schemas/DashboardSummary"
/scans:
get:
operationId: listScans
tags: [scans]
summary: List scan history
responses:
"200":
description: List of scans (most recent first)
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Scan"
post:
operationId: createScan
tags: [scans]
summary: Upload a skill and run an audit
description: >-
Accepts a skill as a base64 ZIP archive, a single base64 file, or pasted
text, runs the static rule engine and (optionally) the configured AI
analysis, and returns the completed report.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SkillScanInput"
responses:
"201":
description: Completed scan report
content:
application/json:
schema:
$ref: "#/components/schemas/ScanDetail"
"400":
description: Invalid input
content:
application/json:
schema:
$ref: "#/components/schemas/ApiError"
/scans/{id}:
get:
operationId: getScan
tags: [scans]
summary: Get a scan report with findings
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: Scan report
content:
application/json:
schema:
$ref: "#/components/schemas/ScanDetail"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/ApiError"
delete:
operationId: deleteScan
tags: [scans]
summary: Delete a scan report
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"204":
description: Deleted
/providers:
get:
operationId: listProviders
tags: [providers]
summary: List configured AI providers
responses:
"200":
description: List of providers (tokens masked)
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/AiProvider"
post:
operationId: createProvider
tags: [providers]
summary: Create an AI provider
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AiProviderInput"
responses:
"201":
description: Created provider
content:
application/json:
schema:
$ref: "#/components/schemas/AiProvider"
/providers/{id}:
patch:
operationId: updateProvider
tags: [providers]
summary: Update an AI provider
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AiProviderUpdate"
responses:
"200":
description: Updated provider
content:
application/json:
schema:
$ref: "#/components/schemas/AiProvider"
delete:
operationId: deleteProvider
tags: [providers]
summary: Delete an AI provider
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"204":
description: Deleted
/providers/{id}/test:
post:
operationId: testProvider
tags: [providers]
summary: Test the connection to an AI provider
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"200":
description: Test result
content:
application/json:
schema:
$ref: "#/components/schemas/ProviderTestResult"
/prompts:
get:
operationId: listPrompts
tags: [prompts]
summary: List configurable AI prompts
responses:
"200":
description: List of prompts
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Prompt"
/prompts/{id}:
patch:
operationId: updatePrompt
tags: [prompts]
summary: Update an AI prompt
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PromptUpdate"
responses:
"200":
description: Updated prompt
content:
application/json:
schema:
$ref: "#/components/schemas/Prompt"
/rules:
get:
operationId: listRules
tags: [rules]
summary: List the static rule catalog
responses:
"200":
description: List of rules
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Rule"
/rules/{id}:
patch:
operationId: updateRule
tags: [rules]
summary: Update a rule's severity or enabled state
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/RuleUpdate"
responses:
"200":
description: Updated rule
content:
application/json:
schema:
$ref: "#/components/schemas/Rule"
components:
schemas:
HealthStatus:
type: object
properties:
status:
type: string
required:
- status
ApiError:
type: object
required: [error]
properties:
error:
type: string
SkillScanInput:
type: object
required: [source, useAi]
properties:
name:
type: ["string", "null"]
description: Optional display name for the scan
source:
type: string
enum: [zip, file, text]
useAi:
type: boolean
description: Whether to also run the configured AI analysis
contentBase64:
type: ["string", "null"]
description: Base64 content for source=zip or source=file
filename:
type: ["string", "null"]
description: Original filename for source=file or source=zip
text:
type: ["string", "null"]
description: Raw skill text for source=text
Scan:
type: object
required:
- id
- name
- source
- status
- verdict
- riskScore
- fileCount
- aiUsed
- findingCounts
- createdAt
properties:
id:
type: integer
name:
type: string
source:
type: string
enum: [zip, file, text]
status:
type: string
enum: [completed, failed]
verdict:
type: string
enum: [pass, review, block]
riskScore:
type: integer
fileCount:
type: integer
aiUsed:
type: boolean
aiError:
type: ["string", "null"]
findingCounts:
$ref: "#/components/schemas/FindingCounts"
createdAt:
type: string
FindingCounts:
type: object
required: [critical, high, medium, low, info, security, privacy, total]
properties:
critical:
type: integer
high:
type: integer
medium:
type: integer
low:
type: integer
info:
type: integer
security:
type: integer
privacy:
type: integer
total:
type: integer
ScanCheckpoint:
type: object
description: >-
A single inspection step (Prüfschritt) with its partial assessment
(Teilbewertung).
required: [id, label, category, status, findingCount, scoreDelta]
properties:
id:
type: string
label:
type: string
category:
type: string
axis:
type: ["string", "null"]
enum: [security, privacy, null]
severity:
type: ["string", "null"]
enum: [critical, high, medium, low, info, null]
status:
type: string
enum: [pass, flagged, skipped, error]
findingCount:
type: integer
scoreDelta:
type: integer
detectedBy:
type: ["string", "null"]
enum: [static, ai, null]
ScanFile:
type: object
required: [path, kind, size]
properties:
path:
type: string
kind:
type: string
enum: [instruction, script, resource]
language:
type: ["string", "null"]
size:
type: integer
Finding:
type: object
required:
- id
- ruleId
- axis
- severity
- title
- description
- detectedBy
properties:
id:
type: integer
ruleId:
type: string
axis:
type: string
enum: [security, privacy]
severity:
type: string
enum: [critical, high, medium, low, info]
title:
type: string
description:
type: string
remediation:
type: ["string", "null"]
file:
type: ["string", "null"]
line:
type: ["integer", "null"]
snippet:
type: ["string", "null"]
detectedBy:
type: string
enum: [static, ai]
ScanDetail:
allOf:
- $ref: "#/components/schemas/Scan"
- type: object
required: [files, findings, checkpoints]
properties:
files:
type: array
items:
$ref: "#/components/schemas/ScanFile"
findings:
type: array
items:
$ref: "#/components/schemas/Finding"
checkpoints:
type: array
items:
$ref: "#/components/schemas/ScanCheckpoint"
AiProvider:
type: object
required:
- id
- name
- apiType
- baseUrl
- model
- enabled
- hasToken
- tokenPreview
- createdAt
properties:
id:
type: integer
name:
type: string
apiType:
type: string
enum: [openai, anthropic, custom]
baseUrl:
type: string
model:
type: string
enabled:
type: boolean
hasToken:
type: boolean
tokenPreview:
type: string
description: Masked preview of the stored token (e.g. "sk-...abcd")
createdAt:
type: string
AiProviderInput:
type: object
required: [name, apiType, baseUrl, model]
properties:
name:
type: string
minLength: 1
apiType:
type: string
enum: [openai, anthropic, custom]
baseUrl:
type: string
minLength: 1
model:
type: string
minLength: 1
apiToken:
type: string
enabled:
type: boolean
AiProviderUpdate:
type: object
properties:
name:
type: string
minLength: 1
apiType:
type: string
enum: [openai, anthropic, custom]
baseUrl:
type: string
minLength: 1
model:
type: string
minLength: 1
apiToken:
type: string
description: Provide to replace the stored token; omit to keep existing
enabled:
type: boolean
ProviderTestResult:
type: object
required: [ok]
properties:
ok:
type: boolean
message:
type: ["string", "null"]
Prompt:
type: object
required: [id, key, name, content, updatedAt]
properties:
id:
type: integer
key:
type: string
name:
type: string
content:
type: string
updatedAt:
type: string
PromptUpdate:
type: object
properties:
name:
type: string
minLength: 1
content:
type: string
minLength: 1
Rule:
type: object
required:
- id
- ruleId
- axis
- category
- title
- description
- severity
- detectionType
- enabled
properties:
id:
type: integer
ruleId:
type: string
axis:
type: string
enum: [security, privacy]
category:
type: string
title:
type: string
description:
type: string
severity:
type: string
enum: [critical, high, medium, low, info]
detectionType:
type: string
enum: [regex, heuristic, ai]
enabled:
type: boolean
RuleUpdate:
type: object
properties:
severity:
type: string
enum: [critical, high, medium, low, info]
enabled:
type: boolean
DashboardSummary:
type: object
required:
- totalScans
- avgRiskScore
- verdictCounts
- severityTotals
- axisTotals
- recentScans
- topRules
properties:
totalScans:
type: integer
avgRiskScore:
type: integer
verdictCounts:
$ref: "#/components/schemas/VerdictCounts"
severityTotals:
$ref: "#/components/schemas/SeverityTotals"
axisTotals:
$ref: "#/components/schemas/AxisTotals"
recentScans:
type: array
items:
$ref: "#/components/schemas/Scan"
topRules:
type: array
items:
$ref: "#/components/schemas/RuleStat"
VerdictCounts:
type: object
required: [pass, review, block]
properties:
pass:
type: integer
review:
type: integer
block:
type: integer
SeverityTotals:
type: object
required: [critical, high, medium, low, info]
properties:
critical:
type: integer
high:
type: integer
medium:
type: integer
low:
type: integer
info:
type: integer
AxisTotals:
type: object
required: [security, privacy]
properties:
security:
type: integer
privacy:
type: integer
RuleStat:
type: object
required: [ruleId, title, axis, count]
properties:
ruleId:
type: string
title:
type: string
axis:
type: string
enum: [security, privacy]
count:
type: integer