Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
43aa786
docs: add canonical AppGuardrail documentation map
seonghobae Aug 9, 2026
aadff91
docs: add canonical AppGuardrail PRD
seonghobae Aug 9, 2026
ab79dd2
docs: add canonical AppGuardrail TRD
seonghobae Aug 9, 2026
7d5997e
docs: add canonical AppGuardrail architecture
seonghobae Aug 9, 2026
438d2dd
docs: add AppGuardrail UML views
seonghobae Aug 9, 2026
90119ea
docs: add AppGuardrail data model ERD
seonghobae Aug 9, 2026
9979bab
docs: add AppGuardrail threat model
seonghobae Aug 9, 2026
e6edbf7
docs: add detector validation strategy
seonghobae Aug 9, 2026
5e99c2a
docs: add AppGuardrail operability guide
seonghobae Aug 9, 2026
fad9793
docs: add detector and issue traceability
seonghobae Aug 9, 2026
f09678c
docs: add AppGuardrail ADR index
seonghobae Aug 9, 2026
e1effca
docs: record detector truth ADR
seonghobae Aug 9, 2026
973fb55
docs: separate prevention and detection ADR
seonghobae Aug 9, 2026
877c5f1
docs: record external engine provenance ADR
seonghobae Aug 9, 2026
73a67ed
docs: record tenant and egress boundaries ADR
seonghobae Aug 9, 2026
faed46d
docs: record remediation authority ADR
seonghobae Aug 9, 2026
b9b37e6
docs: record automation authority ADR
seonghobae Aug 9, 2026
1ccfb44
test: enforce canonical product and detector docs
seonghobae Aug 9, 2026
031062c
docs: bind detector and workflow evidence provenance
seonghobae Aug 9, 2026
d045100
docs: make webhook delivery semantics fail-closed
seonghobae Aug 9, 2026
bff713c
docs: correct detector maturity and webhook delivery flow
seonghobae Aug 9, 2026
c302af5
test: harden canonical detector documentation contracts
seonghobae Aug 9, 2026
bfccf5d
docs: restore structural detector truth contract
seonghobae Aug 9, 2026
3afb015
docs: bind canonical evidence trust
seonghobae Aug 9, 2026
96a16f3
docs: pin webhook connection policy
seonghobae Aug 9, 2026
99ecd9a
test: lock evidence and maturity contracts
seonghobae Aug 9, 2026
382cae1
docs: reconcile SSRF assurance after PR #910 integration
seonghobae Aug 12, 2026
4c634dd
test: bind maturity assertions to each SSRF claim
seonghobae Aug 12, 2026
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
123 changes: 123 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# AppGuardrail Architecture

**Status:** Accepted as-built/target architecture with maturity labels
**Last reviewed:** 2026-08-09

## Architectural goal

AppGuardrail converts application/security evidence into deterministic findings, reviewable remediation, continuous policy gates, and longitudinal assurance without conflating optional external scanners, issue metadata, or historical coordination with executable detection truth.

## Component view

```mermaid
flowchart LR
TARGET[Untrusted target repository/app]
DISC[Discovery/normalization]
BUILTIN[Built-in detector engine]
EXT[Optional external engines]
FIND[Normalized findings]
GATE[Deploy gate]
FIX[Safe fix / fix-pack]
SARIF[SARIF / reports / SBOM]
CP[Control plane]
DASH[Dashboard / buyer evidence]
ISSUE[Issue-to-detection audit]

TARGET --> DISC
DISC --> BUILTIN
TARGET --> EXT
BUILTIN --> FIND
EXT --> FIND
FIND --> GATE
FIND --> FIX
FIND --> SARIF
FIND --> CP
CP --> DASH
ISSUE --> BUILTIN
ISSUE --> EXT
```

## Detector authority

The detector that observes evidence is authoritative for its finding. `scanner/rules/*.yml` is not automatically executable in full: supported `pattern-regex` entries can be evaluated by the lightweight engine, while Semgrep-style structural `pattern:` fixtures remain non-executable by the built-in matcher unless explicitly routed to a working structural engine.

External engines retain their own engine/rule/version provenance. AppGuardrail normalizes their output but does not claim their analysis was performed internally.

## Issue-to-detection boundary

```mermaid
flowchart LR
HIST[Independent issue/claim inventory]
REG[Detection obligation registry]
ADAPT[Detector-family adapter]
DET[Actual detector]
EV[Closed evidence fixture or authenticated workflow result]
RES[pass/fail/inconclusive obligation result]

HIST --> REG
REG --> ADAPT
EV --> ADAPT
ADAPT --> DET
DET --> RES
```

A registry maps requirement identity to executable detector family; it cannot assert the detector answer. PR #911 is active-PR implementation of this contract.

## SSRF architecture

```mermaid
flowchart LR
INPUT[User-controlled URL]
VALID[Destination validation]
STORE[(Stored webhook/callback config)]
EXEC[Outbound executor]
DNS[DNS/IP/redirect checks]
NET[Network request]

INPUT --> VALID
VALID --> STORE
STORE --> EXEC
EXEC --> DNS
DNS --> NET
```

Stored SSRF prevention and scanner detection are separate. PR #910 adds a prevention-side write-path check; a scanner rule must independently detect vulnerable validation/store/execute patterns before AppGuardrail claims automatic detection coverage.

## Control-plane boundary

Current standalone control plane is stdlib HTTP + SQLite, with tenant API-key roles and scan/history/drift/webhook configuration. Persistent organization identity is resolved from authenticated key context, not untrusted payload strings. Enterprise replacement of SQLite is behind stable repository service functions and requires migrations/authz/recovery evidence.

## Remediation authority

Autofix can perform only narrowly proven semantics-preserving transformations. Other fixes are guidance for a user/agent and become accepted only after rescanning/reverification. Model-generated remediation is never a substitute for scanner evidence.

## Automation authority

```mermaid
flowchart LR
DEV[Autonomous developer]
VERIFY[Tests/security exact-head evidence]
REVIEW[Independent review agents/humans]
MERGE[Protected merge]
RELEASE[Release environment]

DEV --> VERIFY
VERIFY --> REVIEW
REVIEW --> MERGE
MERGE --> RELEASE
```

The development model does not own qualifying approval, protected merge, release, or reviewer credentials. Scheduler blocks are RCA inputs; one blocked PR does not idle unrelated safe work.

## Deployment modes

1. **CLI/library:** one-shot local scan/report/SBOM/fix.
2. **CI monitor:** installed GitHub workflow generating findings/SARIF and optional control-plane push.
3. **Control plane:** standalone multi-tenant scan history/drift/dashboard/webhook service.
4. **Organization evidence:** read-only aggregation of repository/PR/action evidence for acquisition/security diligence.

These modes share normalized contracts but can operate separately.

## Change control

A new detector engine, persistent schema, tenant authority, arbitrary autofix class, outbound target policy, issue-audit semantics, or automation credential boundary requires ADR and synchronized technical/security/test documentation.
33 changes: 33 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# AppGuardrail Documentation Map

AppGuardrail has extensive rule, scanner, report, release, issue, and scheduler documentation. This index establishes the cross-cutting product and architecture graph so buyers and maintainers do not have to reconstruct the product from README, workflows, issue bodies, and feature-specific notes.

| Area | Canonical document |
|---|---|
| Product requirements | [`docs/PRD.md`](docs/PRD.md) |
| Technical requirements | [`docs/TRD.md`](docs/TRD.md) |
| Architecture | [`ARCHITECTURE.md`](ARCHITECTURE.md) |
| UML/runtime/detection flows | [`docs/UML.md`](docs/UML.md) |
| Logical/physical data model | [`docs/ERD.md`](docs/ERD.md) |
| Threat model | [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) |
| Test and detector-validation strategy | [`docs/TEST_STRATEGY.md`](docs/TEST_STRATEGY.md) |
| Operability/recovery/release | [`docs/OPERABILITY.md`](docs/OPERABILITY.md) |
| Detection/issue/evidence traceability | [`docs/TRACEABILITY.md`](docs/TRACEABILITY.md) |
| Architecture decisions | [`docs/adr/README.md`](docs/adr/README.md) |
| Security reporting | [`SECURITY.md`](SECURITY.md) |
| Release automation | [`docs/release-automation.md`](docs/release-automation.md) |
| Productization roadmap | [`docs/product/2026-07-02-2b-krw-sale-readiness-plan.md`](docs/product/2026-07-02-2b-krw-sale-readiness-plan.md) |
| Agent development rules | [`AGENTS.md`](AGENTS.md) |
| Agent context | [`CLAUDE.md`](CLAUDE.md) |
| Product overview | [`README.md`](README.md) |
| Change history | [`CHANGELOG.md`](CHANGELOG.md) |

## Maturity vocabulary

- **implemented-main** — source and tests exist on protected `develop`.
- **active-PR** — implementation/evidence exists only on an open pull request.
- **planned** — accepted product target without executable detector/control yet.
- **external-engine** — capability delegated to an optional scanner such as Semgrep/Trivy/Bandit/ZAP rather than AppGuardrail's lightweight built-in matcher.
- **evidence-only** — information visible in reports/history but not yet executable as an AppGuardrail detector.

Critical current distinction: issue #911's no-exclusions issue-to-detector registry and executable obligation coverage are **active-PR**, not protected-branch behavior. Stored-webhook SSRF prevention in PR #910 is also not equivalent to AppGuardrail automatically detecting the unsafe stored-SSRF coding pattern; prevention and scanner detection are separate requirements.
164 changes: 164 additions & 0 deletions docs/ERD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# AppGuardrail Logical and Persistence ERD

**Status:** Accepted cross-cutting data model; active-PR detector-obligation entities are labelled.
**Last reviewed:** 2026-08-09

Current control-plane persistence is SQLite behind repository service functions. The scanner itself is primarily filesystem/in-memory and emits normalized finding envelopes. This ERD distinguishes current persistent scan history from active-PR/planned detection-obligation evidence.

## Current control-plane model

```mermaid
erDiagram
ORGANIZATION_RECORD ||--o{ API_KEY_RECORD : authorizes
ORGANIZATION_RECORD ||--o{ SCAN_RECORD : owns
SCAN_RECORD ||--o{ FINDING_RECORD : contains
ORGANIZATION_RECORD ||--o| WEBHOOK_CONFIG : configures
SCAN_RECORD ||--o{ DRIFT_RECORD : compares

ORGANIZATION_RECORD {
string organization_id PK
string organization_name
datetime created_at
}

API_KEY_RECORD {
string api_key_id PK
string organization_id FK
string key_digest
string role_code
datetime created_at
datetime revoked_at
}

SCAN_RECORD {
string scan_id PK
string organization_id FK
string repository_name
string commit_sha
integer blocking_finding_count
string schema_version
datetime created_at
}

FINDING_RECORD {
string finding_id PK
string scan_id FK
string rule_id
string engine_code
string severity_code
string category_code
string file_path
integer line_number
string bounded_metadata_json
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}

DRIFT_RECORD {
string drift_record_id PK
string scan_id FK
string previous_scan_id
integer new_blocker_count
string calculation_version
}

WEBHOOK_CONFIG {
string webhook_config_id PK
string organization_id FK
string normalized_destination
string destination_policy_version
datetime updated_at
}
```

Exact physical SQLite table/column names may differ; migrations/source remain authoritative. Persistent object naming should converge on descriptive two-or-more-word `snake_case` when schema changes occur.

## Detection obligation model — PR #911 active target

```mermaid
erDiagram
ISSUE_CLAIM ||--o{ DETECTION_OBLIGATION : maps_to
DETECTOR_FAMILY ||--o{ DETECTION_OBLIGATION : satisfies
DETECTION_OBLIGATION ||--o{ DETECTOR_EVIDENCE_CASE : evaluated_by
DETECTOR_EVIDENCE_CASE ||--o{ OBLIGATION_RESULT : produces
WORKFLOW_EVIDENCE ||--o{ DETECTOR_EVIDENCE_CASE : authenticates

ISSUE_CLAIM {
integer issue_number
string claim_identifier
string issue_state_code
string source_digest
}

DETECTOR_FAMILY {
string detector_family_id
string execution_owner_code
string detector_version
string capability_status_code
}

DETECTION_OBLIGATION {
string obligation_id
integer issue_number
string claim_identifier
string detector_family_id
string detectability_code
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

DETECTOR_EVIDENCE_CASE {
string evidence_case_id
string obligation_id
string evidence_type_code
string evidence_digest
string provenance_status_code
}

OBLIGATION_RESULT {
string obligation_result_id
string evidence_case_id
string result_code
string detector_rule_id
string finding_digest
}

WORKFLOW_EVIDENCE {
string workflow_evidence_id
string repository_full_name
string workflow_name
string job_name
string head_sha
integer run_id
integer run_attempt
string conclusion_code
string evidence_digest
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
```

This second model is an **active-PR logical contract**, not a protected-develop persisted schema. PR #911 may use committed JSON/registry/fixtures rather than these as database tables.

## Identity and tenancy invariants

- API key identity resolves organization authority; repository/org strings inside scan payloads cannot elevate access.
- Finding IDs, scan IDs, issue numbers, rule IDs, and GitHub run IDs are evidence identities, not authorization identities.
- Webhook destination strings are protected network destinations and must pass policy before persistence/execution.
- Raw secrets discovered in target code are not copied into durable findings; retain rule/location/fingerprint or bounded redacted evidence instead.

## Finding provenance

```mermaid
flowchart LR
SRC[Target source/config]
ENG[Built-in or external engine]
FIND[Normalized finding]
SCAN[Scan envelope]
SARIF[SARIF/report/control plane]

SRC --> ENG
ENG --> FIND
FIND --> SCAN
SCAN --> SARIF
```

A finding retains engine/rule/provenance across transformations. AppGuardrail must not erase the distinction between built-in and external-engine evidence.

## Schema evolution rule

A future managed PostgreSQL control plane requires explicit migration/rollback, tenant authorization/RLS where used, idempotency/concurrency, webhook/egress security, backup/recovery, retention/deletion, and cross-tenant tests. Conceptual issue-obligation entities become persistent only through such a reviewed migration, not merely by being drawn here.
Loading
Loading