Wire the id-preserving mappers into a runnable, idempotent, reversible migration:
- backfill_onboarded_targets(db, dry_run): repositories -> onboarded_targets;
dast_targets fold into the linked repo target (append LiveUrl, promote type,
relink dast_scan_runs/pentest_sessions history) or migrate standalone. Skips
existing (by _id), writes a schema_migrations marker; dry-run computes the
report without writing. Legacy collections are never deleted.
- revert(db): replay the relink log, drop onboarded_targets + the log, clear the
marker — restores the pre-migration state.
- CLI: `compliance-agent migrate onboarding [--all | --tenant <id>] [--dry-run]
[--revert]`, with DatabasePool::list_tenant_ids for --all.
- database.rs: collection_named<T> accessor + list_tenant_ids helper.
Integration test (real Mongo, local-only — CI is --lib) covers fold + relink +
idempotency + revert end to end. 5 mapper unit tests run in CI.
Closes#132.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pure transforms folding legacy records into the unified model, preserving _id so
every downstream collection keyed by that hex id keeps resolving:
- repo_to_target: TrackedRepository -> OnboardedTarget (GitRepo artifact with
branch/watermark/auth; tracker config -> scan_config; webhook/schedule/counts).
- dast_to_artifact / dast_to_standalone_target: DastTarget -> LiveUrl artifact
(crawl config + auth), or a standalone target when repo-less.
- fold_dast_into_target: append a LiveUrl to a repo-derived target (idempotent),
promoting BackendService -> WebApp for a browser app.
5 unit tests. The per-tenant DB orchestration (idempotent backfill + revert) and
the `migrate onboarding` CLI subcommand are the next increment.
Refs #132.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds /mcp-tokens page so a logged-in user can mint, list, and revoke bearer tokens for the MCP server without curl. Pairs with #92's tenant-scoped MCP middleware — copy a token from the dashboard straight into an LLM client config.
Replaces M7.2-C static SCHEDULER_TENANT_IDS with a live query to the tenant-registry at every tick. New tenants picked up without an agent restart; env stays as fallback so a registry outage never silences the scheduler. Resolution order: registry -> SCHEDULER_TENANT_IDS env -> DEFAULT_SCHEDULER_TENANT_ID. Logs the active source on startup.
RUSTSEC-2026-0185 (quinn-proto 0.11.14): patch-bump to 0.11.15. RUSTSEC-2026-0189 (rmcp 0.16 DNS rebinding): added to ignore with public-hostname + bearer-auth threat-model justification; rmcp 0.16->2.x migration tracked as a separate multi-hour PR.
MCP server validates per-tenant bearer tokens on incoming calls and routes each tool to the caller's tenant DB. Closes the cross-tenant data leak in the MCP path identified in M7.3.
GET /api/admin/tenants lists tenant DBs; DELETE /api/admin/tenants/{tenant_id} drops them (GDPR). Behind a separate auth path that rejects customer realm tokens.
Webhook routes live on the separate webhook server (port 3002). M7.2-C URL form is /webhook/{tenant_id}/{platform}/{repo_id}; mounting unscoped variants on the API router would mismatch handler signatures.
## Summary
- **Scan produces no results in Orca** — semgrep (`--config=auto`, unbounded memory) and syft (remote license network calls) were getting OOM-killed or hanging in resource-constrained Orca containers. Scan would "complete" with 0 findings/SBOMs silently because each scanner failure is caught and logged as a warning.
- **Dashboard Script error spam** — `document::Script` in Dioxus 0.7 needs a single text node child for inline scripts; `dangerous_inner_html` was invalid and spammed the error log on every unauthenticated page load.
## Changes
| File | Change |
|------|--------|
| `semgrep.rs` | Add `--max-memory 500 --jobs 1`; 10-minute timeout |
| `syft.rs` | Remove remote license lookup env vars; 5-minute timeout |
| `gitleaks.rs` | 5-minute timeout |
| `app_shell.rs` | Fix `dangerous_inner_html` → text child in `document::Script` |
## Test plan
- [ ] Trigger a scan on a repo in Orca — findings and SBOM entries should now appear
- [ ] Agent logs should show timeout/error warnings rather than silent empty results when tools are killed
- [ ] Navigate to dashboard unauthenticated — Script error gone from logs
- [ ] Verify scans work end-to-end with `docker compose up`
---------
Co-authored-by: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com>
Reviewed-on: #78
Each deploy job now builds the per-service image, pushes to the
private registry as :latest and :sha, then triggers an HMAC-signed
orca redeploy webhook. Coolify webhooks are no longer used.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
## Summary
- Add HTTP response status checking to all Gitea tracker methods that were silently swallowing errors
- Add fallback in create_pr_review: if inline comments fail, retry as plain PR comment
## Test plan
- [ ] Deploy and trigger a PR review, check logs for actual error details
- [ ] Verify fallback posts summary comment when inline comments fail
Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Co-authored-by: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com>
Reviewed-on: #47
- Remove port 143 from mailserver (only expose 993/IMAPS)
- Enable SSL_TYPE=manual with Let's Encrypt certs
- Set DOVECOT_DISABLE_PLAINTEXT_AUTH=yes
- Add pentest_imap_tls config field (defaults to true)
Fixes CERT-Bund report: IMAP PLAIN/LOGIN without TLS on 46.225.100.82:143
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add CHROME_WS_URL env var support for PDF report generation via
Chrome DevTools Protocol over WebSocket (falls back to local binary)
- Update seeded MCP server endpoint URLs on boot when MCP_ENDPOINT_URL
env var differs from stored value (previously only seeded once)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the inline <pre> JSON display with a proper browser download using
Blob + URL.createObjectURL. Clicking "Download" now saves a .json file
(CycloneDX or SPDX format) directly to the user's downloads folder.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previous JSON used an incorrect format. Rewrote both dashboards using
the actual SigNoz v4 schema (widgets array, builder queryData, proper
layout entries, aggregateOperator/aggregateAttribute structure).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two dashboards with ClickHouse queries matching our tracing instrumentation:
- compliance-agent: API handler latency/errors, scan pipeline stage durations,
DAST/graph/chat API panels, and warn/error log tracking
- compliance-dashboard: server function performance, page load distribution,
agent connectivity health, and error log monitoring
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add repo_id, finding_id, and filter fields to tracing::instrument attributes
for better trace correlation in SigNoz. Replace all silently swallowed errors
(Err(_) => Vec::new()) with tracing::warn! logging across mod.rs, dast.rs,
graph.rs handlers. Add stage-level spans with .instrument() to pipeline
orchestrator for visibility into scan phases.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>