@sanity-labs/backstage-plugin-trivy
v1.0.3
Published
A Backstage plugin that fetches Trivy findings from a GCS bucket and displays in [Backstage](https://backstage.io/).
Keywords
Readme
Trivy Backstage Plugin
A Backstage plugin that fetches Trivy findings from a GCS bucket and displays in Backstage.
Packages
- Backend (
@sanity-labs/backstage-plugin-trivy-backend) - Fetches and serves scan data - Frontend (
@sanity-labs/backstage-plugin-trivy) - Entity card component
Requirements
The backend requires Google Cloud credentials to access the storage bucket. Configure authentication using one of:
Service account key (production):
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account-key.jsongcloud CLI (local development):
gcloud auth application-default loginWorkload Identity (GKE deployments)
See Google Cloud authentication docs for details.
Installation
Install both the frontend and backend packages:
# Using npm
npm install @sanity-labs/backstage-plugin-trivy @sanity-labs/backstage-plugin-trivy-backend
# Using yarn
yarn add @sanity-labs/backstage-plugin-trivy @sanity-labs/backstage-plugin-trivy-backend
# Using pnpm
pnpm add @sanity-labs/backstage-plugin-trivy @sanity-labs/backstage-plugin-trivy-backendSetup
Backend
Add to packages/backend/src/index.ts:
import trivy from '@sanity-labs/backstage-plugin-trivy-backend';
const backend = createBackend();
backend.add(trivy());Frontend
1. Register the Trivy API
Add to packages/app/src/apis.ts:
import {
trivyApiRef,
TrivyClient,
} from '@sanity-labs/backstage-plugin-trivy';
import {
discoveryApiRef,
fetchApiRef,
configApiRef,
} from '@backstage/core-plugin-api';
export const apis: AnyApiFactory[] = [
// ... existing APIs
createApiFactory({
api: trivyApiRef,
deps: {
discoveryApi: discoveryApiRef,
fetchApi: fetchApiRef,
configApi: configApiRef,
},
factory: ({ discoveryApi, fetchApi, configApi }) =>
new TrivyClient({ discoveryApi, fetchApi, configApi }),
}),
];2. Add the Entity Card
Add to packages/app/src/components/catalog/EntityPage.tsx:
import {
EntityTrivyCard,
TrivyQueryProvider,
} from '@sanity-labs/backstage-plugin-trivy';
// Inside your entity layout
<Grid item md={6}>
<TrivyQueryProvider>
<EntityTrivyCard />
</TrivyQueryProvider>
</Grid>Note: The TrivyQueryProvider wrapper is required as the plugin uses React Query for data fetching.
The card displays security findings for the component's repository. It uses the entity's github.com/project-slug annotation or assumes the component name matches the repository name:
metadata:
name: my-service # Should match the repository name
annotations:
github.com/project-slug: org/my-service # Optional - uses component name if not setConfiguration
Add the following to your app-config.yaml:
trivy:
# GCS bucket containing Trivy scan results (required)
bucketName: your-bucket-name
# Backend cache time in minutes (optional, default: 30)
# How long the backend caches scan results in memory
# Set to 0 to disable backend caching (useful for development)
cacheTime: 30
# Frontend stale time in minutes (optional, default: 5)
# How long React Query considers data "fresh" before refetching
# Set to 0 to always refetch (useful for development)
staleTime: 5
# Severity levels to display (optional, default: ["CRITICAL", "HIGH", "MEDIUM"])
# Available levels: CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN
severityFilter:
- CRITICAL
- HIGH
- MEDIUMConfiguration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| bucketName | string | sanity-trivy-logs | GCS bucket containing scan results |
| cacheTime | number | 30 | Backend cache duration in minutes (0 = no cache) |
| staleTime | number | 5 | Frontend cache duration in minutes (0 = always refetch) |
| severityFilter | string[] | ["CRITICAL", "HIGH", "MEDIUM"] | Severity levels to display |
Authentication
The backend requires Google Cloud credentials to access the storage bucket. Configure authentication using one of the methods described in the Requirements section.
Error Handling
The plugin provides clear error messages for common issues:
- Permission Denied (403): Service account lacks
Storage Object Viewerrole on the bucket - No Scans Found (404): No scan results exist for the repository on the main branch
- Failed to Fetch (500): Network or backend errors
Check the backend logs for detailed error information.
GCS Bucket Structure
The backend expects scan results in the following structure:
gs://your-bucket/
└── repos/
└── {repo-name}/
└── {branch}/
└── {scan-id}/
├── trivy-metadata.txt
├── trivy-fs-output.txt
└── trivy-image-output.txtExample:
gs://sanity-trivy-logs/
└── repos/
└── my-service/
└── main/
└── 2024-01-01-12-00-00/
├── trivy-metadata.txt
├── trivy-fs-output.txt
└── trivy-image-output.txtMetadata File Format
The trivy-metadata.txt file contains build information:
CircleCI Build URL: https://circleci.com/...
GitHub PR: https://github.com/org/repo/pull/123
Git Commit: abc123def456
Committer: [email protected]Development
Local Development
For development, disable caching to always fetch fresh data:
trivy:
bucketName: your-bucket-name
cacheTime: 0
staleTime: 0Testing
Run tests:
yarn testBuild the plugin:
yarn buildLint:
yarn lintLicense
Apache-2.0
