{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-55dc35de4ec43f90", "name": "`truncate` class without `title=` for hover reveal \u2014 web/src/components/Layout.tsx:75", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web/src/components/Layout.tsx:75"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-be2ae9ae423cf070", "name": "`truncate` class without `title=` for hover reveal \u2014 web/src/features/dashboard/DashboardPage.tsx:158", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web/src/features/dashboard/DashboardPage.tsx:158"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ba7033c89ba677bb", "name": "Icon-only button without accessible name \u2014 web/src/features/admin/AdminPage.tsx:82", "shortDescription": {"text": "Icon-only button without accessible name \u2014 web/src/features/admin/AdminPage.tsx:82"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-25e505332d00162e", "name": "`truncate` class without `title=` for hover reveal \u2014 web/src/features/admin/AdminPage.tsx:753", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web/src/features/admin/AdminPage.tsx:753"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3a5106210ac00eb5", "name": "Icon-only button without accessible name \u2014 web/src/features/domains/DomainsPage.tsx:142", "shortDescription": {"text": "Icon-only button without accessible name \u2014 web/src/features/domains/DomainsPage.tsx:142"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-708fb6c98a092465", "name": "Privileged port 587 in use", "shortDescription": {"text": "Privileged port 587 in use"}, "fullDescription": {"text": "Port 587 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-071c8881d571b5a5", "name": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be28869ac9e7378a", "name": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-52e4ceb4230a447e", "name": "Docker base image is tag-pinned but not digest-pinned: alpine:3.20", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: alpine:3.20"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d104a5c6e430ad7f", "name": "Dockerfile runs as root: docker/fake-primary/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: docker/fake-primary/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9446391ecc0ad3eb", "name": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fe46863e8e59a6e8", "name": "Docker base image is tag-pinned but not digest-pinned: alpine:3.20", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: alpine:3.20"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-976fee211d7fc323", "name": "Insecure pattern 'local_storage_auth_token' in web/src/features/auth/LoginPage.tsx:58", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in web/src/features/auth/LoginPage.tsx:58"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ca59d200299f2129", "name": "Insecure pattern 'local_storage_auth_token' in web/src/lib/api.ts:63", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in web/src/lib/api.ts:63"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d210c877e4ce1a0b", "name": "Insecure pattern 'local_storage_auth_token' in web/src/lib/auth.ts:18", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in web/src/lib/auth.ts:18"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-46c644c6227e4d4a", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "golangci/golangci-lint-action@v9 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1838a141491ce38c", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "golangci/golangci-lint-action@v9 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-85fc06bc8578b4d6", "name": "Very large file: tests/system_e2e_test.go (1420 lines)", "shortDescription": {"text": "Very large file: tests/system_e2e_test.go (1420 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 22 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 51 placeholder/mock markers across 17 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-17d866d91a7c451e", "name": "Agent instruction/config may expose a secret: CLAUDE.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-61a95c2b148e2489", "name": "`fetch()` without try/.catch or AbortSignal \u2014 web/src/features/auth/LoginPage.tsx:49", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 web/src/features/auth/LoginPage.tsx:49"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-aca3128cbb1cce7f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 web/src/lib/api.ts:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 web/src/lib/api.ts:20"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1c6b0d9317627961", "name": "Frontend route `/checkout/success` has no Link/navigate to it \u2014 web/src/App.tsx", "shortDescription": {"text": "Frontend route `/checkout/success` has no Link/navigate to it \u2014 web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a63e186a44200865", "name": "Frontend route `/checkout/cancel` has no Link/navigate to it \u2014 web/src/App.tsx", "shortDescription": {"text": "Frontend route `/checkout/cancel` has no Link/navigate to it \u2014 web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a518f25523468fea", "name": "JS PUT `/admin/users/${userId}/plan` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:354", "shortDescription": {"text": "JS PUT `/admin/users/${userId}/plan` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:354"}, "fullDescription": {"text": "Admin-scoped JS route with no recognizable auth: no middleware-position guard, no router-level guard above it in this file, and no inline permission call within the first 15 lines of the handler. If auth is applied where this router is mounted, dismiss with reason `by_design` or tag the route `// public-by-design`."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5078b340196f3e15", "name": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:897", "shortDescription": {"text": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:897"}, "fullDescription": {"text": "Admin-scoped JS route with no recognizable auth: no middleware-position guard, no router-level guard above it in this file, and no inline permission call within the first 15 lines of the handler. If auth is applied where this router is mounted, dismiss with reason `by_design` or tag the route `// public-by-design`."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-98ef31df058019d6", "name": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:924", "shortDescription": {"text": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:924"}, "fullDescription": {"text": "Admin-scoped JS route with no recognizable auth: no middleware-position guard, no router-level guard above it in this file, and no inline permission call within the first 15 lines of the handler. If auth is applied where this router is mounted, dismiss with reason `by_design` or tag the route `// public-by-design`."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-018964c1c5309c5c", "name": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:949", "shortDescription": {"text": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:949"}, "fullDescription": {"text": "Admin-scoped JS route with no recognizable auth: no middleware-position guard, no router-level guard above it in this file, and no inline permission call within the first 15 lines of the handler. If auth is applied where this router is mounted, dismiss with reason `by_design` or tag the route `// public-by-design`."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-bd8c246736afaaf2", "name": "Dangling fetch: POST /api/v1/auth/refresh (web/src/features/auth/LoginPage.tsx:49)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/auth/refresh (web/src/features/auth/LoginPage.tsx:49)"}, "fullDescription": {"text": "`web/src/features/auth/LoginPage.tsx:49` calls `POST /api/v1/auth/refresh` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/refresh`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c198a093ac7b5146", "name": "Dangling fetch: GET /api/v1/auth/me (web/src/features/auth/LoginPage.tsx:59)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/auth/me (web/src/features/auth/LoginPage.tsx:59)"}, "fullDescription": {"text": "`web/src/features/auth/LoginPage.tsx:59` calls `GET /api/v1/auth/me` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/me`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-370f1281f5b6dc7a", "name": "Dangling fetch: POST /api/v1/auth/logout (web/src/lib/auth.ts:49)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/auth/logout (web/src/lib/auth.ts:49)"}, "fullDescription": {"text": "`web/src/lib/auth.ts:49` calls `POST /api/v1/auth/logout` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/logout`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-dd159bd05997c05c", "name": "Unused endpoint: GET /admin/stats", "shortDescription": {"text": "Unused endpoint: GET /admin/stats"}, "fullDescription": {"text": "`web/src/features/dashboard/DashboardPage.tsx` declares `GET /admin/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cd8dc4599ec52a08", "name": "Unused endpoint: GET /stats", "shortDescription": {"text": "Unused endpoint: GET /stats"}, "fullDescription": {"text": "`web/src/features/dashboard/DashboardPage.tsx` declares `GET /stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c85094ad85aafb5c", "name": "Unused endpoint: GET /me/subscription", "shortDescription": {"text": "Unused endpoint: GET /me/subscription"}, "fullDescription": {"text": "`web/src/features/dashboard/DashboardPage.tsx` declares `GET /me/subscription` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f5cae3068724f9d3", "name": "Unused endpoint: GET /plans", "shortDescription": {"text": "Unused endpoint: GET /plans"}, "fullDescription": {"text": "`web/src/features/checkout/UpgradePage.tsx` declares `GET /plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2273ac666d251484", "name": "Unused endpoint: GET /admin/plans", "shortDescription": {"text": "Unused endpoint: GET /admin/plans"}, "fullDescription": {"text": "`web/src/features/admin/AdminPage.tsx` declares `GET /admin/plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fbeea22a66e4836c", "name": "Unused endpoint: GET /admin/sales", "shortDescription": {"text": "Unused endpoint: GET /admin/sales"}, "fullDescription": {"text": "`web/src/features/admin/AdminPage.tsx` declares `GET /admin/sales` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e2ad6d44231b81ad", "name": "Unused endpoint: GET /admin/settings", "shortDescription": {"text": "Unused endpoint: GET /admin/settings"}, "fullDescription": {"text": "`web/src/features/admin/AdminPage.tsx` declares `GET /admin/settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-479353b005c631f2", "name": "Unused endpoint: PUT /admin/settings", "shortDescription": {"text": "Unused endpoint: PUT /admin/settings"}, "fullDescription": {"text": "`web/src/features/admin/AdminPage.tsx` declares `PUT /admin/settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2905cc97704238c0", "name": "Unused endpoint: GET /auth/config", "shortDescription": {"text": "Unused endpoint: GET /auth/config"}, "fullDescription": {"text": "`web/src/features/auth/LoginPage.tsx` declares `GET /auth/config` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-da8f5c9a3ee90788", "name": "Unused endpoint: GET /cluster/nodes", "shortDescription": {"text": "Unused endpoint: GET /cluster/nodes"}, "fullDescription": {"text": "`web/src/features/cluster/ClusterPage.tsx` declares `GET /cluster/nodes` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6ad2194d377bd37e", "name": "Unused endpoint: GET /domains", "shortDescription": {"text": "Unused endpoint: GET /domains"}, "fullDescription": {"text": "`web/src/features/domains/DomainsPage.tsx` declares `GET /domains` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/25397"}, "properties": {"repository": "diggyen/MXhaven", "repoUrl": "https://github.com/diggyen/MXhaven", "branch": "main"}, "results": [{"ruleId": "scanner-55dc35de4ec43f90", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web/src/components/Layout.tsx:75"}, "properties": {"repobilityId": "1770b230578fa356", "scanner": "scanner-primary", "fingerprint": "55dc35de4ec43f90", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-be2ae9ae423cf070", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web/src/features/dashboard/DashboardPage.tsx:158"}, "properties": {"repobilityId": "bc56e5e800cf2a8d", "scanner": "scanner-primary", "fingerprint": "be2ae9ae423cf070", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ba7033c89ba677bb", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 web/src/features/admin/AdminPage.tsx:82"}, "properties": {"repobilityId": "a8011b422d47870e", "scanner": "scanner-primary", "fingerprint": "ba7033c89ba677bb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-25e505332d00162e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web/src/features/admin/AdminPage.tsx:753"}, "properties": {"repobilityId": "37a5ec1893fda666", "scanner": "scanner-primary", "fingerprint": "25e505332d00162e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3a5106210ac00eb5", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 web/src/features/domains/DomainsPage.tsx:142"}, "properties": {"repobilityId": "4f581d5c1e784e40", "scanner": "scanner-primary", "fingerprint": "3a5106210ac00eb5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-708fb6c98a092465", "level": "warning", "message": {"text": "Privileged port 587 in use"}, "properties": {"repobilityId": "a87a96c3b2e62c08", "scanner": "scanner-primary", "fingerprint": "708fb6c98a092465", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "internal/service/transactional.go"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-071c8881d571b5a5", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "9210f114d935126a", "scanner": "scanner-primary", "fingerprint": "071c8881d571b5a5", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-071c8881d571b5a5", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:24-alpine"}, "properties": {"repobilityId": "153f1b44189f7337", "scanner": "scanner-primary", "fingerprint": "071c8881d571b5a5", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-be28869ac9e7378a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine"}, "properties": {"repobilityId": "139ef30e1bcf6de9", "scanner": "scanner-primary", "fingerprint": "be28869ac9e7378a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-52e4ceb4230a447e", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: alpine:3.20"}, "properties": {"repobilityId": "cbbadbe113e852d5", "scanner": "scanner-primary", "fingerprint": "52e4ceb4230a447e", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-d104a5c6e430ad7f", "level": "warning", "message": {"text": "Dockerfile runs as root: docker/fake-primary/Dockerfile"}, "properties": {"repobilityId": "7eb785e4a71b934e", "scanner": "scanner-primary", "fingerprint": "d104a5c6e430ad7f", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-9446391ecc0ad3eb", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine"}, "properties": {"repobilityId": "21c86acd042aa247", "scanner": "scanner-primary", "fingerprint": "9446391ecc0ad3eb", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/fake-primary/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fe46863e8e59a6e8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: alpine:3.20"}, "properties": {"repobilityId": "341711d9d563a8ce", "scanner": "scanner-primary", "fingerprint": "fe46863e8e59a6e8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/fake-primary/Dockerfile"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-976fee211d7fc323", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in web/src/features/auth/LoginPage.tsx:58"}, "properties": {"repobilityId": "0d66a05cc71ce0f2", "scanner": "scanner-primary", "fingerprint": "976fee211d7fc323", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/features/auth/LoginPage.tsx"}, "region": {"startLine": 58}}}]}, {"ruleId": "scanner-ca59d200299f2129", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in web/src/lib/api.ts:63"}, "properties": {"repobilityId": "7b46985bbfec8df3", "scanner": "scanner-primary", "fingerprint": "ca59d200299f2129", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/lib/api.ts"}, "region": {"startLine": 63}}}]}, {"ruleId": "scanner-d210c877e4ce1a0b", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in web/src/lib/auth.ts:18"}, "properties": {"repobilityId": "442c4f1d8fbf97ee", "scanner": "scanner-primary", "fingerprint": "d210c877e4ce1a0b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/lib/auth.ts"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-46c644c6227e4d4a", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "7072ae3da503ef8b", "scanner": "scanner-primary", "fingerprint": "46c644c6227e4d4a", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-46c644c6227e4d4a", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "db9d162631d7772f", "scanner": "scanner-primary", "fingerprint": "46c644c6227e4d4a", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 82}}}]}, {"ruleId": "scanner-1838a141491ce38c", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "b8fd4f5048f96576", "scanner": "scanner-primary", "fingerprint": "1838a141491ce38c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/release.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "7b7ce4a66324740d", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "34724acf4d6dbe60", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 83}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9efbe00d4aa88280", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 86}}}]}, {"ruleId": "scanner-85fc06bc8578b4d6", "level": "note", "message": {"text": "Very large file: tests/system_e2e_test.go (1420 lines)"}, "properties": {"repobilityId": "dd2be9bbff4eb681", "scanner": "scanner-primary", "fingerprint": "85fc06bc8578b4d6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "040da8b4145cffe1", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "4ca873793181fd53", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "39911f3bd12e3797", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "83cdc2165391a63c", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-17d866d91a7c451e", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "properties": {"repobilityId": "ccce5984e58a48f0", "scanner": "scanner-primary", "fingerprint": "17d866d91a7c451e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 50}}}]}, {"ruleId": "scanner-61a95c2b148e2489", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 web/src/features/auth/LoginPage.tsx:49"}, "properties": {"repobilityId": "45624b9fd0d6b659", "scanner": "scanner-primary", "fingerprint": "61a95c2b148e2489", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-aca3128cbb1cce7f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 web/src/lib/api.ts:20"}, "properties": {"repobilityId": "578e75364a252f7c", "scanner": "scanner-primary", "fingerprint": "aca3128cbb1cce7f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1c6b0d9317627961", "level": "warning", "message": {"text": "Frontend route `/checkout/success` has no Link/navigate to it \u2014 web/src/App.tsx"}, "properties": {"repobilityId": "f75c0295b862b511", "scanner": "scanner-primary", "fingerprint": "1c6b0d9317627961", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a63e186a44200865", "level": "warning", "message": {"text": "Frontend route `/checkout/cancel` has no Link/navigate to it \u2014 web/src/App.tsx"}, "properties": {"repobilityId": "a9d8dae9a404995b", "scanner": "scanner-primary", "fingerprint": "a63e186a44200865", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a518f25523468fea", "level": "error", "message": {"text": "JS PUT `/admin/users/${userId}/plan` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:354"}, "properties": {"repobilityId": "1882ccbedbb58279", "scanner": "scanner-primary", "fingerprint": "a518f25523468fea", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.js.admin_unauth"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/features/admin/AdminPage.tsx"}, "region": {"startLine": 354}}}]}, {"ruleId": "scanner-5078b340196f3e15", "level": "error", "message": {"text": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:897"}, "properties": {"repobilityId": "26bcff6c8b2c0133", "scanner": "scanner-primary", "fingerprint": "5078b340196f3e15", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.js.admin_unauth"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/features/admin/AdminPage.tsx"}, "region": {"startLine": 897}}}]}, {"ruleId": "scanner-98ef31df058019d6", "level": "error", "message": {"text": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:924"}, "properties": {"repobilityId": "4419d110725d7904", "scanner": "scanner-primary", "fingerprint": "98ef31df058019d6", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.js.admin_unauth"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/features/admin/AdminPage.tsx"}, "region": {"startLine": 924}}}]}, {"ruleId": "scanner-018964c1c5309c5c", "level": "error", "message": {"text": "JS PUT `/admin/settings` admin endpoint without auth \u2014 web/src/features/admin/AdminPage.tsx:949"}, "properties": {"repobilityId": "bc8179c361a16577", "scanner": "scanner-primary", "fingerprint": "018964c1c5309c5c", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.js.admin_unauth"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web/src/features/admin/AdminPage.tsx"}, "region": {"startLine": 949}}}]}, {"ruleId": "scanner-bd8c246736afaaf2", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/auth/refresh (web/src/features/auth/LoginPage.tsx:49)"}, "properties": {"repobilityId": "11a2850ab59b3d27", "scanner": "scanner-primary", "fingerprint": "bd8c246736afaaf2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c198a093ac7b5146", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/auth/me (web/src/features/auth/LoginPage.tsx:59)"}, "properties": {"repobilityId": "0fcc9b006911ac96", "scanner": "scanner-primary", "fingerprint": "c198a093ac7b5146", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-370f1281f5b6dc7a", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/auth/logout (web/src/lib/auth.ts:49)"}, "properties": {"repobilityId": "1bf5bad7ac7681fd", "scanner": "scanner-primary", "fingerprint": "370f1281f5b6dc7a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dd159bd05997c05c", "level": "note", "message": {"text": "Unused endpoint: GET /admin/stats"}, "properties": {"repobilityId": "fa6c97e4564e4d6d", "scanner": "scanner-primary", "fingerprint": "dd159bd05997c05c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "c0efa1e0264a2d8a", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c85094ad85aafb5c", "level": "note", "message": {"text": "Unused endpoint: GET /me/subscription"}, "properties": {"repobilityId": "b263547eb06993cd", "scanner": "scanner-primary", "fingerprint": "c85094ad85aafb5c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f5cae3068724f9d3", "level": "note", "message": {"text": "Unused endpoint: GET /plans"}, "properties": {"repobilityId": "8564be4d3855bb31", "scanner": "scanner-primary", "fingerprint": "f5cae3068724f9d3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2273ac666d251484", "level": "note", "message": {"text": "Unused endpoint: GET /admin/plans"}, "properties": {"repobilityId": "f55506ce7055ab96", "scanner": "scanner-primary", "fingerprint": "2273ac666d251484", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fbeea22a66e4836c", "level": "note", "message": {"text": "Unused endpoint: GET /admin/sales"}, "properties": {"repobilityId": "634f5742070f8f33", "scanner": "scanner-primary", "fingerprint": "fbeea22a66e4836c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e2ad6d44231b81ad", "level": "note", "message": {"text": "Unused endpoint: GET /admin/settings"}, "properties": {"repobilityId": "159f2d3dbc402cc5", "scanner": "scanner-primary", "fingerprint": "e2ad6d44231b81ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-479353b005c631f2", "level": "note", "message": {"text": "Unused endpoint: PUT /admin/settings"}, "properties": {"repobilityId": "253727f343259708", "scanner": "scanner-primary", "fingerprint": "479353b005c631f2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2905cc97704238c0", "level": "note", "message": {"text": "Unused endpoint: GET /auth/config"}, "properties": {"repobilityId": "3629f297288c6109", "scanner": "scanner-primary", "fingerprint": "2905cc97704238c0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-da8f5c9a3ee90788", "level": "note", "message": {"text": "Unused endpoint: GET /cluster/nodes"}, "properties": {"repobilityId": "3a9049cb3029e16b", "scanner": "scanner-primary", "fingerprint": "da8f5c9a3ee90788", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6ad2194d377bd37e", "level": "note", "message": {"text": "Unused endpoint: GET /domains"}, "properties": {"repobilityId": "b32ff1cecce39aeb", "scanner": "scanner-primary", "fingerprint": "6ad2194d377bd37e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}