Admin access required
+This panel is only available to TrustOS administrators.
+diff --git a/backend/app/api/routes/reports.py b/backend/app/api/routes/reports.py
index b58b898..2300e17 100644
--- a/backend/app/api/routes/reports.py
+++ b/backend/app/api/routes/reports.py
@@ -9,7 +9,12 @@ import json
from app.db.session import get_db
from app.models.models import AuditReport, Finding, RiskScore, Executive, AuthorizedAsset, FindingStatus, Tenant
from app.schemas.schemas import AuditReportOut, AuditReportCreate
-from app.core.security import require_admin
+from app.core.security import require_admin, require_executive_or_above, require_it_or_above
+
+
+def _check_tenant_access(payload: dict, tenant_id: str):
+ if payload.get("role") != "trustos_admin" and payload.get("tenant_id") != tenant_id:
+ raise HTTPException(status_code=403, detail="Access denied")
router = APIRouter(prefix="/audit-reports", tags=["audit-reports"])
@@ -17,9 +22,10 @@ router = APIRouter(prefix="/audit-reports", tags=["audit-reports"])
@router.get("", response_model=List[AuditReportOut])
async def list_reports(
tenant_id: str = Query(...),
- payload: dict = Depends(require_admin),
+ payload: dict = Depends(require_executive_or_above),
db: AsyncSession = Depends(get_db),
):
+ _check_tenant_access(payload, tenant_id)
result = await db.execute(
select(AuditReport)
.where(AuditReport.tenant_id == tenant_id)
@@ -89,26 +95,28 @@ async def generate_audit_report(
@router.get("/{report_id}", response_model=AuditReportOut)
async def get_report(
report_id: str,
- payload: dict = Depends(require_admin),
+ payload: dict = Depends(require_executive_or_above),
db: AsyncSession = Depends(get_db),
):
result = await db.execute(select(AuditReport).where(AuditReport.id == report_id))
report = result.scalar_one_or_none()
if not report:
raise HTTPException(status_code=404, detail="Report not found")
+ _check_tenant_access(payload, report.tenant_id)
return report
@router.get("/{report_id}/pdf")
async def download_report_pdf(
report_id: str,
- payload: dict = Depends(require_admin),
+ payload: dict = Depends(require_executive_or_above),
db: AsyncSession = Depends(get_db),
):
result = await db.execute(select(AuditReport).where(AuditReport.id == report_id))
report = result.scalar_one_or_none()
if not report:
raise HTTPException(status_code=404, detail="Report not found")
+ _check_tenant_access(payload, report.tenant_id)
tenant_result = await db.execute(select(Tenant).where(Tenant.id == report.tenant_id))
tenant = tenant_result.scalar_one_or_none()
@@ -142,10 +150,11 @@ async def download_report_pdf(
@router.post("/{tenant_id}/pdf-snapshot")
async def generate_pdf_snapshot(
tenant_id: str,
- payload: dict = Depends(require_admin),
+ payload: dict = Depends(require_it_or_above),
db: AsyncSession = Depends(get_db),
):
"""Generate a one-off PDF report for a tenant (not stored as a record)."""
+ _check_tenant_access(payload, tenant_id)
tenant_result = await db.execute(select(Tenant).where(Tenant.id == tenant_id))
tenant = tenant_result.scalar_one_or_none()
if not tenant:
diff --git a/frontend/next.config.ts b/frontend/next.config.ts
index 5204212..9873e47 100644
--- a/frontend/next.config.ts
+++ b/frontend/next.config.ts
@@ -9,9 +9,6 @@ const nextConfig: NextConfig = {
},
];
},
- eslint: {
- ignoreDuringBuilds: true,
- },
};
export default nextConfig;
diff --git a/frontend/src/app/admin/page.tsx b/frontend/src/app/admin/page.tsx
new file mode 100644
index 0000000..8182c00
--- /dev/null
+++ b/frontend/src/app/admin/page.tsx
@@ -0,0 +1,165 @@
+"use client";
+import { useEffect, useState } from "react";
+import { useAuth } from "@/hooks/useAuth";
+import { api, type Report } from "@/lib/api";
+import Sidebar from "@/components/Sidebar";
+import {
+ Settings, FileText, Download, Play, CheckCircle2, AlertCircle, RefreshCw
+} from "lucide-react";
+
+export default function AdminPage() {
+ const { tenantId, role, ready } = useAuth();
+ const [reports, setReports] = useState Admin access required This panel is only available to TrustOS administrators. Audit report generation and tenant operations Snapshots the current score and top findings as a permanent audit record.
+ Generates a full findings + score-trend PDF for this tenant without creating an audit record. Perfect for ad-hoc board requests.
+ Recent Reports No reports generated yet.
+
+
+
+
+
+
Continuous Scanning
++ {scan.last_scan + ? `Last scanner activity ${new Date(scan.last_scan).toLocaleString([], { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" })}` + : "No automated scans in the last 24 hours"} +
+All security findings across your environment
No findings match these filters
@@ -118,7 +206,7 @@ export default function FindingsPage() { - {findings.map(f => ( + {visible.map(f => ({label}
+{value}
++ TrustOS is the AI operating system that turns raw vulnerabilities into a single + Cyber Health Score your board understands — and a prioritized plan your IT team can execute. +
++ Demo access included · No credit card · Authorized assessments only +
+Live from the demo vault
++ Every finding, every asset, every executive exposure — distilled into a single number + that trends over 90 days. When the score goes up, you have proof. When it dips, you know why first. +
+{s.value}
+{s.label}
+The Platform
++ Six capabilities, one vault. Built for growing companies that need enterprise-grade resilience without an enterprise-grade security team. +
+{desc}
+How It Works
+{desc}
+Built Trustworthy
++ Multi-tenant isolation, role-based access, encrypted transport, and authorized-scope-only + assessments. Your data never trains anyone else's model, and your assessments never touch + anything you haven't explicitly enrolled. +
+ + {ctaLabel}It's time you did too. Open your vault and see your real exposure in under five minutes.
+ + {ctaLabel}Point-in-time baseline reports and audit deliverables
+Point-in-time baseline reports and audit deliverables
+Audit reports are managed by your TrustOS administrator.
-No audit reports yet
-Generate the first Vault Audit from the admin panel.
++ {role === "trustos_admin" + ? "Generate the first Vault Audit from the Admin Panel." + : "Your TrustOS administrator will publish audit reports here."} +
{new Date(r.report_date).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" })} - {r.baseline_score && ` · Score at audit: ${Math.round(r.baseline_score)}`} + {r.baseline_score != null && ` · Score at audit: ${Math.round(r.baseline_score)}`}
{r.executive_summary && ({r.executive_summary}
)}Asset health, automated scans, and freshly discovered exposures
+{label}
+{value}
+No assets enrolled yet. Assets are added during Vault onboarding.
+{a.asset_name}
+{a.asset_value}
+No automated scanner findings yet.
+ {canScan &&Run a full scan to populate this feed.
} +{f.title}
+ {f.affected_component && ( +{f.affected_component}
+ )} +