Adds /mcp-tokens page that lets a logged-in user mint, list, and
revoke bearer tokens for the MCP server. Stacks on #92 (which added
the agent endpoints + middleware) — once both land, the loop is
closed: a user can copy a token from the dashboard straight into
their Claude Desktop / Cursor / ChatGPT MCP config.
UX
- "Create Token" button → inline form with name input.
- On submit, server function calls `POST /api/v1/mcp-tokens`. The
raw token is shown ONCE in a prominent yellow banner with a copy
button and a "won't be shown again" warning, then the user
dismisses it manually.
- List view: card per token with name, prefix `mcpt_xxxx…`, created
date, last_used (or "never"). Revoked tokens render dimmed with a
"revoked" pill. Active tokens have a trash button → confirm
modal → soft delete.
- Toast feedback on create/revoke success/failure.
Files
- infrastructure/mcp_tokens.rs (new) — three #[server] functions:
fetch_mcp_tokens, create_mcp_token, revoke_mcp_token. All go
through agent_client so the Keycloak Bearer is auto-attached;
the agent then enforces tenant scoping on every endpoint.
- pages/mcp_tokens.rs (new) — the page component itself.
- app.rs — adds Route::McpTokensPage at /mcp-tokens.
- pages/mod.rs, infrastructure/mod.rs — module + re-export wiring.
Timestamp format
- The agent serializes BSON DateTime as extended JSON
`{"$date":{"$numberLong":"..."}}`. Page has a small helper that
accepts that shape, plain ISO strings, or anything else
(best-effort). Same approach used elsewhere in the dashboard so
there's no new dependency.
Test plan
- cargo fmt --all clean
- cargo clippy -p compliance-dashboard --features server
-- -D warnings clean
- cargo clippy -p compliance-dashboard --features web
--no-default-features -- -D warnings clean
- cargo check on both feature sets clean
Followup
- No sidebar entry yet (matches mcp_servers — settings-style
pages are reached via direct URL today). Worth adding a
Settings sub-menu in a separate UX pass.
- Token expiry + per-tool scope when those land on the agent side
will need a small UI for the create modal (extra fields).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
## 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
## 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
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>
- Fetch SSH public key every time auth section opens (was only fetching
once and caching failures)
- Add mkdir for SSH key directory in Dockerfile.agent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New `compliance-mcp` crate providing a Model Context Protocol server
with 7 tools: list/get/summarize findings, list SBOM packages, SBOM
vulnerability report, list DAST findings, and DAST scan summary.
Supports stdio (local dev) and Streamable HTTP (deployment via MCP_PORT).
Includes Dockerfile, CI clippy check, and Coolify deploy job.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Reviewed-on: #5
Restructured layout: avatar, truncated username, and logout icon
in a single row. Collapsed state stacks vertically. Logout button
uses a subtle icon-only style with red hover. Proper text ellipsis
prevents name overflow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dioxus defaults to 127.0.0.1 which is unreachable from outside the
container. Hardcode 0.0.0.0 binding so reverse proxies can reach it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard: OAuth2/OIDC login flow with PKCE, session-based auth middleware
protecting all server function endpoints, check-auth server function for
frontend auth state, login page gate in AppShell, user info in sidebar.
Agent API: JWT validation middleware using Keycloak JWKS endpoint,
conditionally enabled when KEYCLOAK_URL and KEYCLOAK_REALM are set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com>
Reviewed-on: #2
Adds a repo_filter signal and fetches the repository list to populate
a select dropdown before existing severity/type/status filters,
allowing users to filter findings by specific repository.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Show updated_at as relative time (e.g. "5m ago", "3d ago") instead
of the last_scanned_commit hex SHA which was not a date
- Add Graph link button next to Scan button for quick navigation
to the repository's code knowledge graph
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Widen code inspector panel from 450px to 550px for better readability
- Redesign graph index landing page with polished repo cards showing
name, git URL, branch, findings count, and relative update time
- Add search suggestions dropdown in graph explorer that appears on
typing >= 2 chars, showing node name, kind badge, and file path
- Add full graph explorer styles matching Obsidian Control dark theme
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds code inspector, file tree components, graph visualization JS,
graph API handlers, sidebar navigation updates, and misc improvements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add DAST scanning and code knowledge graph features across the stack:
- compliance-dast and compliance-graph workspace crates
- Agent API handlers and routes for DAST targets/scans and graph builds
- Core models and traits for DAST and graph domains
- Dashboard pages for DAST targets/findings/overview and graph explorer/impact
- Toast notification system with auto-dismiss for async action feedback
- Button click animations and disabled states for better UX
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Run cargo fmt on all crates
- Fix regex patterns using unsupported lookahead in patterns.rs
- Replace unwrap() calls with compile_regex() helper
- Fix never type fallback in GitHub tracker
- Fix redundant field name in findings page
- Allow enum_variant_names for Dioxus Route enum
- Fix &mut Vec -> &mut [T] clippy lint in sbom.rs
- Mark unused-but-intended APIs with #[allow(dead_code)]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Feature-gate mongodb in compliance-core (optional, default on) so wasm
builds don't pull in tokio/mio via mongodb
- Use bson v2 directly for ObjectId types (wasm-compatible)
- Restructure dashboard infrastructure/mod.rs: server function modules
always compiled (for RPC stubs), server-only modules cfg-gated
- Remove reqwest from dashboard web feature (not needed, data flows
through server functions)
- Add .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>