audit, advisories and doctors/setup work
This commit is contained in:
@@ -20,6 +20,7 @@ Advisory AI is the retrieval-augmented assistant that synthesizes advisory and V
|
||||
- Preserve determinism and provenance in all derived outputs.
|
||||
- Document offline/air-gap pathways for any new feature.
|
||||
- Update telemetry/observability assets alongside feature work.
|
||||
- Chat gateway must enforce quotas, scrubber rules, tool allowlists, and audit logging.
|
||||
|
||||
## Required Reading
|
||||
- `docs/modules/advisory-ai/README.md`
|
||||
|
||||
@@ -153,3 +153,13 @@ All endpoints accept `profile` parameter (default `fips-local`) and return `outp
|
||||
- **Remote inference toggle.** Set `AdvisoryAI:Inference:Mode` (env: `ADVISORYAI__AdvisoryAI__Inference__Mode`) to `Remote` when you want prompts to be executed by an external inference tier. Provide `AdvisoryAI:Inference:Remote:BaseAddress` and, optionally, `...:ApiKey`. When remote calls fail the executor falls back to the sanitized prompt and sets `inference.fallback_*` metadata so CLI/Console surface a warning.
|
||||
- **Scalability.** Start with 1 web replica + 1 worker for up to ~10 requests/minute. For higher throughput, scale `advisory-ai-worker` horizontally; each worker is CPU-bound (2 vCPU / 4 GiB RAM recommended) while the web front end is I/O-bound (1 vCPU / 1 GiB). Because the queue/plan/output stores are content-addressed files, ensure the shared volume delivers ≥500 IOPS and <5 ms latency; otherwise queue depth will lag.
|
||||
- **Offline & air-gapped stance.** The Compose/Helm manifests avoid external network calls by default and the Offline Kit now publishes the `advisory-ai-web` and `advisory-ai-worker` images alongside their SBOMs/provenance. Operators can rehydrate the RWX volume from the kit to pre-prime cache directories before enabling the service.
|
||||
|
||||
## 14) Controlled conversational interface and tool gating
|
||||
|
||||
- **Chat Gateway controls.** Chat endpoints enforce Authority auth, per-tenant/user quotas, token budgets, and PII/secret scrubbing before any model invocation.
|
||||
- **Sanctioned tools only.** Tool calls are schema-bound and allowlisted (read-only by default). Action tools require explicit user confirmation plus policy allow.
|
||||
- **Policy lattice.** Tool permissions are evaluated against policy rules (scope, tenant, role, resource) before invocation.
|
||||
- **Audit log.** Persist prompt hash, redaction metadata, tool calls, policy decisions, and model identifiers to Postgres; optional DSSE signatures capture evidence integrity.
|
||||
- **Offline parity.** Local model profiles are the default; remote inference is opt-in and blocked in sealed mode.
|
||||
|
||||
See `docs/modules/advisory-ai/chat-interface.md` and `docs-archived/product/advisories/13-Jan-2026 - Controlled Conversational Interface.md`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **Sprint:** SPRINT_20260107_006_003 Task CH-016
|
||||
> **Status:** Active
|
||||
> **Last Updated:** 2026-01-09
|
||||
> **Last Updated:** 2026-01-13
|
||||
|
||||
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.
|
||||
|
||||
@@ -14,6 +14,17 @@ The chat interface enables:
|
||||
- **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
|
||||
@@ -22,18 +33,23 @@ The chat interface enables:
|
||||
|
||||
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:chat` or `advisory:run`).
|
||||
|
||||
```http
|
||||
POST /api/v1/advisory-ai/conversations
|
||||
POST /v1/advisory-ai/conversations
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer <token>
|
||||
X-StellaOps-User: user-xyz
|
||||
X-StellaOps-Roles: chat:user
|
||||
X-StellaOps-Client: ui
|
||||
|
||||
{
|
||||
"tenantId": "tenant-123",
|
||||
"context": {
|
||||
"findingId": "f-456",
|
||||
"currentCveId": "CVE-2023-44487",
|
||||
"currentComponent": "pkg:npm/lodash@4.17.21",
|
||||
"currentImageDigest": "sha256:abc123",
|
||||
"scanId": "s-789",
|
||||
"cveId": "CVE-2023-44487",
|
||||
"component": "pkg:npm/lodash@4.17.21"
|
||||
"sbomId": "sbom-123"
|
||||
},
|
||||
"metadata": {
|
||||
"source": "ui",
|
||||
@@ -50,11 +66,7 @@ Authorization: Bearer <token>
|
||||
"userId": "user-xyz",
|
||||
"createdAt": "2026-01-09T12:00:00Z",
|
||||
"updatedAt": "2026-01-09T12:00:00Z",
|
||||
"context": {
|
||||
"currentCveId": "CVE-2023-44487",
|
||||
"currentComponent": "pkg:npm/lodash@4.17.21"
|
||||
},
|
||||
"turnCount": 0
|
||||
"turns": []
|
||||
}
|
||||
```
|
||||
|
||||
@@ -63,13 +75,16 @@ Authorization: Bearer <token>
|
||||
Sends a user message and streams the AI response.
|
||||
|
||||
```http
|
||||
POST /api/v1/advisory-ai/conversations/{conversationId}/turns
|
||||
POST /v1/advisory-ai/conversations/{conversationId}/turns
|
||||
Content-Type: application/json
|
||||
Accept: text/event-stream
|
||||
Authorization: Bearer <token>
|
||||
X-StellaOps-User: user-xyz
|
||||
X-StellaOps-Roles: chat:user
|
||||
X-StellaOps-Client: ui
|
||||
|
||||
{
|
||||
"message": "Is CVE-2023-44487 exploitable in our environment?"
|
||||
"content": "Is CVE-2023-44487 exploitable in our environment?",
|
||||
"stream": true
|
||||
}
|
||||
```
|
||||
|
||||
@@ -155,6 +170,24 @@ DELETE /api/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
|
||||
@@ -225,10 +258,11 @@ You may want to accept this risk: [Accept Risk]{action:approve,cve_id=CVE-2023-4
|
||||
|
||||
1. **Parsing**: ActionProposalParser extracts actions from model output
|
||||
2. **Permission Check**: User roles are validated against required role
|
||||
3. **Display**: Allowed actions render as buttons; blocked actions show disabled with reason
|
||||
4. **Confirmation**: User clicks button and confirms in modal
|
||||
5. **Execution**: Backend executes action with audit trail
|
||||
6. **Result**: Success/failure displayed in chat
|
||||
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
|
||||
|
||||
@@ -244,6 +278,20 @@ When a user lacks permission for an action:
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
@@ -333,17 +381,40 @@ Assistant: I will create a VEX statement with the following details:
|
||||
|
||||
```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
|
||||
AuditAllExecutions: true```n
|
||||
RequirePolicyAllow: true
|
||||
AuditAllExecutions: true
|
||||
```
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
@@ -364,4 +435,5 @@ AdvisoryAI:
|
||||
- [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)
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ The `stella` CLI is the operator-facing Swiss army knife for scans, exports, pol
|
||||
- Preserve determinism: sort outputs, normalise timestamps (UTC ISO-8601), and avoid machine-specific artefacts.
|
||||
- Keep Offline Kit parity in mind—document air-gapped workflows for any new feature.
|
||||
- Update runbooks/observability assets when operational characteristics change.
|
||||
- Advisory commands must default to read-only and display evidence refs with citations.
|
||||
## Required Reading
|
||||
- `docs/modules/cli/README.md`
|
||||
- `docs/modules/cli/architecture.md`
|
||||
|
||||
@@ -174,7 +174,12 @@ Both subcommands honour offline-first expectations (no network access) and norma
|
||||
* Uses `STELLAOPS_ADVISORYAI_URL` when configured; otherwise it reuses the backend base address and adds `X-StellaOps-Scopes` (`advisory:run` + task scope) per request.
|
||||
* `--timeout 0` performs a single cache lookup (for CI flows that only want cached artefacts).
|
||||
|
||||
### 2.12 Decision evidence (new)
|
||||
* `advise ask "<question>" [--evidence] [--no-action] [--conversation-id <id>] [--context <cve|scan|image>]`
|
||||
|
||||
* Calls advisory chat endpoints, returns a cited answer with evidence refs.
|
||||
* `--no-action` disables action proposals; `--evidence` forces evidence chips in output.
|
||||
|
||||
### 2.12 Decision evidence (new)
|
||||
|
||||
- `decision export`
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ Policy Engine compiles and evaluates Stella DSL policies deterministically, prod
|
||||
- Preserve determinism: sort outputs, normalise timestamps (UTC ISO-8601), and avoid machine-specific artefacts.
|
||||
- Keep Offline Kit parity in mind—document air-gapped workflows for any new feature.
|
||||
- Update runbooks/observability assets when operational characteristics change.
|
||||
- Assistant tool lattice rules must be deterministic and policy-auditable.
|
||||
## Required Reading
|
||||
- `docs/modules/policy/README.md`
|
||||
- `docs/modules/policy/architecture.md`
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
# Advisory AI Assistant Parameters
|
||||
# Advisory AI Assistant Parameters
|
||||
|
||||
_Primary audience: platform operators & policy authors • Updated: 2025-11-24_
|
||||
_Primary audience: platform operators & policy authors • Updated: 2026-01-13_
|
||||
|
||||
This note centralises the tunable knobs that control Advisory AI’s planner, retrieval stack, inference clients, and guardrails. All options live under the `AdvisoryAI` configuration section and can be set via `appsettings.*` files or environment variables using ASP.NET Core’s double-underscore convention (`ADVISORYAI__Inference__Mode`, etc.).
|
||||
This note centralises the tunable knobs that control Advisory AI’s planner, retrieval stack, inference clients, and guardrails. All options live under the `AdvisoryAI` configuration section and can be set via `appsettings.*` files or environment variables using ASP.NET Core’s double-underscore convention (`ADVISORYAI__Inference__Mode`, etc.). Chat quotas and tool allowlists can also be overridden per tenant/user via the chat settings endpoints; appsettings/env values are defaults.
|
||||
|
||||
**Policy/version pin** — For Sprint 0111, use the policy bundle hash shipped on 2025-11-19 (same drop as `CLI-VULN-29-001` / `CLI-VEX-30-001`). Set `AdvisoryAI:PolicyVersion` or `ADVISORYAI__POLICYVERSION=2025.11.19` in deployments; include the hash in DSSE metadata for Offline Kits.
|
||||
**Policy/version pin** — For Sprint 0111, use the policy bundle hash shipped on 2025-11-19 (same drop as `CLI-VULN-29-001` / `CLI-VEX-30-001`). Set `AdvisoryAI:PolicyVersion` or `ADVISORYAI__POLICYVERSION=2025.11.19` in deployments; include the hash in DSSE metadata for Offline Kits.
|
||||
|
||||
| Area | Key(s) | Environment variable | Default | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Inference mode | `AdvisoryAI:Inference:Mode` | `ADVISORYAI__INFERENCE__MODE` | `Local` | `Local` runs the deterministic pipeline only; `Remote` posts sanitized prompts to `Remote.BaseAddress`. |
|
||||
| Remote base URI | `AdvisoryAI:Inference:Remote:BaseAddress` | `ADVISORYAI__INFERENCE__REMOTE__BASEADDRESS` | — | Required when `Mode=Remote`. HTTPS strongly recommended. |
|
||||
| Remote API key | `AdvisoryAI:Inference:Remote:ApiKey` | `ADVISORYAI__INFERENCE__REMOTE__APIKEY` | — | Injected as `Authorization: Bearer <key>` when present. |
|
||||
| Remote base URI | `AdvisoryAI:Inference:Remote:BaseAddress` | `ADVISORYAI__INFERENCE__REMOTE__BASEADDRESS` | — | Required when `Mode=Remote`. HTTPS strongly recommended. |
|
||||
| Remote API key | `AdvisoryAI:Inference:Remote:ApiKey` | `ADVISORYAI__INFERENCE__REMOTE__APIKEY` | — | Injected as `Authorization: Bearer <key>` when present. |
|
||||
| Remote timeout | `AdvisoryAI:Inference:Remote:TimeoutSeconds` | `ADVISORYAI__INFERENCE__REMOTE__TIMEOUTSECONDS` | `30` | Failing requests fall back to the sanitized prompt with `inference.fallback_reason=remote_timeout`. |
|
||||
| Guardrail prompt cap | `AdvisoryAI:Guardrails:MaxPromptLength` | `ADVISORYAI__GUARDRAILS__MAXPROMPTLENGTH` | `16000` | Prompts longer than the cap are blocked with `prompt_too_long`. |
|
||||
| Guardrail citations | `AdvisoryAI:Guardrails:RequireCitations` | `ADVISORYAI__GUARDRAILS__REQUIRECITATIONS` | `true` | When `true`, at least one citation must accompany every prompt. |
|
||||
| Guardrail phrase seeds | `AdvisoryAI:Guardrails:BlockedPhrases[]`<br>`AdvisoryAI:Guardrails:BlockedPhraseFile` | `ADVISORYAI__GUARDRAILS__BLOCKEDPHRASES__0`<br>`ADVISORYAI__GUARDRAILS__BLOCKEDPHRASEFILE` | See defaults below | File paths are resolved relative to the content root; phrases are merged, de-duped, and lower-cased. |
|
||||
| Chat request quota | `AdvisoryAI:Chat:Quotas:RequestsPerMinute` | `ADVISORYAI__CHAT__QUOTAS__REQUESTSPERMINUTE` | `60` | Requests per minute per user/org. |
|
||||
| Chat daily request quota | `AdvisoryAI:Chat:Quotas:RequestsPerDay` | `ADVISORYAI__CHAT__QUOTAS__REQUESTSPERDAY` | `500` | Requests per day per user/org. |
|
||||
| Chat token budget | `AdvisoryAI:Chat:Quotas:TokensPerDay` | `ADVISORYAI__CHAT__QUOTAS__TOKENSPERDAY` | `100000` | Tokens per day per user/org. |
|
||||
| Chat tool budget | `AdvisoryAI:Chat:Quotas:ToolCallsPerDay` | `ADVISORYAI__CHAT__QUOTAS__TOOLCALLSPERDAY` | `10000` | Tool calls per day per user/org. |
|
||||
| Guardrail scrubber entropy | `AdvisoryAI:Guardrails:EntropyThreshold` | `ADVISORYAI__GUARDRAILS__ENTROPYTHRESHOLD` | `3.5` | Entropy threshold for high-risk token redaction. |
|
||||
| Guardrail scrubber min length | `AdvisoryAI:Guardrails:EntropyMinLength` | `ADVISORYAI__GUARDRAILS__ENTROPYMINLENGTH` | `20` | Minimum token length for entropy checks. |
|
||||
| Guardrail scrubber allowlist file | `AdvisoryAI:Guardrails:AllowlistFile` | `ADVISORYAI__GUARDRAILS__ALLOWLISTFILE` | `data/advisory-ai/allowlist.txt` | Allowlisted patterns bypass redaction. |
|
||||
| Guardrail scrubber allowlist patterns | `AdvisoryAI:Guardrails:AllowlistPatterns` | `ADVISORYAI__GUARDRAILS__ALLOWLISTPATTERNS__0` | See defaults | Additional allowlist patterns appended to defaults. |
|
||||
| Chat tools allow all | `AdvisoryAI:Chat:Tools:AllowAll` | `ADVISORYAI__CHAT__TOOLS__ALLOWALL` | `true` | When true, allow all tools with enabled providers. |
|
||||
| Chat tool allowlist | `AdvisoryAI:Chat:Tools:AllowedTools` | `ADVISORYAI__CHAT__TOOLS__ALLOWEDTOOLS__0` | See defaults | Allowed tools when `AllowAll=false`. |
|
||||
| Chat audit enabled | `AdvisoryAI:Chat:Audit:Enabled` | `ADVISORYAI__CHAT__AUDIT__ENABLED` | `true` | Toggles chat audit persistence. |
|
||||
| Chat audit connection string | `AdvisoryAI:Chat:Audit:ConnectionString` | `ADVISORYAI__CHAT__AUDIT__CONNECTIONSTRING` | --- | Postgres connection string for chat audit logs. |
|
||||
| Chat audit schema | `AdvisoryAI:Chat:Audit:SchemaName` | `ADVISORYAI__CHAT__AUDIT__SCHEMANAME` | `advisoryai` | Schema for chat audit tables. |
|
||||
| Chat audit evidence bundle | `AdvisoryAI:Chat:Audit:IncludeEvidenceBundle` | `ADVISORYAI__CHAT__AUDIT__INCLUDEEVIDENCEBUNDLE` | `false` | Store full evidence bundle JSON in audit log. |
|
||||
| Chat audit retention | `AdvisoryAI:Chat:Audit:RetentionPeriod` | `ADVISORYAI__CHAT__AUDIT__RETENTIONPERIOD` | `90.00:00:00` | Retention period for audit logs. |
|
||||
| Chat action policy allow | `AdvisoryAI:Chat:Actions:RequirePolicyAllow` | `ADVISORYAI__CHAT__ACTIONS__REQUIREPOLICYALLOW` | `true` | Require policy lattice approval before actions. |
|
||||
| Plan cache TTL | `AdvisoryAI:PlanCache:DefaultTimeToLive`* | `ADVISORYAI__PLANCACHE__DEFAULTTIMETOLIVE` | `00:10:00` | Controls how long cached plans are reused. (`CleanupInterval` defaults to `00:05:00`). |
|
||||
| Queue capacity | `AdvisoryAI:Queue:Capacity` | `ADVISORYAI__QUEUE__CAPACITY` | `1024` | Upper bound on in-memory tasks when using the default queue. |
|
||||
| Queue wait interval | `AdvisoryAI:Queue:DequeueWaitInterval` | `ADVISORYAI__QUEUE__DEQUEUEWAITINTERVAL` | `00:00:01` | Back-off between queue polls when empty. |
|
||||
@@ -23,12 +39,12 @@ This note centralises the tunable knobs that control Advisory AI’s planner, re
|
||||
|
||||
---
|
||||
|
||||
## 1. Inference knobs & “temperature”
|
||||
## 1. Inference knobs & “temperatureâ€
|
||||
|
||||
Advisory AI supports two inference modes:
|
||||
|
||||
- **Local (default)** – The orchestrator emits deterministic prompts and the worker returns the sanitized prompt verbatim. This mode is offline-friendly and does **not** call any external LLMs. There is no stochastic “temperature” here—the pipeline is purely rule-based.
|
||||
- **Remote** – Sanitized prompts, citations, and metadata are POSTed to `Remote.BaseAddress + Remote.Endpoint` (default `/v1/inference`). Remote providers control sampling temperature on their side. StellaOps treats remote responses deterministically: we record the provider’s `modelId`, token usage, and any metadata they return. If your remote tier exposes a temperature knob, set it there; Advisory AI simply forwards the prompt.
|
||||
- **Local (default)** – The orchestrator emits deterministic prompts and the worker returns the sanitized prompt verbatim. This mode is offline-friendly and does **not** call any external LLMs. There is no stochastic “temperature†here—the pipeline is purely rule-based.
|
||||
- **Remote** – Sanitized prompts, citations, and metadata are POSTed to `Remote.BaseAddress + Remote.Endpoint` (default `/v1/inference`). Remote providers control sampling temperature on their side. StellaOps treats remote responses deterministically: we record the provider’s `modelId`, token usage, and any metadata they return. If your remote tier exposes a temperature knob, set it there; Advisory AI simply forwards the prompt.
|
||||
|
||||
### Remote inference quick sample
|
||||
|
||||
@@ -52,22 +68,36 @@ Advisory AI supports two inference modes:
|
||||
|
||||
| Setting | Default | Explanation |
|
||||
| --- | --- | --- |
|
||||
| `MaxPromptLength` | 16000 chars | Upper bound enforced after redaction. Increase cautiously—remote providers typically cap prompts at 32k tokens. |
|
||||
| `MaxPromptLength` | 16000 chars | Upper bound enforced after redaction. Increase cautiously—remote providers typically cap prompts at 32k tokens. |
|
||||
| `RequireCitations` | `true` | Forces each prompt to include at least one citation. Disable only when testing synthetic prompts. |
|
||||
| `BlockedPhrases[]` | `ignore previous instructions`, `disregard earlier instructions`, `you are now the system`, `override the system prompt`, `please jailbreak` | Inline list merged with the optional file. Comparisons are case-insensitive. |
|
||||
| `BlockedPhraseFile` | — | Points to a newline-delimited list. Relative paths resolve against the content root (`AdvisoryAI.Hosting` sticks to AppContext base). |
|
||||
| `BlockedPhraseFile` | — | Points to a newline-delimited list. Relative paths resolve against the content root (`AdvisoryAI.Hosting` sticks to AppContext base). |
|
||||
| `EntropyThreshold` | `3.5` | Shannon entropy threshold for high-risk token redaction. Set to `0` to disable entropy checks. |
|
||||
| `EntropyMinLength` | `20` | Minimum token length evaluated by the entropy scrubber. |
|
||||
| `AllowlistPatterns` | Defaults (sha256/sha1/sha384/sha512) | Regex patterns that bypass entropy redaction for known-safe identifiers. |
|
||||
| `AllowlistFile` | — | Optional allowlist file (JSON array or newline-delimited). Paths resolve against the content root. |
|
||||
|
||||
Violations surface in the response metadata (`guardrail.violations[*]`) and increment `advisory_ai_guardrail_blocks_total`. Console consumes the same payload for its ribbon state.
|
||||
|
||||
## 2.1 Tool policy lattice (chat)
|
||||
|
||||
Chat tool calls are allowed only when policy rules permit. Scope is evaluated on tenant, role, tool name, and resource.
|
||||
|
||||
Example (pseudo):
|
||||
```text
|
||||
allow_tool("vex.query") if role in ["analyst"] and namespace in ["team-a"]
|
||||
deny_tool("vault.secrets.get") always
|
||||
```
|
||||
|
||||
## 3. Retrieval & ranking weights (per-task)
|
||||
|
||||
Each task type (Summary, Conflict, Remediation) inherits the defaults below. Override any value via `AdvisoryAI:Tasks:<TaskType>:<Property>`.
|
||||
|
||||
| Task | `StructuredMaxChunks` | `VectorTopK` | `VectorQueries` (default) | `SbomMaxTimelineEntries` | `SbomMaxDependencyPaths` | `IncludeBlastRadius` |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| Summary | 25 | 5 | `Summarize key facts`, `What is impacted?` | 10 | 20 | ✔ |
|
||||
| Conflict | 30 | 6 | `Highlight conflicting statements`, `Where do sources disagree?` | 8 | 15 | ✖ |
|
||||
| Remediation | 35 | 6 | `Provide remediation steps`, `Outline mitigations and fixes` | 12 | 25 | ✔ |
|
||||
| Summary | 25 | 5 | `Summarize key facts`, `What is impacted?` | 10 | 20 | ✔ |
|
||||
| Conflict | 30 | 6 | `Highlight conflicting statements`, `Where do sources disagree?` | 8 | 15 | ✖ |
|
||||
| Remediation | 35 | 6 | `Provide remediation steps`, `Outline mitigations and fixes` | 12 | 25 | ✔ |
|
||||
|
||||
These knobs act as weighting levers: lower `VectorTopK` emphasises deterministic evidence; higher values favor breadth. `StructuredMaxChunks` bounds how many CSAF/OSV/VEX chunks reach the prompt, keeping token budgets predictable.
|
||||
|
||||
@@ -77,17 +107,17 @@ These knobs act as weighting levers: lower `VectorTopK` emphasises deterministic
|
||||
|
||||
| Task | Prompt tokens | Completion tokens |
|
||||
| --- | --- | --- |
|
||||
| Summary | 2 048 | 512 |
|
||||
| Conflict | 2 048 | 512 |
|
||||
| Remediation | 2 048 | 640 |
|
||||
| Summary | 2 048 | 512 |
|
||||
| Conflict | 2 048 | 512 |
|
||||
| Remediation | 2 048 | 640 |
|
||||
|
||||
Overwrite via `AdvisoryAI:Tasks:Summary:Budget:PromptTokens`, etc. The worker records actual consumption in the response metadata (`inference.prompt_tokens`, `inference.completion_tokens`).
|
||||
|
||||
## 5. Cache TTLs & queue directories
|
||||
|
||||
- **Plan cache TTLs** – In-memory and file-system caches honour `AdvisoryAI:PlanCache:DefaultTimeToLive` (default 10 minutes) and `CleanupInterval` (default 5 minutes). Shorten the TTL to reduce stale plans or increase it to favour offline reuse. Both values accept ISO 8601 or `hh:mm:ss` time spans.
|
||||
- **Queue & storage paths** – `AdvisoryAI:Queue:DirectoryPath`, `AdvisoryAI:Storage:PlanCacheDirectory`, and `AdvisoryAI:Storage:OutputDirectory` default to `data/advisory-ai/{queue,plans,outputs}` under the content root; override these when mounting RWX volumes in sovereign clusters.
|
||||
- **Output TTLs** – Output artefacts inherit the host file-system retention policies. Combine `DefaultTimeToLive` with a cron or systemd timer to prune `outputs/` periodically when operating in remote-inference-heavy environments.
|
||||
- **Plan cache TTLs** – In-memory and file-system caches honour `AdvisoryAI:PlanCache:DefaultTimeToLive` (default 10 minutes) and `CleanupInterval` (default 5 minutes). Shorten the TTL to reduce stale plans or increase it to favour offline reuse. Both values accept ISO 8601 or `hh:mm:ss` time spans.
|
||||
- **Queue & storage paths** – `AdvisoryAI:Queue:DirectoryPath`, `AdvisoryAI:Storage:PlanCacheDirectory`, and `AdvisoryAI:Storage:OutputDirectory` default to `data/advisory-ai/{queue,plans,outputs}` under the content root; override these when mounting RWX volumes in sovereign clusters.
|
||||
- **Output TTLs** – Output artefacts inherit the host file-system retention policies. Combine `DefaultTimeToLive` with a cron or systemd timer to prune `outputs/` periodically when operating in remote-inference-heavy environments.
|
||||
|
||||
### Example: raised TTL & custom queue path
|
||||
|
||||
@@ -108,5 +138,6 @@ Overwrite via `AdvisoryAI:Tasks:Summary:Budget:PromptTokens`, etc. The worker re
|
||||
## 6. Operational notes
|
||||
|
||||
- Updating **guardrail phrases** triggers only on host reload. When distributing blocked-phrase files via Offline Kits, keep filenames stable and version them through Git so QA can diff changes.
|
||||
- **Temperature / sampling** remains a remote-provider concern. StellaOps records the provider’s `modelId` and exposes fallback metadata so policy authors can audit when sanitized prompts were returned instead of model output.
|
||||
- **Temperature / sampling** remains a remote-provider concern. StellaOps records the provider’s `modelId` and exposes fallback metadata so policy authors can audit when sanitized prompts were returned instead of model output.
|
||||
- Always track changes in `docs/implplan/SPRINT_0111_0001_0001_advisoryai.md` (task `DOCS-AIAI-31-006`) when promoting this document so the guild can trace which parameters were added per sprint.
|
||||
|
||||
|
||||
29
docs/modules/policy/guides/assistant-tool-lattice.md
Normal file
29
docs/modules/policy/guides/assistant-tool-lattice.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Assistant Tool Lattice Policy Mapping
|
||||
|
||||
This guide defines the tool lattice rule schema and default scope mapping for assistant tool calls.
|
||||
The lattice is evaluated by Policy Gateway and returns allow or deny decisions for each tool request.
|
||||
|
||||
## Default deny behavior
|
||||
- If no rule matches a tool request, the decision is deny.
|
||||
- A rule must match tool name, action, and any configured tenant, role, scope, or resource filters to allow access.
|
||||
|
||||
## Rule fields
|
||||
- tool: Tool name or wildcard pattern (for example, "vex.query" or "scanner.*").
|
||||
- action: Read or action discriminator (for example, "read" or "action").
|
||||
- scopes: Required Authority scopes (one or more).
|
||||
- roles: Optional role filters (one or more).
|
||||
- tenants: Optional tenant filters (one or more).
|
||||
- resource: Optional resource pattern (for example, "sbom:component:*").
|
||||
- effect: allow or deny.
|
||||
- priority: Integer priority; higher values evaluate first.
|
||||
|
||||
## Default scope mapping
|
||||
| Tool | Action | Required scopes |
|
||||
| --- | --- | --- |
|
||||
| vex.query | read | vex:read |
|
||||
| sbom.read | read | sbom:read |
|
||||
| scanner.findings.topk | read | scanner:read or findings:read |
|
||||
|
||||
## Override guidance
|
||||
- Use priority to override default rules.
|
||||
- Keep rules deterministic by using stable patterns and avoiding ambiguous overlaps.
|
||||
@@ -169,12 +169,18 @@ message ResolveResponse {
|
||||
|
||||
**Doctor Check Output**:
|
||||
```typescript
|
||||
interface DoctorHowToFix {
|
||||
summary: string;
|
||||
commands: string[];
|
||||
}
|
||||
|
||||
interface DoctorCheckResult {
|
||||
checkType: string;
|
||||
status: "pass" | "warn" | "fail";
|
||||
message: string;
|
||||
details: Record<string, any>;
|
||||
suggestions: string[];
|
||||
howToFix?: DoctorHowToFix;
|
||||
runAt: DateTime;
|
||||
durationMs: number;
|
||||
}
|
||||
@@ -183,10 +189,33 @@ interface DoctorReport {
|
||||
integrationId: UUID;
|
||||
overallStatus: "healthy" | "degraded" | "unhealthy";
|
||||
checks: DoctorCheckResult[];
|
||||
evidenceLog?: {
|
||||
jsonlPath: string;
|
||||
dssePath?: string;
|
||||
};
|
||||
generatedAt: DateTime;
|
||||
}
|
||||
```
|
||||
|
||||
Doctor JSON output for CLI/agents uses `how_to_fix` (snake case) as the alias of
|
||||
`howToFix` to preserve verbatim fix commands.
|
||||
Doctor fix executes only non-destructive commands; destructive steps are manual
|
||||
and never executed by Doctor.
|
||||
Evidence logs include `doctor_command`, and DSSE summaries include the same
|
||||
operator-invoked command note.
|
||||
|
||||
**Declarative Packs (YAML)**:
|
||||
- Packs live in `plugins/doctor/*.yaml` and are discoverable by env/file gating.
|
||||
- `checks[].run.exec` executes CLI commands; `checks[].parse` defines pass/fail.
|
||||
- `checks[].how_to_fix.commands[]` must be printed verbatim and remain deterministic.
|
||||
|
||||
Sample manifest:
|
||||
- `docs/benchmarks/doctor/doctor-plugin-release-orchestrator-gitlab.yaml`
|
||||
|
||||
**Evidence Artifacts**:
|
||||
- JSONL evidence log per run (local by default).
|
||||
- Optional DSSE summary for audit export.
|
||||
|
||||
---
|
||||
|
||||
## Cache Eviction Policies
|
||||
|
||||
@@ -26,36 +26,14 @@ The attestation provides the *evidence* that supports VEX claims. For example, a
|
||||
### Component Diagram
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Binary Diff Attestation Flow │
|
||||
├──────────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ OCI │ │ Layer │ │ Binary │ │ Section │ │
|
||||
│ │ Registry │───▶│ Extraction │───▶│ Detection │───▶│ Hash │ │
|
||||
│ │ Client │ │ │ │ │ │ Extractor │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ Base Image ─────────────────────────────────────┐ │ │
|
||||
│ Target Image ───────────────────────────────────┤ ▼ │
|
||||
│ │ ┌─────────────┐ │
|
||||
│ └─▶│ Diff │ │
|
||||
│ │ Computation │ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ DSSE │◀───│ Predicate │◀───│ Finding │◀───│ Verdict │ │
|
||||
│ │ Signer │ │ Builder │ │ Aggregation │ │ Classifier │ │
|
||||
│ └──────┬──────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Rekor │ │ File │ │
|
||||
│ │ Submission │ │ Output │ │
|
||||
│ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
└──────────────────────────────────────────────────────────────────────────────┘
|
||||
+-------------------+ +--------------------+ +--------------------+ +----------------------+
|
||||
| OCI Registry |-->| Layer Extraction |-->| ELF Detection |-->| Section Hash Extract |
|
||||
+-------------------+ +--------------------+ +--------------------+ +----------------------+
|
||||
| base + target images
|
||||
v
|
||||
+-------------------+ +--------------------+ +------------------+ +------------------+
|
||||
| Diff Computation |-->| Predicate Builder |-->| DSSE Signer |-->| Output Files |
|
||||
+-------------------+ +--------------------+ +------------------+ +------------------+
|
||||
```
|
||||
|
||||
### Key Components
|
||||
@@ -63,8 +41,8 @@ The attestation provides the *evidence* that supports VEX claims. For example, a
|
||||
| Component | Location | Responsibility |
|
||||
|-----------|----------|----------------|
|
||||
| `ElfSectionHashExtractor` | `Scanner.Analyzers.Native` | Extract per-section SHA-256 hashes from ELF binaries |
|
||||
| `BinaryDiffService` | `Cli.Services` | Orchestrate diff computation between two images |
|
||||
| `BinaryDiffPredicateBuilder` | `Attestor.StandardPredicates` | Construct BinaryDiffV1 in-toto predicates |
|
||||
| `BinaryDiffService` | `Cli.Commands.Scan` | Orchestrate diff computation between two images |
|
||||
| `BinaryDiffPredicateBuilder` | `Attestor.StandardPredicates` | Construct BinaryDiffV1 predicate payloads |
|
||||
| `BinaryDiffDsseSigner` | `Attestor.StandardPredicates` | Sign predicates with DSSE envelopes |
|
||||
|
||||
### Data Flow
|
||||
@@ -74,9 +52,9 @@ The attestation provides the *evidence* that supports VEX claims. For example, a
|
||||
3. **Binary Identification**: Identify ELF binaries in both filesystems
|
||||
4. **Section Hash Computation**: Compute SHA-256 for each target section in each binary
|
||||
5. **Diff Computation**: Compare section hashes between base and target
|
||||
6. **Verdict Classification**: Classify changes as patched/vanilla/unknown
|
||||
6. **Verdict Classification**: Basic classification of unchanged vs modified binaries
|
||||
7. **Predicate Construction**: Build BinaryDiffV1 predicate with findings
|
||||
8. **DSSE Signing**: Sign predicate and optionally submit to Rekor
|
||||
8. **DSSE Signing**: Sign predicate; optional transparency log submission is handled by attestor tooling
|
||||
|
||||
## ELF Section Hashing
|
||||
|
||||
@@ -131,26 +109,24 @@ All operations produce deterministic output:
|
||||
|
||||
### Schema Overview
|
||||
|
||||
The `BinaryDiffV1` predicate follows in-toto attestation format:
|
||||
The `BinaryDiffV1` predicate payload uses the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"_type": "https://in-toto.io/Statement/v1",
|
||||
"subject": [
|
||||
"predicateType": "stellaops.binarydiff.v1",
|
||||
"subjects": [
|
||||
{
|
||||
"name": "docker://repo/app@sha256:target...",
|
||||
"digest": { "sha256": "target..." }
|
||||
"digest": { "sha256": "target..." },
|
||||
"platform": { "os": "linux", "architecture": "amd64" }
|
||||
}
|
||||
],
|
||||
"predicateType": "stellaops.binarydiff.v1",
|
||||
"predicate": {
|
||||
"inputs": {
|
||||
"base": { "digest": "sha256:base..." },
|
||||
"target": { "digest": "sha256:target..." }
|
||||
},
|
||||
"findings": [...],
|
||||
"metadata": {...}
|
||||
}
|
||||
"inputs": {
|
||||
"base": { "digest": "sha256:base..." },
|
||||
"target": { "digest": "sha256:target..." }
|
||||
},
|
||||
"findings": [...],
|
||||
"metadata": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -175,15 +151,18 @@ Each finding represents a binary comparison:
|
||||
"binaryFormat": "elf",
|
||||
"sectionDeltas": [
|
||||
{ "section": ".text", "status": "modified" },
|
||||
{ "section": ".rodata", "status": "identical" }
|
||||
{ "section": ".rodata", "status": "added" }
|
||||
],
|
||||
"confidence": 0.95,
|
||||
"verdict": "patched"
|
||||
"confidence": 0.50,
|
||||
"verdict": "unknown"
|
||||
}
|
||||
```
|
||||
|
||||
### Verdicts
|
||||
|
||||
Current CLI output uses `vanilla` for unchanged binaries and `unknown` for modified binaries.
|
||||
Advanced verdict classification (patched/vanilla) is planned for follow-up work.
|
||||
|
||||
| Verdict | Meaning | Confidence Threshold |
|
||||
|---------|---------|---------------------|
|
||||
| `patched` | Binary shows evidence of security patch | >= 0.90 |
|
||||
@@ -210,13 +189,12 @@ Each finding represents a binary comparison:
|
||||
|
||||
### Signature Algorithm
|
||||
|
||||
- **Default**: Ed25519
|
||||
- **Alternative**: ECDSA P-256, RSA-PSS (via `ICryptoProviderRegistry`)
|
||||
- **Keyless**: Sigstore Fulcio certificate chain
|
||||
- **CLI output**: ECDSA (P-256/384/521) with operator-provided PEM key
|
||||
- **Library support**: Ed25519 available via `EnvelopeSignatureService`
|
||||
|
||||
### Rekor Submission
|
||||
|
||||
When Rekor is enabled:
|
||||
When Rekor is enabled in attestor tooling:
|
||||
|
||||
1. DSSE envelope is submitted to Rekor transparency log
|
||||
2. Inclusion proof is retrieved
|
||||
@@ -229,22 +207,28 @@ When Rekor is enabled:
|
||||
"integratedTime": "2026-01-13T12:00:00Z"
|
||||
}
|
||||
```
|
||||
Note: `stella scan diff` does not submit to Rekor; it only emits local DSSE outputs.
|
||||
|
||||
### Verification
|
||||
|
||||
Binary diff attestations can be verified with:
|
||||
|
||||
```bash
|
||||
# Using cosign
|
||||
# Attach the DSSE envelope to the image
|
||||
stella attest attach \
|
||||
--image docker://repo/app:1.0.1 \
|
||||
--attestation ./binarydiff.dsse.json
|
||||
|
||||
# Verify with cosign (key-based)
|
||||
cosign verify-attestation \
|
||||
--type stellaops.binarydiff.v1 \
|
||||
--certificate-identity-regexp '.*' \
|
||||
--certificate-oidc-issuer-regexp '.*' \
|
||||
--key ./keys/binarydiff.pub \
|
||||
docker://repo/app:1.0.1
|
||||
|
||||
# Using stella CLI
|
||||
stella verify attestation ./binarydiff.dsse.json \
|
||||
--type stellaops.binarydiff.v1
|
||||
# Verify with stella CLI
|
||||
stella attest verify \
|
||||
--image docker://repo/app:1.0.1 \
|
||||
--predicate-type stellaops.binarydiff.v1
|
||||
```
|
||||
|
||||
## Integration Points
|
||||
@@ -335,7 +319,7 @@ See [CLI Reference](../../API_CLI_REFERENCE.md#stella-scan-diff) for full option
|
||||
1. **ELF only**: PE and Mach-O support planned for M2
|
||||
2. **Single platform**: Multi-platform diff requires multiple invocations
|
||||
3. **No function-level analysis**: Section-level granularity only
|
||||
4. **Confidence scoring**: Based on section changes, not semantic analysis
|
||||
4. **Confidence scoring**: Placeholder scoring only; verdict classifier is minimal
|
||||
|
||||
### Roadmap
|
||||
|
||||
|
||||
84
docs/modules/scanner/image-inspection.md
Normal file
84
docs/modules/scanner/image-inspection.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# OCI Image Inspection
|
||||
|
||||
## Overview
|
||||
|
||||
OCI image inspection resolves an image reference to its manifest or index, enumerates platform manifests, and returns ordered layer metadata. The inspector is used by CLI workflows that need deterministic image metadata without pulling layers.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Components
|
||||
|
||||
| Component | Location | Responsibility |
|
||||
| --- | --- | --- |
|
||||
| `IOciImageInspector` | `Scanner.Storage.Oci` | Public interface for image inspection |
|
||||
| `OciImageInspector` | `Scanner.Storage.Oci` | Implements manifest/index resolution, auth flow, and ordering |
|
||||
| `ImageInspectionResult` | `Scanner.Contracts` | Output model for index, platform, and layer data |
|
||||
|
||||
### Data flow
|
||||
|
||||
1. Parse the image reference into registry, repository, tag or digest.
|
||||
2. HEAD the manifest to obtain media type and digest.
|
||||
3. GET the manifest payload.
|
||||
4. If media type is index, enumerate platform manifests and optionally resolve each manifest.
|
||||
5. For each manifest, fetch config (for platform metadata) and list layers in manifest order.
|
||||
6. Return ordered results with warnings and a deterministic inspection timestamp.
|
||||
|
||||
## Media type support
|
||||
|
||||
| Media type | Type | Handling |
|
||||
| --- | --- | --- |
|
||||
| `application/vnd.oci.image.index.v1+json` | OCI index | Parse as index and enumerate manifests |
|
||||
| `application/vnd.docker.distribution.manifest.list.v2+json` | Docker list | Parse as index |
|
||||
| `application/vnd.oci.image.manifest.v1+json` | OCI manifest | Parse as manifest |
|
||||
| `application/vnd.docker.distribution.manifest.v2+json` | Docker manifest | Parse as manifest |
|
||||
|
||||
## Configuration
|
||||
|
||||
The inspector uses `OciRegistryOptions`:
|
||||
|
||||
| Field | Purpose |
|
||||
| --- | --- |
|
||||
| `DefaultRegistry` | Registry to use when no registry is specified |
|
||||
| `AllowInsecure` | Allow HTTP and insecure TLS for registry calls |
|
||||
| `Auth.Username` / `Auth.Password` | Basic auth credentials |
|
||||
| `Auth.Token` | Bearer token |
|
||||
| `Auth.AllowAnonymousFallback` | Allow retry without auth after 401 |
|
||||
|
||||
CLI configuration binding uses the `OciRegistry` section (example):
|
||||
|
||||
```json
|
||||
{
|
||||
"OciRegistry": {
|
||||
"DefaultRegistry": "docker.io",
|
||||
"AllowInsecure": false,
|
||||
"Auth": {
|
||||
"Username": "registry-user",
|
||||
"Password": "registry-pass",
|
||||
"AllowAnonymousFallback": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Output model
|
||||
|
||||
`ImageInspectionResult` returns:
|
||||
|
||||
- Resolved digest and media type
|
||||
- Multi-arch indicator
|
||||
- Ordered platform manifests (os, arch, variant)
|
||||
- Ordered layer list with size and media type
|
||||
- UTC inspection timestamp from `TimeProvider`
|
||||
- Deterministic, sorted warnings
|
||||
|
||||
## Determinism
|
||||
|
||||
- Platforms sorted by `os`, `architecture`, `variant`.
|
||||
- Layers preserve manifest order (0-indexed).
|
||||
- Warnings sorted lexicographically and de-duplicated.
|
||||
- Timestamps come from injected `TimeProvider`.
|
||||
|
||||
## Integration points
|
||||
|
||||
- CLI: `stella image inspect` consumes the inspector result for table and JSON output.
|
||||
- Scanner services can reuse the inspector for registry resolution without pulling layers.
|
||||
@@ -26,6 +26,7 @@ The Console presents operator dashboards for scans, policies, VEX evidence, runt
|
||||
- Preserve determinism: sort outputs, normalise timestamps (UTC ISO-8601), and avoid machine-specific artefacts.
|
||||
- Keep Offline Kit parity in mind—document air-gapped workflows for any new feature.
|
||||
- Update runbooks/observability assets when operational characteristics change.
|
||||
- Advisor surfaces must be evidence-first and require confirmation for any actions.
|
||||
## Required Reading
|
||||
- `docs/modules/ui/README.md`
|
||||
- `docs/modules/ui/architecture.md`
|
||||
|
||||
@@ -178,11 +178,18 @@ Each feature folder builds as a **standalone route** (lazy loaded). All HTTP sha
|
||||
- Kernel/privilege preflight checks for eBPF/ETW observers.
|
||||
- Helm and systemd install templates.
|
||||
- Agent download and registration flow.
|
||||
* **Models**: `integration.models.ts` defines `IntegrationDraft`, `IntegrationProvider`, `WizardStep`, `PreflightCheck`, `AuthMethod`, and provider constants.
|
||||
|
||||
---
|
||||
|
||||
## 4) Auth, sessions & RBAC
|
||||
* **Models**: `integration.models.ts` defines `IntegrationDraft`, `IntegrationProvider`, `WizardStep`, `PreflightCheck`, `AuthMethod`, and provider constants.
|
||||
|
||||
### 3.12 Advisor (Ask Stella)
|
||||
|
||||
* **Chat panel** scoped to the current artifact, CVE, or release, with citations and evidence chips.
|
||||
* **Citations and Evidence** drawer lists object refs (SBOM, VEX, scan IDs) and hashes.
|
||||
* **Action confirmation** modal required for any tool action; disabled when policy denies.
|
||||
* **Budget indicators** show quota or token budget exhaustion with retry hints.
|
||||
|
||||
---
|
||||
|
||||
## 4) Auth, sessions & RBAC
|
||||
|
||||
### 4.1 OIDC flow
|
||||
|
||||
|
||||
Reference in New Issue
Block a user