@@ -17,28 +17,20 @@ The Trivy CLI must be available on the machine running Sencho. Trivy is not bund
Trivy is installed independently on each Sencho instance. When you select a remote node, the **Security** page → **Scanner setup** tab shows only the scanner status for that node; install, update, or uninstall Trivy from there to manage the remote's binary. Scan policies, CVE suppressions, and misconfig acknowledgements are managed on the control instance and replicate fleet-wide.
-## Tier availability
+## What's included
-| Feature | Community | Admiral |
-|---------|:---------:|:-------:|
-| Install / update / uninstall Trivy | ✓ | ✓ |
-| On-demand image vulnerability scanning | ✓ | ✓ |
-| Full scan (vulnerabilities + secrets) | ✓ | ✓ |
-| Compose file misconfiguration scanning | ✓ | ✓ |
-| Severity badges in the Resources Hub | ✓ | ✓ |
-| Scan results drawer with grouped tabs | ✓ | ✓ |
-| Post-deploy automated scanning | ✓ | ✓ |
-| Pre-deploy scan advisory on manual deploys | ✓ | ✓ |
-| Scan history sheet | ✓ | ✓ |
-| Scan comparison | ✓ | ✓ |
-| CVE suppressions | ✓ | ✓ |
-| Misconfig acknowledgements | ✓ | ✓ |
-| Scheduled fleet scans (all images on a node) | ✓ | ✓ |
-| Scan policies with `block_on_deploy` enforcement | | ✓ |
-| Suppression-aware deploy blocking (optional toggle) | | ✓ |
-| SBOM generation (SPDX, CycloneDX) | ✓ | ✓ |
-| SARIF export (code scanning integration) | | ✓ |
-| Auto-update of the managed Trivy binary | ✓ | ✓ |
+Every vulnerability-scanning capability is available on every tier:
+
+- Install / update / uninstall Trivy, with auto-update of the managed binary
+- On-demand image scanning and full scans (vulnerabilities + secrets)
+- Compose file misconfiguration scanning
+- Severity badges in the Resources Hub and a scan results drawer with grouped tabs
+- Post-deploy automated scanning and a pre-deploy scan advisory on manual deploys
+- Scan history sheet and scan comparison
+- CVE suppressions and misconfig acknowledgements
+- Scheduled fleet scans (all images on a node)
+- Scan policies with `block_on_deploy` enforcement, including suppression-aware deploy blocking
+- SBOM generation (SPDX, CycloneDX) and SARIF export for code-scanning integration
## On-demand scanning
@@ -85,7 +77,7 @@ The drawer opens as a right-side sheet with the breadcrumb `Security › Scans
- **Re-scan**: kick off a fresh scan, ignoring the digest cache.
- **Compare**: pick a baseline scan from the dropdown to diff against this one.
- **CSV**: export the full vulnerability list for offline review.
-- **SARIF**: download the full scan (vulnerabilities, secrets, and misconfigs) as SARIF 2.1.0 for upload to GitHub code scanning or any SARIF-aware tool. Admiral required.
+- **SARIF**: download the full scan (vulnerabilities, secrets, and misconfigs) as SARIF 2.1.0 for upload to GitHub code scanning or any SARIF-aware tool.
The summary header below the actions reports the per-severity counts, the total, how many findings have a fix available, when the scan ran, and what triggered it. An **SBOM** button below the summary downloads a Software Bill of Materials in SPDX JSON or CycloneDX format.
@@ -159,10 +151,6 @@ Failures are usually transient (registry timeouts, missing credentials) and neve
## Scan policies
-- {isPaid ? 'Manage enforcement policies on the Policies tab. ' : ''}This is a read-only posture for the active node. + Manage enforcement policies on the Policies tab. This is a read-only posture for the active node.
diff --git a/frontend/src/components/security/ScanPolicyManager.tsx b/frontend/src/components/security/ScanPolicyManager.tsx index 5eedb59a..91d43308 100644 --- a/frontend/src/components/security/ScanPolicyManager.tsx +++ b/frontend/src/components/security/ScanPolicyManager.tsx @@ -14,7 +14,6 @@ import { SettingsCallout } from '@/components/settings/SettingsCallout'; import { SettingsPrimaryButton } from '@/components/settings/SettingsActions'; import { useNodes } from '@/context/NodeContext'; import { useAuth } from '@/context/AuthContext'; -import { useLicense } from '@/context/LicenseContext'; import { useTrivyStatus } from '@/hooks/useTrivyStatus'; import type { FleetRole, ScanPolicy, VulnSeverity } from '@/types/security'; @@ -53,14 +52,11 @@ const EMPTY_FORM: PolicyFormState = { /** * Deploy-enforcement scan policies (block-on-deploy severity thresholds), the * honor-suppressions toggle, and the replica "managed by control" state. This - * is the paid governance surface for the Security page Policies tab; it returns - * null for Community (no enforcement management) so the catalog is all a - * Community operator sees. Policies are control-governed: fetched localOnly and - * shown only on the local node, mirroring how the rest of the fleet-governance - * UI behaves. + * is the governance surface for the Security page Policies tab. Policies are + * control-governed: fetched localOnly and shown only on the local node, + * mirroring how the rest of the fleet-governance UI behaves. */ export function ScanPolicyManager() { - const { isPaid } = useLicense(); const { isAdmin } = useAuth(); const { activeNode } = useNodes(); const isRemote = activeNode?.type === 'remote'; @@ -103,17 +99,17 @@ export function ScanPolicyManager() { }; useEffect(() => { - if (!isPaid || isRemote) { setLoading(false); return; } + if (isRemote) { setLoading(false); return; } fetchPolicies(); - }, [isPaid, isRemote]); + }, [isRemote]); useEffect(() => { - if (!isPaid || isRemote) return; + if (isRemote) return; void refreshTrivy(); - }, [isPaid, isRemote, activeNode?.id, refreshTrivy]); + }, [isRemote, activeNode?.id, refreshTrivy]); useEffect(() => { - if (!isPaid || isRemote) return; + if (isRemote) return; let cancelled = false; (async () => { try { @@ -135,7 +131,7 @@ export function ScanPolicyManager() { } })(); return () => { cancelled = true; }; - }, [isPaid, isRemote]); + }, [isRemote]); const handleHonorSuppressionsToggle = async (enabled: boolean) => { setHonorBusy(true); @@ -264,11 +260,6 @@ export function ScanPolicyManager() { } }; - // Enforcement management is a paid governance surface; the Policies tab is - // hidden for Community entirely (gated in SecurityView), so this is a - // defensive guard. - if (!isPaid) return null; - return (