Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 90 additions & 14 deletions ARCHITECTURE.md

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,54 @@

All notable changes to RedDock are documented here.

## [0.3.0] — Phase 2 Detection

Observations can now become findings. They remain separate concepts: an observation states what an adapter saw, a finding states what one named detector concluded from one or more of them, and a finding that cites no observation is refused rather than stored.

### Added

- Detector contract: a detector receives an immutable snapshot of one Dockyard and returns value objects, with no database session, socket, subprocess, target, or operator-supplied option in reach
- Detector registry with an explicit, fixed set; nothing is discovered, imported by name, or loaded from a plugin directory at runtime
- DetectionRun: an auditable record of which detectors ran, what each did or failed to do, how much state was read, what was produced and resolved, and which enrichment source was in effect
- Finding model with separate severity and confidence, a stable SHA-256 fingerprint, and links to the observations that support it
- Finding lifecycle: `open`, `resolved`, `suppressed`, and `accepted`, where resolution is RedDock's answer about the data and suppression and acceptance are the operator's
- FindingEvidence linking each finding to its observations, their discovery run, and the hashed RedLedger artifact behind them
- `http.security_headers` detector: plaintext transport and absent response-level protections, for the headers the probe recorded that it examined
- `service.rules` detector: a fixed table of protocol rules over services RedDock identified, plus disclosed product versions
- `tls.certificates` detector: what certificate verification objected to, using the code and message OpenSSL gave
- CVE enrichment boundary with an optional local catalogue behind `REDDOCK_CVE_CATALOG`
- API for detectors, detection runs, findings, finding detail with evidence, and operator status decisions
- Findings and Detection sections in the workspace, and a Dockyard-scoped Findings page
- ADR 0006 (detection boundary) and ADR 0007 (CVE enrichment is an association)

### Changed

- The HTTP probe records the header set it examined alongside the headers that were present, so a detector can tell an absent header from one RedDock never looked for
- The HTTP probe records the code and message OpenSSL gave when certificate verification failed, because an unverified handshake returns an empty peer certificate
- The HTTP probe retains `x-content-type-options`, `content-security-policy`, and `x-frame-options` in addition to the previous allowlist
- The HTTP probe User-Agent is derived from the application version rather than repeated as a literal
- The evidence store writes detection documents under a `detection` scope, so a detection run and a discovery run that share an identifier cannot share a directory
- The dashboard reports open findings; the observations view states that a detector, not the observation, produces interpretation

### Security

- Detection contacts nothing and takes no operator parameters: the request body is empty by design, so no operator string reaches a detector
- A detector that raises, returns malformed output, or names data outside its Dockyard is failed as a whole; its results are discarded and it resolves nothing
- Findings are never deleted, and an operator cannot declare one resolved
- Severity is stated conservatively and separately from confidence; RedDock produces no risk score, CVSS vector, or aggregate rating
- No CVE data is downloaded, matching is exact-version only, and an association never changes a severity, confidence, or status
- Detection snapshots, per-detector output, per-finding evidence references, and an operator-supplied catalogue are all bounded

### Testing

- Structural tests that parse the detection package and fail the build if a detector could reach a network, a process, the filesystem, or the database
- Detection orchestration tests for deduplication, resolution, reopening, operator decisions, detector failure isolation, malformed output, Dockyard isolation, and deterministic evidence
- A fingerprint test that runs in separate processes under different `PYTHONHASHSEED` values
- Detector tests covering false-positive avoidance: unexamined headers, redirects, server errors, scheme handling, and port numbers without an identification
- Schema-upgrade test proving a 0.2.1-shaped database upgrades in place and runs a full detection on data the previous release wrote
- A version test asserting the application, the API, and both packages report one version
- The end-to-end smoke test now covers detection, findings, evidence traceability, and deduplication

## [0.2.1] — Phase 1 Discovery, finalized

Phase 1 remains as released in 0.2.0; this is a corrective patch release.
Expand Down
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ cd frontend && npm ci && npm run lint && npm run check && npm run test && npm ru
docker compose build
```

Backend development needs Python 3.13; running RedDock itself needs only Docker. To verify the full discovery path end to end against loopback:
Backend development needs Python 3.13; running RedDock itself needs only Docker. To verify the full discovery and detection path end to end against loopback:

```bash
docker compose up -d --build && python scripts/smoke_test.py
```

## Guidelines

- Do not add exploitation, credential attacks, vulnerability detection, or autonomous execution without an approved phase and DockGuard design.
- Do not add exploitation, credential attacks, active vulnerability testing, or autonomous execution without an approved phase and DockGuard design.
- Every target must reach a tool through DockGuard. Never pass operator-supplied values to a subprocess as flags, and never build a command string.
- Record what was observed, not what it means. Severity, scoring, and findings belong to Phase 2.
- An adapter records what was observed. A detector says what it means, from stored observations only: it may not open a socket, start a process or reach the database, and a finding it produces must cite the observations behind it.
- Do not inflate a rating. A missing hardening header is not a high, a version banner is not a vulnerability, and a CVE association is not a test result.
- Preserve the API/domain/persistence/UI boundaries.
- Add tests for observable behavior and update documentation when behavior changes.
- Use clear names and explain non-obvious safety decisions.
Expand Down
54 changes: 42 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ Container-native security assessment and validation platform with controlled exe
[![Python](https://img.shields.io/badge/Python-3.13-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![CI](https://github.com/chriswayneh/RedDock/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/chriswayneh/RedDock/actions/workflows/ci.yml)
[![License](https://img.shields.io/github/license/chriswayneh/RedDock)](LICENSE)
[![Phase](https://img.shields.io/badge/phase-1%20Discovery-C1121F)](ROADMAP.md)
[![Phase](https://img.shields.io/badge/phase-2%20Detection-C1121F)](ROADMAP.md)

**Current release:** [v0.2.1](https://github.com/chriswayneh/RedDock/tags) — Phase 1 Discovery · Active development
**Current release:** [v0.3.0](https://github.com/chriswayneh/RedDock/tags) — Phase 2 Detection · Active development

[Quick Start](#quick-start) · [Current Capabilities](#what-you-get) · [Architecture](#architecture) · [Security](#security-by-design) · [Roadmap](ROADMAP.md) · [Contributing](CONTRIBUTING.md)

Expand All @@ -25,18 +25,22 @@ Container-native security assessment and validation platform with controlled exe

RedDock explores how security tooling can become portable, container-native, policy-controlled, reproducible, and evidence-driven instead of a collection of host-specific scripts. It is designed for authorized environments and intentionally grows through small, verified phases.

Its operating model is simple: **AI proposes. Policy authorizes. Tools execute. Evidence proves.** Phase 1 implements the middle two: an explicit authorized scope, a policy boundary called DockGuard that every target must pass, and non-invasive discovery adapters that produce hashed evidence. There is still no AI integration, vulnerability detection, exploitation, credential attack, or payload of any kind.
Its operating model is simple: **AI proposes. Policy authorizes. Tools execute. Evidence proves.** Three of the four are implemented: an explicit authorized scope, a policy boundary called DockGuard that every target must pass, non-invasive discovery adapters that produce hashed evidence, and detectors that turn those observations into findings a reviewer can trace back to the evidence behind them. There is still no AI integration, exploitation, credential attack, active vulnerability testing, or payload of any kind.

## What You Get

| Capability | Phase 1 implementation |
| Capability | Current implementation |
| --- | --- |
| Runtime | One Dockerized application that serves the UI and API on the same origin |
| Workspaces | Dockyards that own an explicit authorized scope |
| Scope policy | DockGuard evaluates every target deterministically and fails closed |
| Discovery | Nmap host and TCP service discovery, plus a single-request HTTP origin probe |
| Inventory | Normalized assets and services that reconcile across repeat discovery |
| Observations | Dated, adapter-attributed records of what was seen — never findings |
| Detection | Deterministic detectors that read stored observations and reach nothing |
| Findings | Normalized conclusions with separate severity and confidence, deduplicated by fingerprint |
| Lifecycle | Findings resolve rather than disappear, and operator decisions survive later runs |
| CVE enrichment | A boundary with an optional local catalogue; an association, never a verdict |
| Evidence | Raw output, normalized result, and metadata per run, each SHA-256 hashed |
| Persistence | SQLite and evidence stored in a named Docker volume |
| Safety | Non-invasive profiles only; no scripting, brute force, evasion, or exploitation |
Expand All @@ -45,16 +49,28 @@ Its operating model is simple: **AI proposes. Policy authorizes. Tools execute.

<div align="center">

<img src="docs/screenshots/findings.png" alt="RedDock findings view showing severity, confidence, status, the detector that produced a finding, and the hashed evidence behind it" width="900">

<sub>Findings: severity and confidence stated separately, with the detector, the observation, and the SHA-256 that supports each one.</sub>

<br><br>

<img src="docs/screenshots/dashboard.png" alt="RedDock dashboard showing workspace metrics and a discovery run audit trail" width="900">

<sub>The dashboard: workspace metrics and the discovery audit trail, including a run DockGuard denied.</sub>

<br><br>

<img src="docs/screenshots/workspace.png" alt="RedDock Dockyard workspace showing the discovery launch flow beside a DockGuard ALLOWED decision" width="900">
<img src="docs/screenshots/workspace.png" alt="RedDock Dockyard workspace showing the authorized scope beside a DockGuard ALLOWED decision" width="900">

<sub>The Dockyard workspace: a target must pass DockGuard before discovery can be launched.</sub>

<br><br>

<img src="docs/screenshots/detection.png" alt="RedDock detection view showing the registered detectors and a completed detection run" width="900">

<sub>Detection: the registered detectors, what each of them reads, and what a completed run produced.</sub>

</div>

## Quick Start
Expand All @@ -78,8 +94,9 @@ Stop the application with `docker compose down`. The `reddock-data` volume holds
3. Enter a target and ask DockGuard for a decision. It answers `ALLOWED` or a specific denial with the reason and the scope entry that decided it.
4. Run a safe discovery profile. The server re-evaluates DockGuard immediately before the adapter is invoked, so an out-of-scope target is never reached.
5. Results normalize into assets, services, and observations, and the run's raw output, normalized result, and metadata are retained and hashed.
6. Run detection. It contacts nothing: every registered detector reads what the Dockyard already recorded and returns findings, each naming the rule that produced it and the observations it was drawn from.

Run the same discovery again and RedDock updates what it already knows rather than duplicating it, while every observation is kept as history.
Run the same discovery again and RedDock updates what it already knows rather than duplicating it, while every observation is kept as history. Run detection again and the same issue stays one finding whose `last_seen` moves, while an issue that is no longer reproduced is marked resolved rather than quietly removed.

## Architecture

Expand All @@ -93,9 +110,16 @@ flowchart TB
Adapter --> Normalize[Assets · Services · Observations]
Normalize --> Database[(SQLite named Docker volume)]
Adapter --> Evidence[(Hashed evidence)]
API --> Detect[Detector]
Database --> Detect
Detect --> Findings[Findings]
Findings --> Database
Findings -.cites.-> Evidence
```

The production image builds the React application and serves it from the same FastAPI process that exposes `/api`. There is deliberately no reverse proxy, separate frontend service, queue, or remote dependency; discovery runs on a small bounded thread pool inside the application. See [ARCHITECTURE.md](ARCHITECTURE.md) for the scope model, adapter boundary, and trust boundaries.
Only one of those two paths touches a network. Discovery goes out through DockGuard to a target; detection reads what is already stored and never leaves the process, which is why it needs no scope decision.

The production image builds the React application and serves it from the same FastAPI process that exposes `/api`. There is deliberately no reverse proxy, separate frontend service, queue, or remote dependency; discovery runs on a small bounded thread pool inside the application and detection runs inline. See [ARCHITECTURE.md](ARCHITECTURE.md) for the scope model, the adapter and detector boundaries, and the trust boundaries.

## Security by Design

Expand All @@ -107,14 +131,18 @@ The production image builds the React application and serves it from the same Fa
- **Names and addresses stay separate.** A hostname is never authorized because it resolves into an authorized network, and there is no wildcard or subdomain expansion.
- **Tools never receive operator flags.** Argument vectors are generated internally from a fixed table of safe options, executed without a shell, bounded by timeouts, and built only from targets normalized to a character set that cannot form an option.
- **Dangerously broad scope is rejected.** A scope entry may not cover more than 256 addresses, and a default route is never valid.
- **Observations are not findings.** RedDock records what an adapter saw and assigns no severity, score, or verdict.
- **Observations are not findings.** An observation records what an adapter saw and carries no severity or verdict. A finding is a separate thing: a normalized conclusion one named detector drew, which cannot exist without the observations it cites.
- **Detectors reach nothing.** A detector is handed an immutable snapshot and no session, socket, subprocess, target, or operator option. A test parses the detection package and fails the build if that stops being true.
- **A finding is checkable.** It names the detector and rule that produced it, the observations behind it, the runs involved, and the SHA-256 of the retained artifact.
- **Ratings are not inflated.** Severity and confidence are separate fields, missing hardening headers are `low`, and there is no risk score, CVSS vector, or aggregate rating, because RedDock does not compute one.
- **CVE data is never invented.** RedDock downloads none. Enrichment is optional, local, exact-match only, and never changes a severity or a status.

Read [SECURITY.md](SECURITY.md) for the authorized-use policy and the full Phase 1 control list.
Read [SECURITY.md](SECURITY.md) for the authorized-use policy and the full control list.

## Repository Structure

```text
backend/ FastAPI API, DockGuard, discovery adapters, evidence, and SQLite persistence
backend/ FastAPI API, DockGuard, discovery adapters, detectors, evidence, and SQLite persistence
frontend/ React and TypeScript dashboard
scripts/ Local end-to-end smoke test
docs/ Architecture decisions and project documentation
Expand All @@ -133,13 +161,15 @@ docs/ Architecture decisions and project documentation

## Project Status

**v0.2.1 is the current release:** it finalizes Phase 1 with consistent version metadata across the application, API, and packages.
**v0.3.0 delivered Phase 2 — Detection:** the detector contract and registry, detection runs, normalized findings with separate severity and confidence, deduplication by stable fingerprint, a lifecycle that resolves rather than deletes, evidence links from every finding back to the observations and hashes behind it, and the CVE enrichment boundary.

**v0.2.1 finalized Phase 1** with consistent version metadata across the application, API, and packages.

**v0.2.0 delivered Phase 1 — Discovery:** DockGuard scope enforcement, asset/service/observation models, the Nmap and HTTP discovery adapters, discovery-run auditing, and the RedLedger evidence foundation.

**v0.1.0 delivered Phase 0 — Foundation:** a containerized React/FastAPI application, local Dockyard persistence, a dashboard, documentation, tests, and CI.

**Next: Phase 2Detection.** Normalized findings, detection adapter contracts, CVE enrichment, and deduplication are planned, not implemented. See the [roadmap](ROADMAP.md) for the complete phased plan.
**Next: Phase 3Validation.** Controlled non-destructive validation, approval gates, and evidence packages are planned, not implemented. Detection concludes; it does not confirm by attempting. See the [roadmap](ROADMAP.md) for the complete phased plan.

## Contributing and Security

Expand Down
8 changes: 5 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ Containerized application, React UI shell, FastAPI API, SQLite Dockyards, safety

DockGuard scope definitions, asset/service/observation models, the Nmap and HTTP discovery adapters, discovery-run auditing, and the RedLedger evidence foundation. Scoped discovery now produces auditable asset observations with hashed evidence. Released as v0.2.0 and finalized in v0.2.1.

## Next — Phase 2: Detection
## Completed — Phase 2: Detection

Normalized findings, detection adapter contracts, CVE enrichment, and deduplication. Complete when observations can become traceable findings without fabricating data.
Normalized findings, the detector contract and registry, detection runs, deduplication by stable fingerprint, a finding lifecycle that resolves rather than deletes, and the CVE enrichment boundary. Observations now become traceable findings without fabricating data: a finding names the detector and rule that produced it, cites the observations it was drawn from, and carries the hashes that verify them. Released as v0.3.0.

## Phase 3 — Validation
RedDock ships no CVE data. Enrichment is a boundary with a local, operator-supplied catalogue behind it, and a catalogue match is an association rather than a conclusion. See [ADR 0007](docs/adr/0007-cve-enrichment-is-an-association.md).

## Next — Phase 3: Validation

Controlled non-destructive validation, confidence scoring, approval gates, and evidence packages. Complete when validation actions require scope and policy decisions.

Expand Down
Loading
Loading