Architecture¶
The project separates data collection, rule evaluation, policy, and presentation.
GitLab REST API
│
▼
typed client / transport
│
├── project collector
├── governance collector
├── CI collector/parser
├── variable collector
├── pipeline-history collector
└── release collector
│
▼
AuditContext
│
▼
RuleRegistry + AuditEngine
│
▼
AuditResult
│
configuration policy
│
┌───────┼────────┐
▼ ▼ ▼
human JSON SARIF
API boundary¶
gitlab_project_audit.api.GitLabClient centralises:
- token authentication
- self-managed GitLab base URLs
- URL encoding
- pagination
- bounded pagination
- retry/backoff
- rate-limit handling
- stable exception types
The transport is injectable so unit tests remain offline.
Collectors¶
Collectors reduce GitLab API responses into small typed snapshots. They preserve unavailable and not-applicable states instead of inventing values when permissions are insufficient.
Rule engine¶
Rules implement a small AuditRule protocol. Each rule owns:
- stable rule ID
- category
- deterministic evaluation
The engine sorts rules by ID and isolates unexpected rule exceptions so one broken rule does not silently discard unrelated findings.
Policy¶
Configuration is applied separately from collection/evaluation:
- select categories/rules
- override severity
- annotate active suppressions
This separation lets different teams apply different policy to the same factual checks.
Portfolio layer¶
The portfolio runner accepts a single-project audit callable and adds:
- explicit multi-project execution
- group project discovery
- bounded concurrency
- deterministic ordering
- per-project failure isolation
- aggregate summaries