Documentation
¶
Overview ¶
Package security is secret scanning for your code: submit sources, get findings, masked never raw.
It serves /v1/security: the pure detect engine finds hardcoded secrets, and findings persist masked and fingerprinted — never the raw secret.
Index ¶
- func Mount(app cloud.Router, deps cloud.Deps) error
- func Shutdown() error
- type Scan
- type Store
- func (s *Store) Close() error
- func (s *Store) GetFinding(ctx context.Context, org, id string) (StoredFinding, error)
- func (s *Store) GetScan(ctx context.Context, org, id string) (Scan, error)
- func (s *Store) ListFindings(ctx context.Context, org, scanID, minSeverity string, limit int) ([]StoredFinding, error)
- func (s *Store) ListScans(ctx context.Context, org string, limit int) ([]Scan, error)
- func (s *Store) SaveScan(ctx context.Context, sc Scan, fs []StoredFinding) error
- type StoredFinding
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Mount ¶
Mount wires /v1/security/* onto app and opens the per-deployment findings store under {DataDir}/security.db. It follows the clients/git contract: validate deps, open the store, register routes, return. The store lifecycle and package-global handle make this a direct construction (cloud.NewBase), not cloud.Mount.
Types ¶
type Scan ¶
type Scan struct {
ID string
Org string
Project string // may be "" (org-level scan)
Files int
Findings int
Critical int
High int
Medium int
Low int
CreatedAt int64
}
Scan is the org-scoped record of one submitted scan: what was scanned, when, and the finding tally by severity. The individual findings live in the findings table, joined by scan_id. Tenancy is the (org, project) columns, enforced on every query exactly like clients/git.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the findings database. ONE SQLite file ({DataDir}/security.db) holds every org's scans + findings; tenancy is the org column on both tables. MaxOpenConns(1) serializes writes against the file lock.
func (*Store) GetFinding ¶
GetFinding returns one finding for (org,id) or errNotFound.
func (*Store) GetScan ¶
GetScan returns the scan header for (org,id) or errNotFound. The org predicate is the isolation boundary — a scan id from another tenant misses.
func (*Store) ListFindings ¶
func (s *Store) ListFindings(ctx context.Context, org, scanID, minSeverity string, limit int) ([]StoredFinding, error)
ListFindings returns a tenant's findings. When scanID is non-empty it narrows to that scan; when minSeverity is non-empty it drops anything ranked below it. Ordered worst-first. Both filters compose in SQL so a huge history never materializes in memory.
func (*Store) SaveScan ¶
SaveScan persists a scan header and all its findings in ONE transaction, so a scan is never half-written (a reader either sees the whole scan or none of it). The findings' Org is forced to the scan's Org here, so a caller can't smuggle a cross-tenant row in via the finding list.
type StoredFinding ¶
type StoredFinding struct {
ID string
ScanID string
Org string
RuleID string
RuleName string
Severity string
Path string
Line int
Preview string
Fingerprint string
CreatedAt int64
}
StoredFinding is the persisted, redacted finding. It NEVER holds the raw secret — only the engine's masked Preview and SHA-256 Fingerprint (see engine.go). Scoped to (org, scan) so a tenant only ever reads its own.